/**************************************************************************//** * @item CosyOS-III Kernel * @file os_handler.c * @brief tCosyTick_Handler and sPendSV_Handler * @author 迟凯峰 * @version v3.0.0 * @date 2026.07.21 ******************************************************************************/ #include "os_var.h" #include "os_api.h" #include "sv_com.h" #include "sv_create.h" #include "sv_tick.h" #include "ur_api.h" #include "ur_eapi.h" #if defined ( __ICCARM__ ) #define __IAR_WEAK __WEAK #else #define __IAR_WEAK #endif sCat2Str(SYSCFG_STARTERCREATE, ExternTask(Starter)); #if (SYSCFG_DEBUGGING == __ENABLED__) __IAR_WEAK s_u32_t usedtime[2]/**/sZeroInstall_Group; #endif __IAR_WEAK void tCosyTick_Handler(void) MCUCFG_SYSTICK_ATTRIBUTE { #if (OS_TIMINTTOTAL > 0 || OS_TIMQRYTOTAL > 0) s_u8_t _SYS_REG_ i; #endif #if (SYSCFG_SYSTICKTIME_COUNT == __ENABLED__) #if defined ( __GNUC__ ) m_tick_t ticktemp_s = 0; #else m_tick_t ticktemp_s; #endif #endif s_taskctrl_tsp _SYS_REG_ htask; /* 清除中断标志位 */ #if defined ( __C51__ ) || defined ( __C251__ ) mSysTick_Clear(); #endif if(s_task_current == OS_NULL) return; /* 系统滴答开始时刻 */// 此刻定义为系统滴答开始时刻 for 系统滴答时间统计。 #if (SYSCFG_SYSTICKTIME_COUNT == __ENABLED__) if(s_taskmgr_sign){ ticktemp_s = MCUCFG_SYSTICK_CURRVALUE; } #endif /* 软件RTC */ #if (SYSCFG_SOFTRTC == __ENABLED__) #define counter s_rtc_counter if(true){ if(counter < 1000000UL / SYSCFG_SYSTICK_CYCLE - 1){ counter++; if(counter == 1000000UL / SYSCFG_SYSTICK_CYCLE / 2){ s_sign_every.halfsec = true; } } else{ counter = 0; s_sign_every.halfsec = true; s_sign_every.second = true; if(s_rtc.second < 59) s_rtc.second++; else{ s_rtc.second = 0; s_sign_every.minute = true; if(s_rtc.minute < 59) s_rtc.minute++; else{ s_rtc.minute = 0; s_sign_every.hour = true; if(s_rtc.hour < 23) s_rtc.hour++; else{ s_rtc.hour = 0; s_sign_every.day = true; if(s_rtc.day < 7) s_rtc.day++; else s_rtc.day = 1; if(s_rtc.date < (s_rtc.month == 2 ? s_month2day : s_month0day[s_rtc.month])) s_rtc.date++; else{ s_rtc.date = 1; s_sign_every.month = true; if(s_rtc.month < 12) s_rtc.month++; else{ s_rtc.month = 1; s_sign_every.year = true; if(s_rtc.year < 99) s_rtc.year++; else{ s_rtc.year = 0; s_rtc.yeah++; } } } } } } } } #undef counter #endif /* 运行时间统计 */ #if (SYSCFG_RUNTIME_COUNT == __ENABLED__) if(true){ static m_rtccount_t _SYS_MEM_ counter = 0; if(counter < 1000000UL / SYSCFG_SYSTICK_CYCLE - 1){ counter++; } else{ counter = 0; if(s_runtime.second < 59) s_runtime.second++; else{ s_runtime.second = 0; if(s_runtime.minute < 59) s_runtime.minute++; else{ s_runtime.minute = 0; if(s_runtime.hour < 23) s_runtime.hour++; else{ s_runtime.hour = 0; s_runtime.day++; } } } } } #endif /* 滴答钩子 */ #if (SYSCFG_TICKHOOK == __ENABLED__) if(true){ void tick_hook(void); tick_hook(); } #endif /* 任务管理器 */ #if (SYSCFG_DEBUGGING == __ENABLED__) if(s_debug_recvlen){ void os_debug_recv(void); os_debug_recv(); s_debug_recvlen = 0; } if(s_debug_sendsign){ s_debug_sendsign = false; tTimQry_ms(OS_TMID_DEBUGGER, 10); } #endif /* 定时中断 */ #if (OS_TIMINTTOTAL > 0) i = OS_TIMINTTOTAL; while(i--){ if(s_timint_handle[i]->timer){ s_timint_handle[i]->timer--; if(!s_timint_handle[i]->timer){ if(s_timint_handle[i]->autoreload){ s_timint_handle[i]->timer = s_timint_handle[i]->reload; } if(s_timint_handle[i]->hookortask){ sResumeTask_TimInt(i); } else{ sCallHook_TimInt(i); } } } } #endif /* 定时查询 */ #if (OS_TIMQRYTOTAL > 0) i = OS_TIMQRYTOTAL; while(i--){ if(s_timqry_handle[i]->timer && s_timqry_handle[i]->timer < (s_timqry_t)~0){ s_timqry_handle[i]->timer--; } if(!s_timqry_handle[i]->timer){ if((*s_timqry_handle[i]->event)()){ if(s_timqry_handle[i]->autoreload){ s_timqry_handle[i]->timer = s_timqry_handle[i]->reload; } else{ s_timqry_handle[i]->timer = ~0; } if(s_timqry_handle[i]->hookortask){ sResumeTask_TimQry(i); } else{ sCallHook_TimQry(i); } } } } #endif /* 任务定时器 */// 定时器链表中的任务状态:就绪、浮动、阻塞、挂起。 if(true){ s_timer_pointer = (s_timer_pointer + 1) & (OS_TIMESLOTNUM - 1UL); htask = s_timer_list[s_timer_pointer]; if(htask != OS_NULL){ bool loop_sign = true; s_taskctrl_tsp _SYS_REG_ hnext; s_taskctrl_tsp _SYS_REG_ htail = htask->last_t; __TIMER_LOOP: if(htask == htail){ loop_sign = false; } else{ hnext = htask->next_t; } if(htask->status < OS_STATUS_SUSPENDED){ if( htask->timer.cycle){ htask->timer.cycle--; } else if(htask->status == OS_STATUS_READY){ sa_remove_timerlist(htask); s_sign_delay = false; } else{ sa_clear_block(htask); } } if(loop_sign){ htask = hnext; goto __TIMER_LOOP; } } } /* 时间片 */ #if (SYSCFG_SAMEPRISCHEDULE == __TIMESHARING__) if(s_task_current->tc_counter < OS_TIMESHARING(s_task_current)){ s_task_current->tc_counter++; } else{ s_sign_schedule.every[1] = false; } #endif /* 安全运行时 */ #if (SYSCFG_SAFERUNTIME == __ENABLED__) /* 结束超时 */// 删除超时链表。 htask = s_timeout_list; if(!s_timeout_sign && htask != OS_NULL){ s_taskctrl_tsp _SYS_REG_ hnext; while(true){ if(htask->status == OS_STATUS_TIMEOUT){ // 超时 htask->status = OS_STATUS_READY; sa_add_ready(htask); } else if(htask->status == (OS_STATUS_TIMEOUT | OS_STATUS_SUSPENDED)){ // 超时|挂起 htask->status = OS_STATUS_READY | OS_STATUS_SUSPENDED; } htask->srt_counter = 0; hnext = htask->next_b; // htask->last_b = htask->next_b = OS_NULL; if(s_timeout_list == hnext){ s_timeout_list = OS_NULL; break; } htask = hnext; } } /* 超时判断 */ htask = s_task_current; if(htask->pri && htask->srt_maximum){ if(++htask->srt_counter > htask->srt_maximum){ if(htask->status == OS_STATUS_READY){ sa_insert_blocklist(&s_timeout_list); sa_remove_ready(htask); htask->status = OS_STATUS_TIMEOUT; htask->handle = &s_timeout_list; s_timeout_sign = true; #if (SYSCFG_DEBUGGING == __ENABLED__) s_alarm.timeout_saferuntime = true; #endif } } } #endif /* 任务管理器 */ #if (SYSCFG_DEBUGGING == __ENABLED__) if(s_taskmgr_sign){ /* CPU使用时间计数 */ usedtime[0]++; s_taskmgr_upspeed++; /* 系统滴答时间统计 */// 此刻定义为系统滴答结束时刻。 #if (SYSCFG_SYSTICKTIME_COUNT == __ENABLED__) if(true){ m_tick_t ticktemp_e = MCUCFG_SYSTICK_CURRVALUE; #if (MCUCFG_SYSTICK_COUNTMODE == 1 || MCUCFG_SYSTICK_COUNTMODE == 3) if(ticktemp_e > ticktemp_s){ s_tick_count1 += ticktemp_e - ticktemp_s; } #elif (MCUCFG_SYSTICK_COUNTMODE == 2 || MCUCFG_SYSTICK_COUNTMODE == 4) if(ticktemp_s > ticktemp_e){ s_tick_count1 += ticktemp_s - ticktemp_e; } #endif s_tick_count2++; } #endif } #endif /* 触发PendSV */ if(!s_sign_schedule.total){ mPendSV_Set(); } } #if (SYSCFG_DEBUGGING == __ENABLED__) __IAR_WEAK void _cpu_usedtime_(m_tick_t ticktemp_0) MCUCFG_OSIT_ATTRIBUTE { #if (MCUCFG_SYSTICK_COUNTMODE == 1 || MCUCFG_SYSTICK_COUNTMODE == 3) if(usedtime[0]){ s_task_current->usedtime[0] += usedtime[0] - 1; usedtime[0] = 0; usedtime[1] = (MCUCFG_SYSTICK_MAXVALUE - usedtime[1]) + (ticktemp_0 - MCUCFG_SYSTICK_MINVALUE); } else if(ticktemp_0 < usedtime[1]){ usedtime[0] = ~0; usedtime[1] = (MCUCFG_SYSTICK_MAXVALUE - usedtime[1]) + (ticktemp_0 - MCUCFG_SYSTICK_MINVALUE); } else{ usedtime[1] = (ticktemp_0 - usedtime[1]); } #elif (MCUCFG_SYSTICK_COUNTMODE == 2 || MCUCFG_SYSTICK_COUNTMODE == 4) if(usedtime[0]){ s_task_current->usedtime[0] += usedtime[0] - 1; usedtime[0] = 0; usedtime[1] = (usedtime[1] - MCUCFG_SYSTICK_MINVALUE) + (MCUCFG_SYSTICK_MAXVALUE - ticktemp_0); } else if(usedtime[1] < ticktemp_0){ usedtime[0] = ~0; usedtime[1] = (usedtime[1] - MCUCFG_SYSTICK_MINVALUE) + (MCUCFG_SYSTICK_MAXVALUE - ticktemp_0); } else{ usedtime[1] = (usedtime[1] - ticktemp_0); } #endif s_task_current->usedtime[0] += (s_task_current->usedtime[1] + usedtime[1]) / MCUCFG_SYSTICK_COUNT1CYC; s_task_current->usedtime[1] = (s_task_current->usedtime[1] + usedtime[1]) % MCUCFG_SYSTICK_COUNT1CYC; } #endif __IAR_WEAK void _float_to_ready_(s_taskctrl_tsp htask) MCUCFG_OSIT_ATTRIBUTE { htask->status = OS_STATUS_READY; // if(htask->next_b != OS_NULL){ sa_remove_blocklist(htask); // } if(htask->next_t != OS_NULL){ sa_remove_timerlist(htask); } } __IAR_WEAK s_taskctrl_tsp _SYS_MEM_ s_task_news/**/sZeroInstall; __IAR_WEAK s_u8_t _start_task_(void) MCUCFG_OSIT_ATTRIBUTE { s_taskctrl_tsp _SYS_REG_ node_news = *(s_task_starter.hload)->h2task; if(node_news != OS_NULL){ /* 任务已启动 */ if(node_news->status != OS_STATUS_DELETED){ #if (SYSCFG_DEBUGGING == __ENABLED__) s_alarm.task_repeated_startup = true; #endif s_task_starter._ecode = OS_ECODE_TASKSTARTED; goto __STARTUP_END; } /* 静态创建 */ else if(node_news->stacksize < MCUCFG_BASICSTACKSIZE){ #if (SYSCFG_DEBUGGING == __ENABLED__) s_fault.failed_startuptask = true; s_fault.overflow_taskstack = true; #endif s_task_starter._ecode = OS_ECODE_OVERFLOW_TASKSTACK; goto __STARTUP_END; } else{ mTaskStack_Init(); } } /* 动态创建 */ else{ node_news = (s_taskctrl_tsp)s_malloc(sizeof(s_taskctrl_ts)); if(node_news != OS_NULL){ node_news->stacksize = (s_task_starter.hload)->stacksize; if(node_news->stacksize < MCUCFG_BASICSTACKSIZE){ node_news->stacksize = MCUCFG_BASICSTACKSIZE; node_news->create = 2; } else{ node_news->create = 1; } node_news->bsp = OS_NULL; node_news->bsp = (s_u8_t _MALLOC_MEM_ *)s_malloc(node_news->stacksize); if(node_news->bsp != OS_NULL){ node_news->opri = (s_task_starter.hload)->opri; node_news->h2task = (s_task_starter.hload)->h2task; *node_news->h2task = node_news; node_news->entry = (s_task_starter.hload)->entry; #if (SYSCFG_DEBUGGING == __ENABLED__) node_news->name = (s_task_starter.hload)->name; #endif #if (SYSCFG_SAFERUNTIME == __ENABLED__) node_news->srt_maximum = (s_task_starter.hload)->srt_maximum; #endif mTaskStack_Init(); } else{ s_free(node_news); #if (SYSCFG_DEBUGGING == __ENABLED__) s_fault.failed_startuptask = true; s_fault.mallocfailed_taskstack = true; #endif s_task_starter._ecode = OS_ECODE_MALLOCFAIL_TASKSTACK; goto __STARTUP_END; } } else{ #if (SYSCFG_DEBUGGING == __ENABLED__) s_fault.failed_startuptask = true; s_fault.mallocfailed_tasknode = true; #endif s_task_starter._ecode = OS_ECODE_MALLOCFAIL_TASKNODE; goto __STARTUP_END; } } /* 公共部分 */ node_news->status = s_task_starter.status; node_news->blocktype = 0; node_news->handle = OS_NULL; node_news->timer.slots = 0; node_news->timer.cycle = 0; if(node_news->opri <= (s_u8_t)(SYSCFG_TASKPRIORITY - 1)){ node_news->pri = node_news->opri; } else{ node_news->pri = SYSCFG_TASKPRIORITY - 1; #if (SYSCFG_DEBUGGING == __ENABLED__) s_alarm.outrange_taskpriority = true; #endif } #if (SYSCFG_SAMEPRISCHEDULE == __COOPERATIVE__) node_news->yield = false; #elif (SYSCFG_SAMEPRISCHEDULE == __TIMESHARING__) node_news->tc_counter = 0; #endif #if (SYSCFG_DEBUGGING == __ENABLED__) node_news->usedtime[0] = 0; node_news->usedtime[1] = 0; node_news->stacklen_max = MCUCFG_BASICSTACKSIZE; #endif #if (SYSCFG_SAFERUNTIME == __ENABLED__) node_news->srt_counter = 0; #endif // node_news->last_b = OS_NULL; node_news->next_b = OS_NULL; // node_news->last_t = OS_NULL; node_news->next_t = OS_NULL; #if (SYSCFG_SAMEPRISCHEDULE && SYSCFG_MUTEX == __ENABLED__) node_news->link = OS_NULL; #endif sa_insert_taskque(node_news); s_task_queue_count++; if(s_task_starter.status == OS_STATUS_READY){ sa_add_ready(node_news); } s_task_starter._ecode = OS_ECODE_NOERROR; __STARTUP_END: s_task_starter.hload = OS_NULL; if(node_news == Starter){ if(s_task_starter._ecode == OS_ECODE_NOERROR){ #if (SYSCFG_DEBUGGING == __ENABLED__) if(s_taskmgr_sign){ usedtime[1] = MCUCFG_SYSTICK_CURRVALUE; } #endif #if defined ( __C51__ ) || defined ( __C251__ ) mUserReg_RESc(); #endif s_task_news = Starter; return 1; } else return 0; } else return 2; } void pendsv_hook(void); #if defined ( __C251__ ) #pragma functions(static) #endif __IAR_WEAK s_u8_t sPendSV_Handler(void) MCUCFG_OSIT_ATTRIBUTE { /* 中断FIFO服务 */ #if (SYSCFG_PENDSVFIFO_DEPTH > 0) mPendSV_FIFOHandle(); #endif /* 中断FLAG服务 */ #if (SYSCFG_PENDSVHOOK == __ENABLED__) pendsv_hook(); #endif /* 每监控(每PendSV假定切换任务)*/ #if (SYSCFG_DEBUGGING == __ENABLED__) if(s_task_current != OS_NULL){ m_stacklen_t len = mTaskStack_Check0(); if(s_task_current->stacklen_max < len){ s_task_current->stacklen_max = len; if(s_task_current->stacksize < len){ s_alarm.overflow_taskstack = true; } } } #endif /* 任务启动 */ if(!s_sign_startup){ s_sign_startup = true; if(s_task_starter.hload != OS_NULL){ s_u8_t r = _start_task_(); if(r < 2) return r; } } /* 任务调度 */ if(s_sign_schedule.total) return 0; else{ #if (SYSCFG_DEBUGGING == __ENABLED__) #if defined ( __GNUC__ ) m_tick_t _SYS_REG_ ticktemp_0 = 0; #else m_tick_t _SYS_REG_ ticktemp_0; #endif m_bit_t push_sign = false; /*!< 入栈信号 */ #else #define push_sign true #endif s_u8_t _SYS_REG_ pri; s_taskctrl_tsp _SYS_REG_ node_news; s_sign_schedule.every[1] = true; /* 抢占式调度(选择就绪)*/ if(true){ #if (SYSCFG_TASKPRIORITY > 64) s_u8_t table_index = s_task_pickmap[s_task_table_index >> (SYSCFG_TASKPICKBITMAP & 1)]; s_u8_t bytes_index = s_task_pickmap[s_task_bytes_index[table_index] >> (SYSCFG_TASKPICKBITMAP & 1)]; s_u8_t bit_index = s_task_pickmap[s_task_ready_table[table_index][bytes_index] >> (SYSCFG_TASKPICKBITMAP & 1)]; pri = (table_index << 6) + (bytes_index << 3) + bit_index; #elif (SYSCFG_TASKPRIORITY > 8) s_u8_t bytes_index = s_task_pickmap[s_task_bytes_index >> (SYSCFG_TASKPICKBITMAP & 1)]; s_u8_t bit_index = s_task_pickmap[s_task_ready_table[bytes_index] >> (SYSCFG_TASKPICKBITMAP & 1)]; pri = (bytes_index << 3) + bit_index; #else pri = s_task_pickmap[s_task_ready_table >> (SYSCFG_TASKPICKBITMAP & 1)]; #endif node_news = s_task_queue[pri]; } /* 相同优先级调度 */ #if (SYSCFG_SAMEPRISCHEDULE) while(true){ #if (SYSCFG_SAMEPRISCHEDULE == __COOPERATIVE__) /* 协作式调度 */ #define __NOT_YIELD !node_news->yield // 无需禅让 #define __CLR_YIELD node_news->yield = false // 清除禅让 #elif (SYSCFG_SAMEPRISCHEDULE == __TIMESHARING__) /* 时间片轮转调度 */// 时间片未到期不禅让,到期禅让 #define __NOT_YIELD node_news->tc_counter < OS_TIMESHARING(node_news) #define __CLR_YIELD node_news->tc_counter = 0 #endif static s_taskctrl_tsp _SYS_REG_ node_temp; if(node_news->status <= OS_STATUS_FLOATING){ if(__NOT_YIELD){ break; } else{ __CLR_YIELD; node_temp = node_news; // 缓存禅让的就绪任务 } } if(node_news != s_task_queue[pri]->last){ node_news = node_news->next; } else{ /* 在该优先级组中,未能找到其它的就绪任务,继续禅让的就绪任务。*/ node_news = node_temp; break; } } #endif /* 新任务为事件阻塞 */ if(node_news->blocktype){ node_news->blocktype = 0; if(node_news->status == OS_STATUS_FLOATING){ /* 浮动变就绪 */ _float_to_ready_(node_news); } mSysIRQ_Disable(); /* 内核上锁 */// 使服务层临界区连续。 } /* 新任务仍为当前任务 -> 返回 */ if(node_news == s_task_current){ return 0; } /* 新任务轮转至其优先级组首节点 */ #if (SYSCFG_SAMEPRISCHEDULE) if(node_news != s_task_queue[pri]){ s_task_queue[pri] = node_news; } #endif /* 入栈监控 */ #if (SYSCFG_DEBUGGING == __ENABLED__) /* 栈尾数据校验 */ #if (MCUCFG_TASKSTACK_MODE & __PSP__) if(s_taskmgr_sign){ m_stacklen_t len = mTaskStack_Check(); if(s_task_current->stacklen_max < len){ s_task_current->stacklen_max = len; } } #endif if(s_task_current->status < OS_STATUS_STOPPED){ if(s_task_current->stacksize < s_task_current->stacklen_max){ #if (MCUCFG_TASKSTACK_REALLOC == __ENABLED__) if(s_task_current->create){ s_task_current->stacksize = s_task_current->stacklen_max + SYSCFG_TASKSTACK_REALLOCINC; s_free(s_task_current->bsp); s_task_current->bsp = OS_NULL; s_task_current->bsp = (s_u8_t _MALLOC_MEM_ *)s_malloc(s_task_current->stacksize); if(s_task_current->bsp != OS_NULL){ push_sign = true; s_task_current->create = 2; s_alarm.realloc_taskstack = true; } else{ sa_stop_task(s_task_current); s_fault.overflow_taskstack = true; s_fault.reallocfailed_taskstack = true; } } else{ sa_stop_task(s_task_current); s_fault.overflow_taskstack = true; } #else sa_stop_task(s_task_current); s_fault.overflow_taskstack = true; #endif } else{ push_sign = true; } } #endif /* 任务切换时刻 */// 此刻定义为任务切换时刻 for CPU使用率统计。 #if (SYSCFG_DEBUGGING == __ENABLED__) if(s_taskmgr_sign){ ticktemp_0 = MCUCFG_SYSTICK_CURRVALUE; } #endif /* 当前任务入栈-预处理 */ if(push_sign){ #if (SYSCFG_SAFERUNTIME == __ENABLED__) if(s_task_current->pri > node_news->pri){ s_task_current->srt_counter = 0; } #endif #if (SYSCFG_DEBUGGING == __ENABLED__) if(s_taskmgr_sign){ _cpu_usedtime_(ticktemp_0); } #endif #if defined ( __C51__ ) || defined ( __C251__ ) mUserReg_SAVEc(); #endif } /* 新任务出栈-预处理 */ if(true){ #if (SYSCFG_DEBUGGING == __ENABLED__) if(s_taskmgr_sign){ usedtime[1] = ticktemp_0; } #endif #if defined ( __C51__ ) || defined ( __C251__ ) mUserReg_RESc(); #endif s_task_news = node_news; } return (s_u8_t)push_sign + 1; } }