diff --git a/System/os_handler.c b/System/os_handler.c new file mode 100644 index 00000000..e5b9728c --- /dev/null +++ b/System/os_handler.c @@ -0,0 +1,724 @@ +/**************************************************************************//** + * @item CosyOS-III Kernel + * @file os_handler.c + * @brief tCosyTick_Handler and sPendSV_Handler + * @author 迟凯峰 + * @version V1.3.1 + * @date 2025.05.31 + ******************************************************************************/ + +#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 + +#if defined ( __GNUC__ ) +#define sKill_W(p) p +#else +#define sKill_W(p) +#endif + +sCat2Str(SYSCFG_STARTERCREATE, ExternTask(Starter)); +#if SYSCFG_DEBUGGING == __ENABLED__ +__IAR_WEAK s_u32_t usedtime[2]/**/sZeroInstall_Group; +__IAR_WEAK m_stacksize_t _SYS_MEM_ s_taskstacklen; +#endif + +__IAR_WEAK void tCosyTick_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__ + m_tick_t ticktemp_s sKill_W(=0); + #endif + s_tasknode_tsp _SYS_REG_ htask; + + /* 清除中断标志位 */ + mSysTick_Clear(); + + /* 系统滴答时间统计开始 */ + #if SYSCFG_SYSTICKTIME_COUNT == __ENABLED__ + if(s_sign_taskmgr){ + ticktemp_s = MCUCFG_SYSTICK_CURRVALUE; + } + #endif + + /* 软件RTC */ + #if SYSCFG_SOFTRTC == __ENABLED__ + if(true){ + static + #if SYSCFG_SYSTICK_CYCLE > 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_SYSTICK_CYCLE / 2; + } + else{ + 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++; + } + } + } + } + } + } + #if SYSCFG_GETRTC_INT == __ENABLED__ + sv_update_rtccopy(); + #endif + } + } + } + #endif + + /* 运行时间统计 */ + #if SYSCFG_RUNTIME_COUNT == __ENABLED__ + if(true){ + static + #if SYSCFG_SYSTICK_CYCLE > 1000000UL / 65536 + s_u16_t + #else + s_u32_t + #endif + _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__ + tick_hook(); + #endif + + /* 任务管理器 */ + #if SYSCFG_DEBUGGING == __ENABLED__ + if(s_sign_debugsend){ + s_sign_debugsend = false; + tTimQry_ms(OS_TMID_DEBUGGER, 10); + } + #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 sKill_W(=OS_NULL); + hcurr = s_list_timer; + while(hcurr != OS_VOID){ + if(hcurr->status == OS_STATUS_FLOATING || hcurr->status == OS_STATUS_BLOCKED){ + if(~hcurr->timer){ + hcurr->timer--; + if(!hcurr->timer){ + sv_clear_block(hcurr); + goto __NODE_REMOVE; + } + } + else{ + goto __NODE_REMOVE; + } + } + else if(hcurr->status & OS_STATUS_SUSPENDED); + else if(hcurr->status == OS_STATUS_DELETED){ + if(hcurr->create){ + 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--; + 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.every[1] = false; + } + #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; + sv_task_add_ready(htask); + htask->status = OS_STATUS_READY; + } + else if(htask->status & OS_STATUS_SUSPENDED){ + htask->srt_counter = 0; + htask->status = OS_STATUS_READY | OS_STATUS_SUSPENDED; + } + else if(htask->status == OS_STATUS_DELETED){ + if(htask->create){ + 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){ + /* 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 + + /* 任务调度 */ + if(!s_sign_schedule.total){ + mPendSV_Set(); + } +} + +__IAR_WEAK bool _start_task_(void) MCUCFG_C51USING +{ + s_tasknode_tsp _SYS_REG_ node_news; + /* 静态创建 */ + 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 - 1)){ + node_news->pri = node_news->opri; + } + else{ + node_news->pri = SYSCFG_TASKPRIORITY - 1; + #if SYSCFG_DEBUGGING == __ENABLED__ + s_alarm.outrange_taskpriority = true; + #endif + } + node_news->status = s_task_status0; + node_news->blocktype = 0; + node_news->timer = 0; + node_news->handle = OS_NULL; + #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->last_b = OS_NULL; + node_news->next_b = OS_NULL; + node_news->next_t = OS_NULL; + #if SYSCFG_SAMEPRISCHEDULE && SYSCFG_MUTEX == __ENABLED__ + node_news->link = OS_NULL; + #endif + 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.every[1] = true; + } + s_startup_code = OS_ECODE_NOERROR; + __STARTUP_END: + s_task_starter = OS_NULL; + if(node_news == u_taskhandle_Starter){ + return true; + } + else{ + return false; + } +} + +#if SYSCFG_DEBUGGING == __ENABLED__ +__IAR_WEAK void _cpu_usedtime_(m_tick_t ticktemp_0) MCUCFG_C51USING +{ + #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 + +void pendsv_hook(void); +void copy_hook(void); +#if (defined ( __CC_ARM )) +register s_tasknode_tsp node_news __ASM("r3"); +#else +__IAR_WEAK s_tasknode_tsp _SYS_MEM_ s_task_news/**/sZeroInstall; +#endif +#if SYSCFG_MCUCORE == 80251 +#pragma functions(static) +#endif +__IAR_WEAK s_u8_t sPendSV_Handler(void) MCUCFG_C51USING +{ + /* 中断挂起服务_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){ + mTaskStack_LEN(); + 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.total) return 0; + else{ + #if SYSCFG_DEBUGGING == __ENABLED__ + m_tick_t _SYS_REG_ ticktemp_0 sKill_W(=0); + #endif + #if (!defined ( __CC_ARM )) + s_tasknode_tsp _SYS_REG_ node_news; + #endif + s_tasknode_tsp _SYS_REG_ node_temp sKill_W(=OS_NULL); + s_u8_t _SYS_REG_ pri; + m_bit_t sign_push = false; /*!< 入栈信号 */ + s_sign_schedule.every[1] = true; + + /* 启动任务 */ + if(s_task_starter != OS_NULL){ + if(_start_task_()){ + node_news = u_taskhandle_Starter; + goto __NEWTASK_PREPROCESS; /*!< 首次任务调度 -> 新任务预处理 */ + } + else return 0; + } + + /* 选择就绪 */ + if(true){ + #if SYSCFG_TASKPRIORITY > 64 + s_u8_t table_index = s_task_map_pick[s_task_table_index >> (SYSCFG_TASKPICKBITMAP & 1)]; + s_u8_t bytes_index = s_task_map_pick[s_task_bytes_index[table_index] >> (SYSCFG_TASKPICKBITMAP & 1)]; + s_u8_t bit_index = s_task_map_pick[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_map_pick[s_task_bytes_index >> (SYSCFG_TASKPICKBITMAP & 1)]; + s_u8_t bit_index = s_task_map_pick[s_task_ready_table[bytes_index] >> (SYSCFG_TASKPICKBITMAP & 1)]; + pri = (bytes_index << 3) + bit_index; + #else + pri = s_task_map_pick[s_task_ready_table >> (SYSCFG_TASKPICKBITMAP & 1)]; + #endif + node_news = s_task_queue[pri]; + } + + /* 协作式调度 */ + #if SYSCFG_SAMEPRISCHEDULE == __COOPERATIVE__ + while(true){ + if(node_news->status <= OS_STATUS_FLOATING){ + break; + } + node_news = node_news->next; + } + #endif + + /* 时间片轮转调度 */ + #if SYSCFG_SAMEPRISCHEDULE == __TIMESHARING__ + while(true){ + if(node_news->status <= OS_STATUS_FLOATING){ + if(node_news->tc_counter < OS_TIMESHARING(node_news)){ /* 时间片未到期 */ + break; + } + else{ /* 时间片已到期 */ + node_news->tc_counter = 0; + 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->status == OS_STATUS_FLOATING){ + node_news->status = OS_STATUS_READY; + sv_remove_block_list(node_news); + } + + /* 新任务仍为当前任务 -> 返回 */ + if(node_news == s_task_current){ + goto __TASKING_RETURN; + } + + /* 新任务轮转至其优先级组首节点 */ + #if SYSCFG_SAMEPRISCHEDULE + if(node_news != s_task_queue[pri]){ + s_task_queue[pri] = node_news; + } + #endif + + /* 入栈监控 */ + #if SYSCFG_DEBUGGING == __ENABLED__ + if(s_task_current->status < OS_STATUS_STOPPED){ + if(s_task_current->stacksize < s_taskstacklen){ + #if MCUCFG_TASKSTACK_REALLOC == __ENABLED__ + if(s_task_current->create){ + s_task_current->stacksize = s_taskstacklen + 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){ + sign_push = true; + s_task_current->create = 2; + s_alarm.realloc_taskstack = true; + } + else{ + sv_stop_task(s_task_current); + s_fault.reallocfailed_taskstack = true; + } + } + else{ + sv_stop_task(s_task_current); + s_fault.overflow_taskstack = true; + } + #else + sv_stop_task(s_task_current); + 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){ + ticktemp_0 = MCUCFG_SYSTICK_CURRVALUE; + } + #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){ + _cpu_usedtime_(ticktemp_0); + } + #endif + mUserReg_SAVEc(); + } + + /* 新任务出栈 */ + if(true){ + if(node_news->blocktype){ + node_news->blocktype = 0; + mSysIRQ_Disable(); + } + #if SYSCFG_DEBUGGING == __ENABLED__ + if(s_sign_taskmgr){ + usedtime[1] = ticktemp_0; + } + #endif + mUserReg_RESc(); + #if (!defined ( __CC_ARM )) + s_task_news = node_news; + #endif + } + + return (s_u8_t)sign_push + 1; + } + + __TASKING_RETURN:{ + if(s_task_current->blocktype){ + s_task_current->blocktype = 0; + mSysIRQ_Disable(); + } + return 0; + } +} diff --git a/System/sv_com.c b/System/sv_com.c new file mode 100644 index 00000000..539ff897 --- /dev/null +++ b/System/sv_com.c @@ -0,0 +1,664 @@ +/**************************************************************************//** + * @item CosyOS-III Kernel + * @file sv_com.c + * @brief 内核服务公共函数 + * @details 在服务层临界区中,由内核服务调用。 + * @author 迟凯峰 + * @version V1.2.7 + * @date 2025.05.31 + ******************************************************************************/ + +#include "os_var.h" +#include "os_api.h" +#include "sv_com.h" + +#if SYSCFG_MCUCORE == 8051 +#pragma NOAREGS /* 相对寄存器访问 for C51 */ +#endif + +/** + \brief 插入至任务队列 + \details 插入任务节点至任务队列尾。 + \param[in] htask 任务句柄 + \return 无 + */ +void sv_insert_task_queue(s_tasknode_tsp htask) +{ + s_u8_t pri = htask->pri; + #if SYSCFG_SAMEPRISCHEDULE + if(s_task_queue[pri] == OS_NULL){ + s_task_queue[pri] = htask->last = htask->next = htask; + } + else{ + htask->last = s_task_queue[pri]->last; + htask->next = s_task_queue[pri]; + s_task_queue[pri]->last->next = htask; + s_task_queue[pri]->last = htask; + } + #else + s_task_queue[pri] = htask; + #endif +} + +/** + \brief 移除从任务队列 + \details 从任务队列中移除任务节点。 + \param[in] htask 任务句柄 + \return 无 + */ +void sv_remove_task_queue(s_tasknode_tsp htask) +{ + s_u8_t pri = htask->pri; + #if SYSCFG_SAMEPRISCHEDULE + if(s_task_queue[pri] == s_task_queue[pri]->last){ + s_task_queue[pri] = OS_NULL; + } + else{ + htask->last->next = htask->next; + htask->next->last = htask->last; + if(htask == s_task_queue[pri]){ + s_task_queue[pri] = htask->next; + } + } + #else + s_task_queue[pri] = OS_NULL; + #endif +} + +/** + \brief 加入就绪 + \details 任务由非就绪状态变为就绪状态的相关调整。 + \param[in] htask 任务句柄 + \return 无 + */ +void sv_task_add_ready(s_tasknode_tsp htask) +{ + s_u8_t pri = htask->pri; + if(pri > s_task_current->pri){ + s_sign_schedule.every[1] = false; + } + #if SYSCFG_SAMEPRISCHEDULE + #if SYSCFG_SAMEPRISCHEDULE == __TIMESHARING__ + htask->tc_counter = 0; + #endif + if(s_task_ready_count[pri]++) return; + #endif + if(true){ + s_u8_t bit_index = (pri & 7); + #if SYSCFG_TASKPRIORITY > 64 + s_u8_t table_index = (pri >> 6); + s_u8_t bytes_index = (pri & 63) >> 3; + s_task_table_index |= (1 << table_index); + s_task_bytes_index[table_index] |= (1 << bytes_index); + s_task_ready_table[table_index][bytes_index] |= (1 << bit_index); + #elif SYSCFG_TASKPRIORITY > 8 + s_u8_t bytes_index = (pri >> 3); + s_task_bytes_index |= (1 << bytes_index); + s_task_ready_table[bytes_index] |= (1 << bit_index); + #else + s_task_ready_table |= (1 << bit_index); + #endif + } +} + +/** + \brief 移除就绪 + \details 任务由就绪状态变为非就绪状态的相关调整。 + \param[in] htask 任务句柄 + \return 无 + */ +void sv_task_remove_ready(s_tasknode_tsp htask) +{ + s_u8_t pri = htask->pri; + if(htask == s_task_current){ + s_sign_schedule.every[1] = false; + } + #if SYSCFG_SAMEPRISCHEDULE + if(--s_task_ready_count[pri]) return; + #endif + if(true){ + s_u8_t bit_index = (pri & 7); + #if SYSCFG_TASKPRIORITY > 64 + s_u8_t table_index = (pri >> 6); + s_u8_t bytes_index = (pri & 63) >> 3; + s_task_ready_table[table_index][bytes_index] &= ~(1 << bit_index); + if(!s_task_ready_table[table_index][bytes_index]){ + s_task_bytes_index[table_index] &= ~(1 << bytes_index); + if(!s_task_bytes_index[table_index]){ + s_task_table_index &= ~(1 << table_index); + } + } + #elif SYSCFG_TASKPRIORITY > 8 + s_u8_t bytes_index = (pri >> 3); + s_task_ready_table[bytes_index] &= ~(1 << bit_index); + if(!s_task_ready_table[bytes_index]){ + s_task_bytes_index &= ~(1 << bytes_index); + } + #else + s_task_ready_table &= ~(1 << bit_index); + #endif + } +} + +/** + \brief 释放任务内存 + \details 动态创建的任务被删除,需释放相应的动态内存。 + \param[in] htask 任务句柄 + \return 无 + */ +__NOINLINE void sv_free_task(s_tasknode_tsp htask) +{ + s_free(htask->bsp); + *htask->dualhandle = OS_NULL; + s_free(htask); +} + +/** + \brief 停止任务 + \param[in] htask 任务句柄 + \return 无 + */ +__NOINLINE void sv_stop_task(s_tasknode_tsp htask) +{ + if(htask->status <= OS_STATUS_FLOATING){ + sv_task_remove_ready(htask); + } + htask->status = OS_STATUS_STOPPED; + if(htask->next_b != OS_NULL){ + sv_remove_block_list(htask); + } +} + +/** + \brief 删除任务 + \param[in] htask 任务句柄 + \return 无 + */ +__NOINLINE void sv_delete_task(s_tasknode_tsp htask) +{ + if(htask->status <= OS_STATUS_FLOATING){ + sv_task_remove_ready(htask); + } + htask->status = OS_STATUS_DELETED; + if(htask->next_b != OS_NULL){ + sv_remove_block_list(htask); + } + sv_remove_task_queue(htask); + s_task_queue_count--; + if(htask->create && htask->next_t == OS_NULL){ + sv_free_task(htask); + } +} + +/** + \brief 恢复任务 + \param[in] htask 任务句柄 + \return 无 + */ +void sv_resume_task(s_tasknode_tsp htask) +{ + htask->status &= (~OS_STATUS_SUSPENDED & 0xFF); + if(htask->status <= OS_STATUS_FLOATING){ + sv_task_add_ready(htask); + } +} + +/** + \brief 挂起任务 + \param[in] htask 任务句柄 + \return 无 + */ +void sv_suspend_task(s_tasknode_tsp htask) +{ + if(htask->status <= OS_STATUS_FLOATING){ + sv_task_remove_ready(htask); + } + htask->status |= OS_STATUS_SUSPENDED; +} + +/** + \brief 清除阻塞(状态) + \param[in] htask 任务句柄 + \return 无 + */ +void sv_clear_block(s_tasknode_tsp htask) +{ + if(htask->status == OS_STATUS_BLOCKED){ + sv_task_add_ready(htask); + } + htask->status = OS_STATUS_READY; +// htask->timer = 0; + if(htask->next_b != OS_NULL){ + sv_remove_block_list(htask); + } +} + +/** + \brief 设置阻塞(时间) + \param[in] htask 任务句柄 + \param[in] tick 滴答周期(阻塞时间)
+ +0:清除阻塞
+ ~0:无限阻塞 + \return 无 + */ +void sv_set_block(s_tasknode_tsp htask, s_delay_t tick) +{ + if(!tick){ + sv_clear_block(htask); + } + else{ + if(~tick){ + if(htask->next_t == OS_NULL){ + htask->next_t = s_list_timer; + s_list_timer = htask; + } + } + htask->timer = tick; + } +} + +/** + \brief 设置任务优先级 + \param[in] htask 任务句柄 + \param[in] npri 新优先级 + \return 无 + */ +void sv_set_taskpri(s_tasknode_tsp htask, s_u8_t npri) +{ + sv_remove_task_queue(htask); + if(htask->status <= OS_STATUS_FLOATING){ + sv_task_remove_ready(htask); + htask->pri = npri; + sv_task_add_ready(htask); + } + else{ + htask->pri = npri; + } + sv_insert_task_queue(htask); +} + +/** + \brief 移除从阻塞链表 + \param[in] htask 任务句柄 + \return 无 + */ +void sv_remove_block_list(s_tasknode_tsp htask) +{ + s_tasknode_tsp *h2task = (s_tasknode_tsp *)htask->handle; + if(htask == htask->next_b){ + *h2task = OS_NULL; + } + else{ + htask->last_b->next_b = htask->next_b; + htask->next_b->last_b = htask->last_b; + if(htask == *h2task){ + *h2task = htask->next_b; + } + } + #if SYSCFG_SAMEPRISCHEDULE && SYSCFG_MUTEX == __ENABLED__ + htask->link = + #endif +// htask->last_b = + htask->next_b = OS_NULL; +} + +/** + \brief 当前任务插入至阻塞链表 + \param[in] h2task 指向链表头的指针 + \return 无 + */ +void sv_insert_block_list(s_tasknode_tsp *h2task) +{ + s_tasknode_tsp htask = *h2task; + if(htask == OS_NULL){ + *h2task = s_task_current->last_b = s_task_current->next_b = s_task_current; + } + else{ + s_task_current->last_b = htask->last_b; + s_task_current->next_b = htask; + htask->last_b->next_b = s_task_current; + htask->last_b = s_task_current; + } +} + +/** + \brief 阻塞变就绪 + \param[in] h2task 指向链表头的指针 + \return 无 + */ +void sv_block_to_ready(s_tasknode_tsp *h2task) +{ + s_tasknode_tsp htask = *h2task; + if(htask->status == OS_STATUS_BLOCKED){ + htask->status = OS_STATUS_READY; + sv_task_add_ready(htask); + } + else if(htask->status == (OS_STATUS_BLOCKED | OS_STATUS_SUSPENDED)){ + htask->status = OS_STATUS_READY | OS_STATUS_SUSPENDED; + } + *h2task = + #if SYSCFG_SAMEPRISCHEDULE && SYSCFG_MUTEX == __ENABLED__ + htask->link = + #endif +// htask->last_b = + htask->next_b = OS_NULL; +} + +/** + \brief 阻塞变浮动 + \param[in] htask 任务句柄 + \return 无 + */ +void sv_block_to_float(s_tasknode_tsp htask) +{ + s_tasknode_tsp htemp = htask; + while(true){ + if(htemp->status == OS_STATUS_BLOCKED){ + htemp->status = OS_STATUS_FLOATING; + sv_task_add_ready(htemp); + } + else if(htemp->status == (OS_STATUS_BLOCKED | OS_STATUS_SUSPENDED)){ + htemp->status = OS_STATUS_FLOATING | OS_STATUS_SUSPENDED; + } + htemp = htemp->next_b; + if(htask == htemp){ + break; + } + } +} + +/** + \brief 浮动变阻塞 + \param[in] htask 任务句柄 + \return 无 + */ +void sv_float_to_block(s_tasknode_tsp htask) +{ + s_tasknode_tsp htemp = htask; + while(true){ + if(htemp->status == OS_STATUS_FLOATING){ + htemp->status = OS_STATUS_BLOCKED; + sv_task_remove_ready(htemp); + } + else if(htemp->status == (OS_STATUS_FLOATING | OS_STATUS_SUSPENDED)){ + htemp->status = OS_STATUS_BLOCKED | OS_STATUS_SUSPENDED; + } + htemp = htemp->next_b; + if(htask == htemp){ + break; + } + } +} + +/** + \brief 当前任务插入至定时器链表 + \param 无 + \return 无 + */ +void sv_insert_timer_list(void) +{ + if(s_task_current->next_t == OS_NULL){ + s_task_current->next_t = s_list_timer; + s_list_timer = s_task_current; + } +} + +#if SYSCFG_BINARY == __ENABLED__ +/** + \brief 给予二值信号量 + \param[in] hbin 二值信号量句柄 + \return 无 + */ +void sv_give_binary(s_binary_tsp hbin) +{ + hbin->binary = true; + if(hbin->htask != OS_NULL){ + sv_block_to_float(hbin->htask); + } +} +#endif + +#if SYSCFG_SEMAPHORE == __ENABLED__ +/** + \brief 给予计数信号量 + \param[in] hsem 计数信号量句柄 + \return 无 + */ +void sv_give_semaphore(s_semaph_tsp hsem) +{ + s_semsize_t counter = hsem->counter; + if(counter < hsem->maximum){ + hsem->counter = counter + 1; + } + if(!counter && hsem->htask != OS_NULL){ + sv_block_to_float(hsem->htask); + } +} +#endif + +#if SYSCFG_FETION == __ENABLED__ +/** + \brief 发送飞信 + \param[in] htbox 信箱句柄 + \param[in] tion 飞信 + \return 无 + */ +void sv_send_fetion(s_tionbox_tsp htbox, m_fetion_t tion) +{ + htbox->tion = tion; + if(htbox->htask != OS_NULL){ + sv_block_to_ready(&htbox->htask); + } +} +#endif + +#if SYSCFG_MAILBOX == __ENABLED__ +/** + \brief 发送邮件 + \param[in] hmbox 邮箱句柄 + \param[in] mail 邮件指针 + \return 无 + */ +void sv_send_mail(s_mailbox_tsp hmbox, void *mail) +{ + hmbox->flag = false; + hmbox->mail = mail; + hmbox->flag = true; + if(hmbox->htask != OS_NULL){ + sv_block_to_ready(&hmbox->htask); + } +} +#endif + +#if SYSCFG_MSGQUEUE == __ENABLED__ +/** + \brief 发送消息 + \param[in] hque 队列句柄 + \param[in] msg 消息指针 + \return 错误码 + */ +s_ecode_t sv_send_msg(s_queue_tsp hque, void *msg) +{ + hque->mutex = false; + if(hque->counter == hque->len){ + #if SYSCFG_DEBUGGING == __ENABLED__ + s_alarm.overflow_msgqueue = true; + #endif + hque->mutex = true; + return OS_ECODE_OVERFLOW_MSGQUEUE; + } + if(hque->type == __DYNAMIC__){ + s_msgnode_tsp hmsg = OS_NULL; + hmsg = (s_msgnode_tsp)s_malloc(sizeof(s_msgnode_ts)); + if(hmsg == OS_NULL){ + #if SYSCFG_DEBUGGING == __ENABLED__ + s_fault.mallocfailed_msgnode = true; + #endif + hque->mutex = true; + return OS_ECODE_MALLOCFAIL_MSGNODE; + } + hmsg->msg = msg; + hmsg->next = OS_NULL; + hmsg->last = ((sd_queue_tsp)hque)->tail; + if(((sd_queue_tsp)hque)->tail != OS_NULL){ + ((sd_queue_tsp)hque)->tail->next = hmsg; + } + ((sd_queue_tsp)hque)->tail = hmsg; + if(((sd_queue_tsp)hque)->head == OS_NULL){ + ((sd_queue_tsp)hque)->head = hmsg; + } + } + else{ + if(((ss_queue_tsp)hque)->tail < ((ss_queue_tsp)hque)->base + hque->len - 1){ + ((ss_queue_tsp)hque)->tail++; + } + else{ + ((ss_queue_tsp)hque)->tail = ((ss_queue_tsp)hque)->base; + } + *((ss_queue_tsp)hque)->tail = msg; + } + hque->counter++; + if(hque->htask != OS_NULL){ + sv_block_to_ready(&hque->htask); + } + hque->mutex = true; + return OS_ECODE_NOERROR; +} + +/** + \brief 接收消息(静态队列) + \param[in] hque 队列句柄 + \return 消息指针 + */ +void *sv_recv_msg_static(ss_queue_tsp hque) +{ + void *msg; + if(hque->mode == __QUE_LIFO__){ + msg = *hque->tail; + if(hque->tail > hque->base){ + hque->tail--; + } + else{ + hque->tail = hque->base + hque->len - 1; + } + } + else{ + msg = *hque->head; + if(hque->head < hque->base + hque->len - 1){ + hque->head++; + } + else{ + hque->head = hque->base; + } + } + hque->counter--; + return msg; +} + +/** + \brief 接收消息(动态队列) + \param[in] hque 队列句柄 + \return 消息指针 + */ +void *sv_recv_msg_dynamic(sd_queue_tsp hque) +{ + void *msg; + s_msgnode_tsp hmsg; + if(hque->mode == __QUE_LIFO__){ + hmsg = hque->tail; + msg = hmsg->msg; + hmsg = hmsg->last; + s_free(hque->tail); + hque->tail = hmsg; + if(hmsg == OS_NULL){ + hque->head = OS_NULL; + } + else{ + hmsg->next = OS_NULL; + } + } + else{ + hmsg = hque->head; + msg = hmsg->msg; + hmsg = hmsg->next; + s_free(hque->head); + hque->head = hmsg; + if(hmsg == OS_NULL){ + hque->tail = OS_NULL; + } + else{ + hmsg->last = OS_NULL; + } + } + hque->counter--; + return msg; +} +#endif + +#if OS_TIMINTTOTAL +/** + \brief 定时中断 + \param[in] tmid 定时中断定时器ID + \param[in] tick 滴答周期(定时时间) + \return 无 + */ +void sv_timint(s_u8_t tmid, s_timint_t tick) +{ + s_timint_handle[tmid]->timer + = s_timint_handle[tmid]->reload + = tick; +} +#endif + +#if OS_TIMQRYTOTAL +/** + \brief 定时查询 + \param[in] tmid 定时查询定时器ID + \param[in] tick 滴答周期(定时时间) + \return 无 + */ +void sv_timqry(s_u8_t tmid, s_timqry_t tick) +{ + s_timqry_handle[tmid]->timer + = s_timqry_handle[tmid]->reload + = tick; +} +#endif + +/** + \brief 清除就绪延时 + \param 无 + \return 无 + */ +void sv_clear_delay(void) +{ + if(s_sign_ready_delay){ + s_sign_ready_delay = false; +// s_task_current->timer = 0; + } +} + +#if SYSCFG_GETRTC_INT == __ENABLED__ +/** + \brief 更新RTC副本 + \param 无 + \return 无 + */ +void sv_update_rtccopy(void) +{ + s_sign_updatecopy = true; + #if SYSCFG_MCUCORE == 8051 + s_rtc_copy.yeah = s_rtc.yeah; + s_rtc_copy.year = s_rtc.year; + s_rtc_copy.month = s_rtc.month; + s_rtc_copy.date = s_rtc.date; + s_rtc_copy.hour = s_rtc.hour; + s_rtc_copy.minute = s_rtc.minute; + s_rtc_copy.second = s_rtc.second; + s_rtc_copy.day = s_rtc.day; + #else + s_rtc_copy = s_rtc; + #endif + s_sign_updatecopy = false; +} +#endif diff --git a/System/sv_task.c b/System/sv_task.c new file mode 100644 index 00000000..8a6deaaa --- /dev/null +++ b/System/sv_task.c @@ -0,0 +1,982 @@ +/**************************************************************************//** + * @item CosyOS-III Kernel + * @file sv_task.c + * @brief 任务服务 + * @details 仅在任务中调用并执行。 + * @author 迟凯峰 + * @version V1.2.7 + * @date 2025.05.31 + ******************************************************************************/ + +#include "os_var.h" +#include "os_api.h" +#include "sv_com.h" +#include "sv_task.h" + +/** + @addtogroup CosyOS_内核服务 + @{ + *//** + \defgroup 任务服务 + \brief 仅在任务中调用并执行。 + @{ + */ +#if MCUCFG_ISA != __ARM__ +/** 调度上锁(进入嵌套任务临界区)*/ +void su_schedule_locks(void) +{ + s_sign_schedule.every[0] = true; + s_schedulelock_counter++; +} + +/** 内核上锁(进入非嵌套服务层临界区)*/ +void su_kernel_lock0(void) +{ + mSysIRQ_Disable(); +} + +/** 内核上锁(进入嵌套服务层临界区)*/ +#if SYSCFG_KERNELLOCKNESTING == __ENABLED__ +void su_kernel_locks(void) +{ + mSysIRQ_Disable(); + s_kernellock_counter++; +} +#endif +#endif + +/** 调度解锁(退出嵌套任务临界区)*/ +void su_schedule_unlocks(void) +{ + s_schedulelock_counter--; + if(!s_schedulelock_counter){ + #if SYSCFG_KERNELLOCKNESTING == __ENABLED__ + if(!s_sign_schedule.every[1] && !s_kernellock_counter){ + #else + if(!s_sign_schedule.every[1]){ + #endif + s_sign_schedule.every[0] = false; + mPendSV_Set(); + while(!s_sign_schedule.every[1]); + } + else{ + s_sign_schedule.every[0] = false; + } + } +} + +/** 内核解锁(退出嵌套服务层临界区)*/ +void su_kernel_unlocks(void) +{ + #if SYSCFG_KERNELLOCKNESTING == __ENABLED__ + s_kernellock_counter--; + if(s_kernellock_counter) return; + #endif + if(!s_sign_schedule.total){ + mPendSV_Set(); + mSysIRQ_Enable(); + #if MCUCFG_ISA == __ARM__ + OS_NOP(1); + #endif + while(!s_sign_schedule.every[1]); + } + else{ + mSysIRQ_Enable(); + } +} + +/** 内核解锁(退出嵌套服务层临界区)并返回(void *) */ +void *su_kernel_unlocks_ret(void *p) +{ + su_kernel_unlocks(); + return p; +} + +/** 内核解锁(退出非嵌套服务层临界区)并触发任务调度 */ +void su_kernel_unlock0_psv(void) +{ + s_sign_schedule.every[1] = false; + mPendSV_Set(); + mSysIRQ_Enable(); + #if MCUCFG_ISA == __ARM__ + OS_NOP(1); + #endif + while(!s_sign_schedule.every[1]); +} + + + +/* + * 操作任务 + */ + +/** + \brief 启动任务 + \param[in] hhand 任务HAND句柄 + \param[in] status 任务初始状态 + \return 错误码 + */ +s_ecode_t su_startup_task(s_taskhand_tsp hhand, s_u8_t status) +{ + s_task_status0 = status; + s_task_starter = hhand; + su_kernel_unlock0_psv(); + return s_startup_code; +} + +/** + \brief 恢复任务 + \param[in] htask 任务句柄 + \return 错误码 + */ +s_ecode_t su_resume_task(s_tasknode_tsp htask) +{ + if(htask == OS_NULL){ + su_kernel_unlocks(); + return OS_ECODE_TASKNOTSTARTED; + } + if(htask->status & OS_STATUS_SUSPENDED){ + sv_resume_task(htask); + su_kernel_unlocks(); + return OS_ECODE_NOERROR; + } + if(htask->status < OS_STATUS_STOPPED){ + su_kernel_unlocks(); + return OS_ECODE_TASKNOTSUSPENDED; + } + if(htask->status == OS_STATUS_STOPPED){ + su_kernel_unlocks(); + return OS_ECODE_TASKSTOPPED; + } + if(htask->status == OS_STATUS_DELETED){ + su_kernel_unlocks(); + return OS_ECODE_TASKNOTSTARTED; + } + else{ + su_kernel_unlocks(); + return OS_ECODE_DONOTKNOW; + } +} + +/** + \brief 恢复指定任务并挂起自身任务 + \param[in] htask 任务句柄 + \return 错误码 + */ +s_ecode_t su_resume_suspend(s_tasknode_tsp htask) +{ + if(htask == OS_NULL){ + su_kernel_unlocks(); + return OS_ECODE_TASKNOTSTARTED; + } + if(htask->status & OS_STATUS_SUSPENDED){ + sv_resume_task(htask); + } + if(htask->status == OS_STATUS_READY){ + sv_suspend_task(s_task_current); + su_kernel_unlocks(); + return OS_ECODE_NOERROR; + } + if(htask->status < OS_STATUS_STOPPED){ + su_kernel_unlocks(); + return OS_ECODE_TASKNOTREADY; + } + if(htask->status == OS_STATUS_STOPPED){ + su_kernel_unlocks(); + return OS_ECODE_TASKSTOPPED; + } + if(htask->status == OS_STATUS_DELETED){ + su_kernel_unlocks(); + return OS_ECODE_TASKNOTSTARTED; + } + else{ + su_kernel_unlocks(); + return OS_ECODE_DONOTKNOW; + } +} + +/** + \brief 挂起任务 + \param[in] htask 任务句柄 + \return 错误码 + */ +s_ecode_t su_suspend_task(s_tasknode_tsp htask) +{ + if(htask == OS_NULL){ + su_kernel_unlocks(); + return OS_ECODE_TASKNOTSTARTED; + } + if(htask->status < OS_STATUS_SUSPENDED){ + sv_suspend_task(htask); + su_kernel_unlocks(); + return OS_ECODE_NOERROR; + } + if(htask->status & OS_STATUS_SUSPENDED){ + su_kernel_unlocks(); + return OS_ECODE_TASKSUSPENDED; + } + if(htask->status == OS_STATUS_STOPPED){ + su_kernel_unlocks(); + return OS_ECODE_TASKSTOPPED; + } + if(htask->status == OS_STATUS_DELETED){ + su_kernel_unlocks(); + return OS_ECODE_TASKNOTSTARTED; + } + else{ + su_kernel_unlocks(); + return OS_ECODE_DONOTKNOW; + } +} + +/** + \brief 删除任务 + \param[in] htask 任务句柄 + \return 错误码 + */ +s_ecode_t su_delete_task(s_tasknode_tsp htask) +{ + if(htask == OS_NULL){ + su_kernel_unlocks(); + return OS_ECODE_TASKNOTSTARTED; + } + if(htask->status < OS_STATUS_DELETED){ + sv_delete_task(htask); + su_kernel_unlocks(); + return OS_ECODE_NOERROR; + } + if(htask->status == OS_STATUS_DELETED){ + su_kernel_unlocks(); + return OS_ECODE_TASKNOTSTARTED; + } + else{ + su_kernel_unlocks(); + return OS_ECODE_DONOTKNOW; + } +} + +/** + \brief 清除阻塞(状态) + \param[in] htask 任务句柄 + \return 错误码 + */ +s_ecode_t su_clear_block(s_tasknode_tsp htask) +{ + if(htask == OS_NULL){ + su_kernel_unlocks(); + return OS_ECODE_TASKNOTSTARTED; + } + if(htask->status == OS_STATUS_FLOATING || htask->status == OS_STATUS_BLOCKED){ + sv_clear_block(htask); + su_kernel_unlocks(); + return OS_ECODE_NOERROR; + } + else{ + su_kernel_unlocks(); + return OS_ECODE_TASKNOTBLOCKED; + } +} + +/** + \brief 设置阻塞(时间) + \param[in] htask 任务句柄 + \param[in] tick 滴答周期(阻塞时间)
+ +0:清除阻塞
+ ~0:无限阻塞 + \return 错误码 + */ +s_ecode_t su_set_block(s_tasknode_tsp htask, s_delay_t tick) +{ + if(htask == OS_NULL){ + su_kernel_unlocks(); + return OS_ECODE_TASKNOTSTARTED; + } + if(htask->status == OS_STATUS_FLOATING || htask->status == OS_STATUS_BLOCKED){ + sv_set_block(htask, tick); + su_kernel_unlocks(); + return OS_ECODE_NOERROR; + } + else{ + su_kernel_unlocks(); + return OS_ECODE_TASKNOTBLOCKED; + } +} + +/** + \brief 设置任务优先级 + \param[in] htask 任务句柄 + \param[in] npri 新优先级 + \return 错误码 + */ +s_ecode_t su_set_taskpri(s_tasknode_tsp htask, s_u8_t npri) +{ + if(htask == OS_NULL){ + su_kernel_unlocks(); + return OS_ECODE_TASKNOTSTARTED; + } + if(htask->status < OS_STATUS_STOPPED){ + if(htask->pri != npri){ + sv_set_taskpri(htask, npri); + su_kernel_unlocks(); + return OS_ECODE_NOERROR; + } + else{ + su_kernel_unlocks(); + return OS_ECODE_TASKPRIUNCHANGED; + } + } + if(htask->status == OS_STATUS_STOPPED){ + su_kernel_unlocks(); + return OS_ECODE_TASKSTOPPED; + } + if(htask->status == OS_STATUS_DELETED){ + su_kernel_unlocks(); + return OS_ECODE_TASKNOTSTARTED; + } + else{ + su_kernel_unlocks(); + return OS_ECODE_DONOTKNOW; + } +} + +#if SYSCFG_SAMEPRISCHEDULE == __TIMESHARING__ +/** + \brief 禅让任务 + \param 无 + \return 无 + */ +void su_yield_tasking(void) +{ + su_kernel_locks(); + s_task_current->tc_counter = ~0; + s_sign_schedule.every[1] = false; + su_kernel_unlocks(); +} +#endif + +/** + \brief 自身任务延时 + \param[in] tick 滴答周期(延时时间)
+ +0:非法
+ ~0:无限延时 + \return 无 + */ +void su_delay(s_delay_t tick) +{ + s_task_current->timer = tick; + if(!s_sign_schedule.every[0]){ /* 阻塞延时 */ + if(~tick) sv_insert_timer_list(); + sv_task_remove_ready(s_task_current); + s_task_current->status = OS_STATUS_BLOCKED; + su_kernel_unlock0_psv(); + } + else{ /* 就绪延时 */ + s_sign_ready_delay = true; + mSysIRQ_Enable(); + while(s_sign_ready_delay); + } +} + + + +/* + * 互斥信号量 + */ +#if SYSCFG_MUTEX == __ENABLED__ +/** + \brief 获取互斥信号量 + \param[in] hmut 互斥信号量句柄 + \param[in] tick 滴答周期(超时时间)
+ +0:立即返回
+ ~0:无限等待 + \return 结果 + \retval false 失败 + \retval true 成功 + */ +bool su_take_mutex(s_mutex_tsp hmut, s_delay_t tick) +{ + if(!hmut->mutex) goto __RET_TRUE1; + if(s_task_current == hmut->otask) goto __RET_TRUE2; + if(!tick) goto __RET_FALSE; + + if(~tick) sv_insert_timer_list(); + sv_insert_block_list(&hmut->htask); + sv_task_remove_ready(s_task_current); + s_task_current->status = OS_STATUS_BLOCKED; + s_task_current->blocktype = OS_BLOCKED_MUTEX; + if(s_task_current->pri > hmut->otask->pri){ + #if SYSCFG_SAMEPRISCHEDULE + s_tasknode_tsp link = hmut->otask; + s_task_current->link = link; + do{ + sv_set_taskpri(link, s_task_current->pri); + link = link->link; + }while(link != OS_NULL); + #else + sv_set_taskpri(hmut->otask, s_taskpri_ceiling++); + #endif + } + s_task_current->timer = tick; + s_task_current->handle = hmut; + su_kernel_unlock0_psv(); + #if SYSCFG_MCUCORE == 8051 + hmut = (s_mutex_tsp)s_task_current->handle; + #endif + if(!hmut->mutex) goto __RET_TRUE1; + +__RET_FALSE: + mSysIRQ_Enable(); + return false; + +__RET_TRUE1: + if(hmut->htask != OS_NULL){ + sv_float_to_block(hmut->htask); + } + hmut->otask = s_task_current; + hmut->opri = s_task_current->pri; + +__RET_TRUE2: + hmut->mutex++; + mSysIRQ_Enable(); + return true; +} + +/** + \brief 归还互斥信号量 + \param[in] hmut 互斥信号量句柄 + \return 无 + */ +void su_back_mutex(s_mutex_tsp hmut) +{ + if(!hmut->mutex); + else if(s_task_current == hmut->otask){ + hmut->mutex--; + if(!hmut->mutex){ + if(s_task_current->pri > hmut->opri){ + sv_set_taskpri(s_task_current, hmut->opri); + #if !SYSCFG_SAMEPRISCHEDULE + s_taskpri_ceiling--; + #endif + } + if(hmut->htask != OS_NULL){ + sv_block_to_float(hmut->htask); + } + } + } + su_kernel_unlocks(); +} +#endif + + + +/* + * 二值信号量 + */ +#if SYSCFG_BINARY == __ENABLED__ +/** + \brief 等待二值信号量 + \param[in] hbin 二值信号量句柄 + \param[in] tick 滴答周期(超时时间)
+ +0:立即返回
+ ~0:无限等待 + \return 结果 + \retval false 失败 + \retval true 成功 + */ +bool su_wait_binary(s_binary_tsp hbin, s_delay_t tick) +{ + if(hbin->binary) goto __RET_TRUE; + if(!tick) goto __RET_FALSE; + + if(~tick) sv_insert_timer_list(); + sv_insert_block_list(&hbin->htask); + sv_task_remove_ready(s_task_current); + s_task_current->status = OS_STATUS_BLOCKED; + s_task_current->blocktype = OS_BLOCKED_BINARY; + s_task_current->timer = tick; + s_task_current->handle = hbin; + su_kernel_unlock0_psv(); + #if SYSCFG_MCUCORE == 8051 + hbin = (s_binary_tsp)s_task_current->handle; + #endif + if(hbin->binary) goto __RET_TRUE; + +__RET_FALSE: + mSysIRQ_Enable(); + return false; + +__RET_TRUE: + mSysIRQ_Enable(); + return true; +} + +/** + \brief 获取二值信号量 + \param[in] hbin 二值信号量句柄 + \param[in] tick 滴答周期(超时时间)
+ +0:立即返回
+ ~0:无限等待 + \return 结果 + \retval false 失败 + \retval true 成功 + */ +bool su_take_binary(s_binary_tsp hbin, s_delay_t tick) +{ + if(hbin->binary) goto __RET_TRUE; + if(!tick) goto __RET_FALSE; + + if(~tick) sv_insert_timer_list(); + sv_insert_block_list(&hbin->htask); + sv_task_remove_ready(s_task_current); + s_task_current->status = OS_STATUS_BLOCKED; + s_task_current->blocktype = OS_BLOCKED_BINARY; + s_task_current->timer = tick; + s_task_current->handle = hbin; + su_kernel_unlock0_psv(); + #if SYSCFG_MCUCORE == 8051 + hbin = (s_binary_tsp)s_task_current->handle; + #endif + if(hbin->binary) goto __RET_TRUE; + +__RET_FALSE: + mSysIRQ_Enable(); + return false; + +__RET_TRUE: + if(hbin->htask != OS_NULL){ + sv_float_to_block(hbin->htask); + } + hbin->binary = false; + mSysIRQ_Enable(); + return true; +} +#endif + + + +/* + * 计数信号量 + */ +#if SYSCFG_SEMAPHORE == __ENABLED__ +/** + \brief 获取计数信号量 + \param[in] hsem 计数信号量句柄 + \param[in] tick 滴答周期(超时时间)
+ +0:立即返回
+ ~0:无限等待 + \return 结果 + \retval false 失败 + \retval true 成功 + */ +bool su_take_semaphore(s_semaph_tsp hsem, s_delay_t tick) +{ + s_semsize_t counter; + counter = hsem->counter; + if(counter) goto __RET_TRUE; + if(!tick) goto __RET_FALSE; + + if(~tick) sv_insert_timer_list(); + sv_insert_block_list(&hsem->htask); + sv_task_remove_ready(s_task_current); + s_task_current->status = OS_STATUS_BLOCKED; + s_task_current->blocktype = OS_BLOCKED_SEMAPHORE; + s_task_current->timer = tick; + s_task_current->handle = hsem; + su_kernel_unlock0_psv(); + #if SYSCFG_MCUCORE == 8051 + hsem = (s_semaph_tsp)s_task_current->handle; + #endif + counter = hsem->counter; + if(counter) goto __RET_TRUE; + +__RET_FALSE: + mSysIRQ_Enable(); + return false; + +__RET_TRUE: + counter--; + if(!counter && hsem->htask != OS_NULL){ + sv_float_to_block(hsem->htask); + } + hsem->counter = counter; + mSysIRQ_Enable(); + return true; +} +#endif + + + +/* + * 飞信 + */ +#if SYSCFG_FETION == __ENABLED__ +/** + \brief 退出非嵌套服务层临界区并返回飞信 + \param[in] htbox 信箱句柄 + \return 飞信 + */ +__STATIC_FORCEINLINE m_fetion_t _unlock0_rfet_(s_tionbox_tsp htbox) +{ + m_fetion_t tion = htbox->tion; + htbox->tion = false; + mSysIRQ_Enable(); + return tion; +} + +/** + \brief 接收飞信 + \param[in] htbox 信箱句柄 + \param[in] tick 滴答周期(超时时间)
+ +0:立即返回
+ ~0:无限等待 + \return 飞信 + \retval false 失败 + */ +m_fetion_t su_recv_fetion(s_tionbox_tsp htbox, s_delay_t tick) +{ + if(htbox->tion) goto __RET_TION; + if(!tick) goto __RET_FALSE; + + if(~tick) sv_insert_timer_list(); + sv_insert_block_list(&htbox->htask); + sv_task_remove_ready(s_task_current); + s_task_current->status = OS_STATUS_BLOCKED; + s_task_current->blocktype = OS_BLOCKED_FETION; + s_task_current->timer = tick; + s_task_current->handle = htbox; + su_kernel_unlock0_psv(); + #if SYSCFG_MCUCORE == 8051 + htbox = (s_tionbox_tsp)s_task_current->handle; + #endif + +__RET_TION: + return _unlock0_rfet_(htbox); + +__RET_FALSE: + mSysIRQ_Enable(); + return false; +} +#endif + + + +/** 退出非嵌套服务层临界区并返回(void *) */ +#if SYSCFG_MAILBOX == __ENABLED__ || SYSCFG_MSGQUEUE == __ENABLED__ +__STATIC_FORCEINLINE void *_unlock0_rvp_(void *p) +{ + mSysIRQ_Enable(); + return p; +} +#endif + + + +/* + * 邮箱 + */ +#if SYSCFG_MAILBOX == __ENABLED__ +/** + \brief 接收邮件 + \param[in] hmbox 邮箱句柄 + \param[in] tick 滴答周期(超时时间)
+ +0:立即返回
+ ~0:无限等待 + \return 邮件指针 + \retval NULL 失败 + */ +void *su_recv_mail(s_mailbox_tsp hmbox, s_delay_t tick) +{ + if(hmbox->flag) goto __RET_MAIL; + if(!tick) goto __RET_NULL; + + if(~tick) sv_insert_timer_list(); + sv_insert_block_list(&hmbox->htask); + sv_task_remove_ready(s_task_current); + s_task_current->status = OS_STATUS_BLOCKED; + s_task_current->blocktype = OS_BLOCKED_MAIL; + s_task_current->timer = tick; + s_task_current->handle = hmbox; + su_kernel_unlock0_psv(); + #if SYSCFG_MCUCORE == 8051 + hmbox = (s_mailbox_tsp)s_task_current->handle; + #endif + if(hmbox->flag) goto __RET_MAIL; + +__RET_NULL: + mSysIRQ_Enable(); + return OS_NULL; + +__RET_MAIL: + hmbox->flag = false; + return _unlock0_rvp_(hmbox->mail); +} +#endif + + + +/* + * 消息队列 + */ +#if SYSCFG_MSGQUEUE == __ENABLED__ +/** + \brief 接收消息 + \param[in] hque 队列句柄 + \param[in] tick 滴答周期(超时时间)
+ +0:立即返回
+ ~0:无限等待 + \return 消息指针 + \retval NULL 失败 + */ +void *su_recv_msg(s_queue_tsp hque, s_delay_t tick) +{ + void *msg; + hque->mutex = false; + + if(hque->counter) goto __RECV_MSG; + if(!tick) goto __RET_NULL; + + hque->mutex = true; + if(~tick) sv_insert_timer_list(); + sv_insert_block_list(&hque->htask); + sv_task_remove_ready(s_task_current); + s_task_current->status = OS_STATUS_BLOCKED; + s_task_current->blocktype = OS_BLOCKED_MSG; + s_task_current->timer = tick; + s_task_current->handle = hque; + su_kernel_unlock0_psv(); + #if SYSCFG_MCUCORE == 8051 + hque = (s_queue_tsp)s_task_current->handle; + #endif + hque->mutex = false; + if(!hque->counter) goto __RET_NULL; + +__RECV_MSG: + if(hque->type == __DYNAMIC__){ + msg = sv_recv_msg_dynamic((sd_queue_tsp)hque); + } + else{ + msg = sv_recv_msg_static((ss_queue_tsp)hque); + } + hque->mutex = true; + return _unlock0_rvp_(msg); + +__RET_NULL: + hque->mutex = true; + mSysIRQ_Enable(); + return OS_NULL; +} + +/** + \brief 发送消息 + \param[in] hque 队列句柄 + \param[in] msg 消息指针 + \return 错误码 + */ +s_ecode_t su_send_msg(s_queue_tsp hque, void *msg) +{ + s_ecode_t _ecode = sv_send_msg(hque, msg); + su_kernel_unlocks(); + return _ecode; +} +#endif + + + +/* + * 事件标志组 + */ +#if SYSCFG_FLAGGROUP == __ENABLED__ +/** + \brief 查询标志组 + \param[in] hgrp 标志组句柄 + \param[in] size sizeof(group) + \return 结果 + \retval false 失败 + \retval true 成功 + */ +bool su_query_group(void _STATIC_MEM_ *hgrp, s_u8_t size) +{ + switch(size){ + case 1: if(*(s_u8_t *)hgrp) goto __RET_TRUE; break; + case 2: if(*(s_u16_t *)hgrp) goto __RET_TRUE; break; + case 4: if(*(s_u32_t *)hgrp) goto __RET_TRUE; break; + } + su_kernel_unlocks(); + return false; + +__RET_TRUE: + su_kernel_unlocks(); + return true; +} + +/** + \brief 等待标志组_1 + \param[in] hgrp 标志组句柄 + \param[in] tick 滴答周期(超时时间)
+ +0:立即返回
+ ~0:无限等待 + \return 结果 + \retval false 失败 + \retval true 成功 + */ +bool su_wait_group_1(s_u8_t _STATIC_MEM_ *hgrp, s_delay_t tick) +{ + if(*hgrp) goto __RET_TRUE; + if(!tick) goto __RET_FALSE; + + if(~tick) sv_insert_timer_list(); + sv_task_remove_ready(s_task_current); + s_task_current->status = OS_STATUS_BLOCKED; + s_task_current->blocktype = 1; + s_task_current->timer = tick; + s_task_current->handle = hgrp; + su_kernel_unlock0_psv(); + #if SYSCFG_MCUCORE == 8051 + hgrp = s_task_current->handle; + #endif + if(*hgrp) goto __RET_TRUE; + +__RET_FALSE: + mSysIRQ_Enable(); + return false; + +__RET_TRUE: + mSysIRQ_Enable(); + return true; +} + +/** + \brief 等待标志组_2 + \param[in] hgrp 标志组句柄 + \param[in] tick 滴答周期(超时时间)
+ +0:立即返回
+ ~0:无限等待 + \return 结果 + \retval false 失败 + \retval true 成功 + */ +bool su_wait_group_2(s_u16_t _STATIC_MEM_ *hgrp, s_delay_t tick) +{ + if(*hgrp) goto __RET_TRUE; + if(!tick) goto __RET_FALSE; + + if(~tick) sv_insert_timer_list(); + sv_task_remove_ready(s_task_current); + s_task_current->status = OS_STATUS_BLOCKED; + s_task_current->blocktype = 2; + s_task_current->timer = tick; + s_task_current->handle = hgrp; + su_kernel_unlock0_psv(); + #if SYSCFG_MCUCORE == 8051 + hgrp = s_task_current->handle; + #endif + if(*hgrp) goto __RET_TRUE; + +__RET_FALSE: + mSysIRQ_Enable(); + return false; + +__RET_TRUE: + mSysIRQ_Enable(); + return true; +} + +/** + \brief 等待标志组_4 + \param[in] hgrp 标志组句柄 + \param[in] tick 滴答周期(超时时间)
+ +0:立即返回
+ ~0:无限等待 + \return 结果 + \retval false 失败 + \retval true 成功 + */ +bool su_wait_group_4(s_u32_t _STATIC_MEM_ *hgrp, s_delay_t tick) +{ + if(*hgrp) goto __RET_TRUE; + if(!tick) goto __RET_FALSE; + + if(~tick) sv_insert_timer_list(); + sv_task_remove_ready(s_task_current); + s_task_current->status = OS_STATUS_BLOCKED; + s_task_current->blocktype = 4; + s_task_current->timer = tick; + s_task_current->handle = hgrp; + su_kernel_unlock0_psv(); + #if SYSCFG_MCUCORE == 8051 + hgrp = s_task_current->handle; + #endif + if(*hgrp) goto __RET_TRUE; + +__RET_FALSE: + mSysIRQ_Enable(); + return false; + +__RET_TRUE: + mSysIRQ_Enable(); + return true; +} +#endif + + + +/* + * 动态内存 + */ +#if SYSCFG_DYNMEMMGE == __ENABLED__ +/** + \brief uxalloc + \param[in] p + \return 指针 + \retval NULL 失败 + */ +void _MALLOC_MEM_ *su_xalloc(void _MALLOC_MEM_ *p) +{ + su_kernel_unlocks(); + return p; +} + +/** + \brief 初始化线程内存池 + \param[in] hmem 线程内存句柄 + \param[in] size 内存池大小 + \return 结果 + \retval false 失败 + \retval true 成功 + */ +bool su_init_mempool(s_thrmem_tsp hmem, size_t size) +{ + hmem->head = hmem->move = (void _MALLOC_MEM_ *)s_malloc(size); + if(hmem->head == OS_NULL){ + su_kernel_unlocks(); + return false; + } + else{ + hmem->size = size; + su_kernel_unlocks(); + return true; + } +} + +/** + \brief 线程内存分配 + \param[in] hmem 线程内存句柄 + \param[in] size 内存块大小 + \return 指针 + \retval NULL 失败 + */ +void _MALLOC_MEM_ *su_talloc(s_thrmem_tsp hmem, size_t size) +{ + if(hmem->head == OS_NULL || (size_t)hmem->move - (size_t)hmem->head + size > hmem->size){ + return OS_NULL; + } + else{ + void _MALLOC_MEM_ *r = hmem->move; + hmem->move = (s_u8_t _MALLOC_MEM_ *)hmem->move + size; + return r; + } +} +#endif + +/** @} */ +/** @} */