/**************************************************************************//** * @item CosyOS-III Kernel * @file os_handler.c * @brief OS_SysTick_Handler and sPendSV_Handler * @author 迟凯峰 * @version V1.0.2 * @date 2025.02.27 ******************************************************************************/ #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 SYSCFG_DEBUGGING == __ENABLED__ static s_u32_t usedtime[2]/**/sZeroInstall_Group; #endif void OS_SysTick_Handler(void) MCUCFG_SYSTICK_ATTRIBUTE { void tick_hook(void); #if OS_TIMINTTOTAL || OS_TIMQRYTOTAL s_u8_t _SYS_REG_ i; #endif #if SYSCFG_SYSTICKTIME_COUNT == __ENABLED__ static m_tick_t tick_temp; #endif s_tasknode_tsp _SYS_REG_ htask; /* 清除中断标志位 */ mSysTick_Clear; /* 系统滴答时间统计开始 */ #if SYSCFG_SYSTICKTIME_COUNT == __ENABLED__ if(s_sign_taskmgr){ tick_temp = mSysTick_Counter; } #endif /* 软件RTC */ #if SYSCFG_SOFTRTC == __ENABLED__ if(true){ static #if SYSCFG_SYSTICKCYCLE > 1000000UL / 65536 s_u16_t #else s_u32_t #endif _SYS_MEM_ counter = 0; if(s_sign_every.set){ s_sign_every.set = false; counter = 1000000UL / SYSCFG_SYSTICKCYCLE / 2; } else{ if(counter < 1000000UL / SYSCFG_SYSTICKCYCLE - 1){ counter++; if(counter == 1000000UL / SYSCFG_SYSTICKCYCLE / 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++; } } } } } } #if SYSCFG_GETRTC_INT == __ENABLED__ sv_update_rtccopy(); #endif } } } #endif /* 运行时间统计 */ #if SYSCFG_RUNTIME_COUNT == __ENABLED__ if(true){ static #if SYSCFG_SYSTICKCYCLE > 1000000UL / 65536 s_u16_t #else s_u32_t #endif _SYS_MEM_ counter = 0; if(counter < 1000000UL / SYSCFG_SYSTICKCYCLE - 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__ tick_hook(); #endif /* 任务管理器 */ #if SYSCFG_DEBUGGING == __ENABLED__ if(s_sign_debug_send){ s_sign_debug_send = false; tTimQry_ms(OS_TMID_DEBUGHOOK, 30); } if(s_sign_debug_recv){ s_sign_debug_recv = false; tTimInt_ms(OS_TMID_DEBUGGER, 15); } #endif /* 定时中断 */ #if OS_TIMINTTOTAL 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 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){ #define hcurr htask s_tasknode_tsp _SYS_REG_ hlast; hcurr = s_list_timer; while(hcurr != OS_VOID){ if(hcurr->status == OS_STATUS_BLOCKED){ if(hcurr->timer && hcurr->timer < (s_delay_t)~0){ hcurr->timer--; if(!hcurr->timer){ hcurr->status = OS_STATUS_READY; sv_task_add_ready(hcurr); goto __NODE_REMOVE; } } } else if(hcurr->status & OS_STATUS_SUSPENDED){ if((hcurr->status & (~OS_STATUS_SUSPENDED & 0xFF)) == OS_STATUS_READY){ goto __NODE_REMOVE; } } else if(hcurr->status == OS_STATUS_DELETED){ if(hcurr->create && hcurr->next_b == OS_NULL){ sv_free_task(hcurr); } goto __NODE_REMOVE; } else{ goto __NODE_REMOVE; } hlast = hcurr; hcurr = hcurr->next_t; continue; __NODE_REMOVE: if(hcurr == s_list_timer){ s_list_timer = hcurr->next_t; hcurr->next_t = OS_NULL; hcurr = s_list_timer; } else{ hlast->next_t = hcurr->next_t; hcurr->next_t = OS_NULL; hcurr = hlast->next_t; } } #undef hcurr } /* 就绪延时 */ if(s_sign_ready_delay){ if(s_task_current->timer && s_task_current->timer < (s_delay_t)~0){ s_task_current->timer--; if(!s_task_current->timer){ s_sign_ready_delay = false; } } } /* 时间片 */ #if SYSCFG_SAMEPRISCHEDULE == __TIMESHARING__ if(s_task_current->tc_counter < OS_TIMESHARING(s_task_current)){ s_task_current->tc_counter++; } else{ s_sign_schedule = true; } #endif /* 安全运行时 */ /* 超时链表中的任务状态:超时、挂起、停止、删除。*/ #if SYSCFG_SAFERUNTIME == __ENABLED__ if(!s_sign_timeout){ htask = s_list_timeout; while(htask != OS_VOID){ if(htask->status == OS_STATUS_TIMEOUT){ htask->srt_counter = 0; htask->status = OS_STATUS_READY; sv_task_add_ready(htask); } else if(htask->status & OS_STATUS_SUSPENDED){ htask->srt_counter = 0; htask->status = OS_STATUS_SUSPENDED; } else if(htask->status == OS_STATUS_DELETED){ if(htask->create && htask->next_b == OS_NULL){ sv_free_task(htask); } } s_list_timeout = htask->next_t; htask->next_t = OS_NULL; htask = s_list_timeout; } } if(s_task_current->pri && s_task_current->saferuntime){ s_task_current->srt_counter++; if(s_task_current->srt_counter > 1UL * s_task_current->saferuntime * OS_TIMESHARING(s_task_current)){ if(s_task_current->status == OS_STATUS_READY){ s_task_current->next_t = s_list_timeout; s_list_timeout = s_task_current; sv_task_remove_ready(s_task_current); s_task_current->status = OS_STATUS_TIMEOUT; s_sign_timeout = true; #if SYSCFG_DEBUGGING == __ENABLED__ s_alarm.timeout_saferuntime = true; #endif } } } #endif /* 任务管理器 */ #if SYSCFG_DEBUGGING == __ENABLED__ if(s_sign_taskmgr){ usedtime[0]++; /*!< CPU使用时间计数 */ #if SYSCFG_SYSTICKTIME_COUNT == __ENABLED__ mSysTick_Counting; /*!< 系统滴答时间统计结束 */ #endif } #endif /* 任务调度 */ if(s_sign_schedule && !s_sign_schedule_forbid){ mPendSV_Set; } } s_tasknode_tsp _SYS_MEM_ s_task_news/**/sZeroInstall; #if SYSCFG_DEBUGGING == __ENABLED__ m_stacksize_t _SYS_MEM_ s_taskstacklen; #endif #if SYSCFG_MCUCORE == 80251 #pragma functions(static) #endif s_u8_t sPendSV_Handler(void) MCUCFG_C51USING { void pendsv_hook(void); void copy_hook(void); sCat2Str(SYSCFG_STARTERCREATE, ExternTask(Starter)); /* 中断挂起服务_FIFO */ #if MCUCFG_PENDSVFIFO_DEPTH > 0 mPendSV_FIFOHandle; #endif /* 中断挂起服务_FLAG */ #if SYSCFG_PENDSVHOOK == __ENABLED__ pendsv_hook(); #endif /* 更新全局变量副本 */ #if SYSCFG_GETRTC_INT == __ENABLED__ if(s_sign_rtc){ s_sign_rtc = false; sv_update_rtccopy(); } #endif #if SYSCFG_COPYHOOK == __ENABLED__ sUpdateCopy(copy_hook()); #endif /* 每PendSV监控(假定入栈)*/ #if SYSCFG_DEBUGGING == __ENABLED__ if(s_task_current != OS_NULL){ if(s_task_current->stacklen_max < s_taskstacklen){ s_task_current->stacklen_max = s_taskstacklen; if(s_task_current->stacksize < s_taskstacklen){ s_alarm.overflow_taskstack = true; } } } #endif /* 任务调度 */ if(s_sign_schedule_forbid) return 0; if(s_sign_schedule){ s_tasknode_tsp _SYS_REG_ node_news; m_bit_t sign_push = false; /*!< 入栈信号 */ #if SYSCFG_SAMEPRISCHEDULE s_u8_t _SYS_REG_ pri; #endif #if SYSCFG_DEBUGGING == __ENABLED__ m_tick_t _SYS_REG_ tick_counter; #endif s_sign_schedule = false; /* 启动任务 */ if(s_task_starter != OS_NULL){ /* 静态创建 */ if(*s_task_starter->dualhandle != OS_NULL){ node_news = (s_tasknode_tsp)s_task_starter; if(node_news->stacksize < MCUCFG_BASICSTACKSIZE){ #if SYSCFG_DEBUGGING == __ENABLED__ s_fault.failed_startuptask = true; s_fault.overflow_taskstack = true; #endif s_startup_code = OS_ECODE_OVERFLOW_TASKSTACK; goto __STARTUP_END; } else{ mTaskStack_INIT; } } /* 动态创建 */ else{ node_news = OS_NULL; node_news = (s_tasknode_tsp)s_malloc(sizeof(s_tasknode_ts)); if(node_news != OS_NULL){ node_news->stacksize = s_task_starter->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){ mTaskStack_INIT; node_news->opri = s_task_starter->opri; node_news->dualhandle = s_task_starter->dualhandle; *node_news->dualhandle = node_news; #if SYSCFG_DEBUGGING == __ENABLED__ node_news->name = s_task_starter->name; #endif #if SYSCFG_SAFERUNTIME == __ENABLED__ node_news->saferuntime = s_task_starter->saferuntime; #endif } else{ s_free(node_news); #if SYSCFG_DEBUGGING == __ENABLED__ s_fault.failed_startuptask = true; s_fault.mallocfailed_taskstack = true; #endif s_startup_code = OS_ECODE_MALLOCFAIL_TASKSTACK; goto __STARTUP_END; } } else{ #if SYSCFG_DEBUGGING == __ENABLED__ s_fault.failed_startuptask = true; s_fault.mallocfailed_tasknode = true; #endif s_startup_code = OS_ECODE_MALLOCFAIL_TASKNODE; goto __STARTUP_END; } } /* 公共部分 */ if(node_news->opri <= (s_u8_t)(SYSCFG_TASKPRIORITY - 2)){ node_news->pri = node_news->opri; } else{ node_news->pri = SYSCFG_TASKPRIORITY - 2; #if SYSCFG_DEBUGGING == __ENABLED__ s_alarm.outrange_taskpriority = true; #endif } node_news->status = s_task_status0; node_news->blocktype = 0; node_news->timer = 0; #if SYSCFG_MCUCORE == 8051 node_news->handle = OS_NULL; #endif #if 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->next_b = OS_NULL; node_news->next_t = OS_NULL; sv_insert_task_queue(node_news); s_task_queue_count++; if(s_task_status0 == OS_STATUS_READY){ sv_task_add_ready(node_news); s_sign_schedule = false; } s_startup_code = OS_ECODE_NOERROR; __STARTUP_END: s_task_starter = OS_NULL; if(node_news == u_taskhandle_Starter){ goto __NEWTASK_PREPROCESS; /*!< 首次任务调度 -> 新任务预处理 */ } else{ return 0; } } /* 任务调度 */ #if SYSCFG_SAMEPRISCHEDULE pri = sv_task_select_ready(); node_news = s_task_queue[pri]; while(true){ #if SYSCFG_SAMEPRISCHEDULE == __TIMESHARING__ s_tasknode_tsp _SYS_REG_ node_temp; #endif if(node_news->status == OS_STATUS_READY){ #if SYSCFG_SAMEPRISCHEDULE == __COOPERATIVE__ break; #elif SYSCFG_SAMEPRISCHEDULE == __TIMESHARING__ if(node_news->tc_counter < OS_TIMESHARING(node_news)){ /* 时间片未到期 */ break; } else{ /* 时间片已到期 */ node_news->tc_counter = 0; node_temp = node_news; } #endif } #if SYSCFG_SAMEPRISCHEDULE == __COOPERATIVE__ node_news = node_news->next; #elif SYSCFG_SAMEPRISCHEDULE == __TIMESHARING__ if(node_news != s_task_queue[pri]->last){ node_news = node_news->next; } else{ node_news = node_temp; break; /* 在该优先级组中,未能找到时间片未到期的就绪任务,继续已到期的就绪任务 */ } #endif } #else node_news = s_task_queue[sv_task_select_ready()]; #endif if(node_news == s_task_current){ /* 新任务仍为当前任务 -> 返回 */ goto __TASKING_RETURN; } #if SYSCFG_SAMEPRISCHEDULE else if(node_news != s_task_queue[pri]){ /* 新任务轮转至其优先级组首节点 */ s_task_queue[pri] = node_news; } #endif /* 当前任务后处理 */ if(s_task_current->status < OS_STATUS_STOPPED){ #if SYSCFG_DEBUGGING == __ENABLED__ /* 入栈监控 */ if(s_task_current->stacksize < s_taskstacklen){ #if MCUCFG_TASKSTACK_REALLOC == __ENABLED__ if(s_task_current->create){ s_task_current->stacksize = s_taskstacklen + MCUCFG_TASKSTACKREALLOC_INC; 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){ sign_push = true; s_task_current->create = 2; s_alarm.realloc_taskstack = true; } else{ s_task_current->status = OS_STATUS_STOPPED; s_fault.reallocfailed_taskstack = true; } } else{ s_task_current->status = OS_STATUS_STOPPED; s_fault.overflow_taskstack = true; } #else s_task_current->status = OS_STATUS_STOPPED; s_fault.overflow_taskstack = true; #endif } else{ sign_push = true; } #else sign_push = true; #endif } /* 新任务预处理 */ __NEWTASK_PREPROCESS:{ #if SYSCFG_DEBUGGING == __ENABLED__ if(s_sign_taskmgr) tick_counter = mSysTick_Counter; #endif } /* 当前任务入栈 */ if(sign_push){ #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_sign_taskmgr) mUsedTime_END; #endif mUserReg_CSave; } /* 新任务出栈 */ if(true){ if(node_news->blocktype){ node_news->blocktype = 0; mSysIRQ_Disable; } #if SYSCFG_DEBUGGING == __ENABLED__ if(s_sign_taskmgr) mUsedTime_INIT; #endif mUserReg_CRes; s_task_news = node_news; } if(sign_push) return 2; else return 1; } __TASKING_RETURN:{ if(s_task_current->blocktype){ s_task_current->blocktype = 0; mSysIRQ_Disable; } return 0; } }