mirror of
https://gitee.com/cosyos/cosyos.git
synced 2026-02-06 03:41:41 +08:00
780 lines
21 KiB
C
780 lines
21 KiB
C
/**************************************************************************//**
|
||
* @item CosyOS-II Kernel
|
||
* @file os_handler.c
|
||
* @brief SysTick_Handler and PendSV_Replacer
|
||
* @author 迟凯峰
|
||
* @version V1.2.0
|
||
* @date 2023.11.25
|
||
******************************************************************************/
|
||
|
||
#include "os_link.h"
|
||
|
||
#if SYSCFG_DEBUGGING == __ENABLED__
|
||
static s_u32_t usedtime[2];
|
||
#endif
|
||
|
||
void SysTick_Handler(void) MCUCFG_SYSTICK_ATTRIBUTE
|
||
{
|
||
s_tid_t _SYS_REG_ i;
|
||
/* 系统滴答时间统计开始 */
|
||
#if SYSCFG_SYSTICKTIME_COUNT == __ENABLED__
|
||
static m_tick_t tick_temp;
|
||
if(s_taskmgr_binary){
|
||
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(counter < 1000000UL / SYSCFG_SYSTICKCYCLE - 1) counter++;
|
||
else{
|
||
counter = 0;
|
||
s_sign_every.second = true;
|
||
if(s_rtc[0][5] < 59) s_rtc[0][5]++;
|
||
else{
|
||
s_rtc[0][5] = 0;
|
||
s_sign_every.minute = true;
|
||
if(s_rtc[0][4] < 59) s_rtc[0][4]++;
|
||
else{
|
||
s_rtc[0][4] = 0;
|
||
s_sign_every.hour = true;
|
||
if(s_rtc[0][3] < 23) s_rtc[0][3]++;
|
||
else{
|
||
s_rtc[0][3] = 0;
|
||
s_sign_every.day = true;
|
||
if(s_rtc[0][6] < 7) s_rtc[0][6]++;
|
||
else s_rtc[0][6] = 1;
|
||
if(s_rtc[0][2] < (s_rtc[0][1] == 2 ? s_month2day : s_month0day[s_rtc[0][1]])) s_rtc[0][2]++;
|
||
else{
|
||
s_rtc[0][2] = 1;
|
||
s_sign_every.month = true;
|
||
if(s_rtc[0][1] < 12) s_rtc[0][1]++;
|
||
else{
|
||
s_rtc[0][1] = 1;
|
||
s_sign_every.year = true;
|
||
if(s_rtc[0][0] < 99) s_rtc[0][0]++;
|
||
else s_rtc[0][0] = 0;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
tUpdateCopy_GVar(s_memcpy(s_rtc[1], s_rtc[0], sizeof(s_rtc[0])));
|
||
}
|
||
#endif
|
||
/* 滴答钩子 */
|
||
#if SYSCFG_TICKHOOK == __ENABLED__
|
||
tick_hook();
|
||
#endif
|
||
/* 定时中断 */
|
||
#if OS_TIMINTTOTAL
|
||
i = OS_TIMINTTOTAL;
|
||
while(i--){
|
||
if(s_timint_loader[i] && s_timint_loader[i] < ~0){
|
||
s_timint_loader[i]--;
|
||
if(!s_timint_loader[i]){
|
||
if(s_timint_hookortask[i]){
|
||
sResumeTask_TimInt(i);
|
||
}
|
||
else{
|
||
(*s_timint_handle[i]->hook)();
|
||
}
|
||
if(s_timint_autoreload[i]){
|
||
s_timint_loader[i] = s_timint_reload[i];
|
||
}
|
||
}
|
||
}
|
||
}
|
||
#endif
|
||
/* 定时查询 */
|
||
#if OS_TIMQRYTOTAL
|
||
i = OS_TIMQRYTOTAL;
|
||
while(i--){
|
||
if(s_timqry_loader[i] && s_timqry_loader[i] < ~0){
|
||
s_timqry_loader[i]--;
|
||
}
|
||
if(!s_timqry_loader[i]){
|
||
if((*s_timqry_handle[i]->event)()){
|
||
if(s_timqry_hookortask[i]){
|
||
sResumeTask_TimQry(i);
|
||
}
|
||
else{
|
||
(*s_timqry_handle[i]->hook)();
|
||
}
|
||
if(s_timqry_autoreload[i]){
|
||
s_timqry_loader[i] = s_timqry_reload[i];
|
||
}
|
||
else{
|
||
s_timqry_loader[i] = ~0;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
#endif
|
||
/* 延时定时器 */
|
||
i = OS_TASKTOTAL;
|
||
do{
|
||
if(s_delay_loader[i] && s_delay_loader[i] < ~0){
|
||
s_delay_loader[i]--;
|
||
}
|
||
}while(--i);
|
||
/* 时间片滴答计数 */
|
||
s_tick_counter++;
|
||
/* 安全运行时 */
|
||
#if SYSCFG_SAFERUNTIME == __ENABLED__
|
||
if(s_task_current != NULL && s_task_current->pri && s_task_current->saferuntime){
|
||
s_task_current->counter++;
|
||
if(s_task_current->counter > 1UL * s_task_current->saferuntime * OS_TIMESHARING){
|
||
s_task_current->status = OS_STATUS_OVERTIME;
|
||
s_sign_timeout[s_task_current->tid] = true;
|
||
#if SYSCFG_DEBUGGING == __ENABLED__
|
||
s_alarm.timedout_saferuntime = true;
|
||
#endif
|
||
}
|
||
}
|
||
#endif
|
||
/* 任务管理器相关 */
|
||
#if SYSCFG_DEBUGGING == __ENABLED__
|
||
if(s_taskmgr_binary){
|
||
usedtime[0]++; /* CPU使用时间计数 */
|
||
#if SYSCFG_SYSTICKTIME_COUNT == __ENABLED__
|
||
mSysTick_Counting; /* 系统滴答时间统计 */
|
||
#endif
|
||
}
|
||
#endif
|
||
/* 触发任务调度(定时调度)*/
|
||
if(!s_sign_return){
|
||
s_sign_scheduling = true;
|
||
mPendSV_Set;
|
||
}
|
||
}
|
||
|
||
/* 任务节点 */
|
||
#define node_head task_node[0] /* 头节点 */
|
||
#define node_midd task_node[1] /* 中间节点 */
|
||
#define node_tail task_node[2] /* 尾节点 */
|
||
#define node_curr node_buff[0] /* 当前节点 */
|
||
#define node_news node_buff[1] /* 新节点 */
|
||
#define node_temp node_buff[2] /* 缓存节点 */
|
||
#define node_last node_curr->last /* 上一节点 */
|
||
#define node_next node_curr->next /* 下一节点 */
|
||
|
||
/* 初始化任务队列(CosyOS的任务队列为双向循环链表)*/
|
||
#define init_taskqueue \
|
||
node_head = node_midd = node_tail = \
|
||
node_news->last = node_news->next = node_news
|
||
#define init_node_head node_curr = node_head /* 初始化 头节点 */
|
||
#define init_node_midd node_curr = node_midd /* 初始化中间节点 */
|
||
#define move_forward node_curr = node_last /* 当前节点前移 */
|
||
#define move_backward node_curr = node_next /* 当前节点后移 */
|
||
|
||
/* 移除节点(从任务队列中移除当前节点)*/
|
||
#define node_remove \
|
||
do{ \
|
||
node_last->next = node_next; \
|
||
node_next->last = node_last; \
|
||
if(node_curr == node_head){ \
|
||
node_head = node_next; \
|
||
} \
|
||
task_queue_len--; \
|
||
}while(false)
|
||
|
||
/* 插入方向 */
|
||
#define forward 0x01 /* 向前 */
|
||
#define voidward 0x00 /* 空 */
|
||
#define backward 0xFF /* 向后 */
|
||
|
||
/* 前插(新节点插入当前节点之前)*/
|
||
#define insert_forward \
|
||
do{ \
|
||
node_news->next = node_curr; \
|
||
node_news->last = node_last; \
|
||
node_last->next = node_news; \
|
||
node_last = node_news; \
|
||
if(node_curr == node_head){ \
|
||
node_head = node_news; \
|
||
} \
|
||
switch(insert_direction){ \
|
||
case forward: \
|
||
insert_direction = voidward; \
|
||
node_midd = node_midd->last; \
|
||
break; \
|
||
case voidward: \
|
||
insert_direction = forward; \
|
||
break; \
|
||
case backward: \
|
||
insert_direction = voidward; \
|
||
break; \
|
||
} \
|
||
}while(false)
|
||
|
||
/* 后插(新节点插入当前节点之后)*/
|
||
#define insert_backward \
|
||
do{ \
|
||
node_news->last = node_curr; \
|
||
node_news->next = node_next; \
|
||
node_next->last = node_news; \
|
||
node_next = node_news; \
|
||
if(node_curr == node_tail){ \
|
||
node_tail = node_news; \
|
||
} \
|
||
switch(insert_direction){ \
|
||
case forward: \
|
||
insert_direction = voidward; \
|
||
break; \
|
||
case voidward: \
|
||
insert_direction = backward; \
|
||
break; \
|
||
case backward: \
|
||
insert_direction = voidward; \
|
||
node_midd = node_midd->next; \
|
||
break; \
|
||
} \
|
||
}while(false)
|
||
|
||
/* 抢占式调度 or 时间片轮转调度 */
|
||
#define preemptive_or_rotate \
|
||
do{ \
|
||
if(!rotate_f){ \
|
||
node_news = node_curr; \
|
||
if(s_task_current == NULL || node_news->pri != s_task_current->pri){ \
|
||
goto __TASK_SCHEDULING; \
|
||
} \
|
||
rotate_f = true; \
|
||
} \
|
||
}while(false)
|
||
|
||
/* 入栈监控 */
|
||
#if MCUCFG_TASKSTACK_REALLOC == __DISABLED__
|
||
#if SYSCFG_DEBUGGING == __ENABLED__
|
||
#define sPUSH_Monitor \
|
||
do{ \
|
||
if(s_task_current->stacksize < stacklen){ \
|
||
s_task_current->status = OS_STATUS_STOPPED_TSOF; \
|
||
s_fault.overflow_taskstack = true; \
|
||
} \
|
||
else{ \
|
||
push_f = true; \
|
||
} \
|
||
}while(false)
|
||
#else
|
||
#define sPUSH_Monitor push_f = true
|
||
#endif
|
||
#else
|
||
#if SYSCFG_DEBUGGING == __ENABLED__
|
||
#define sPUSH_Monitor_01 s_task_current->realloc = true; \
|
||
s_alarm.realloc_taskstack = true
|
||
#define sPUSH_Monitor_02 s_fault.reallocfailed_taskstack = true
|
||
#else
|
||
#define sPUSH_Monitor_01 do{}while(false)
|
||
#define sPUSH_Monitor_02 do{}while(false)
|
||
#endif
|
||
#define sPUSH_Monitor \
|
||
do{ \
|
||
if(s_task_current->stacksize < stacklen){ \
|
||
s_task_current->stacksize = stacklen + MCUCFG_TASKSTACKREALLOC_INC; \
|
||
s_free(s_task_current->bsp); \
|
||
s_task_current->bsp = NULL; \
|
||
s_task_current->bsp = (s_u8_t *)s_malloc(s_task_current->stacksize); \
|
||
if(s_task_current->bsp != NULL){ \
|
||
push_f = true; \
|
||
sPUSH_Monitor_01; \
|
||
} \
|
||
else{ \
|
||
s_task_current->status = OS_STATUS_STOPPED_TSRF; \
|
||
sPUSH_Monitor_02; \
|
||
} \
|
||
} \
|
||
else{ \
|
||
push_f = true; \
|
||
} \
|
||
}while(false)
|
||
#endif
|
||
|
||
#if SYSCFG_MCUCORE == 80251
|
||
#pragma functions(static)
|
||
#endif
|
||
void PendSV_Replacer(void) MCUCFG_PENDSV_ATTRIBUTE
|
||
{
|
||
/* 中断挂起服务 */
|
||
{
|
||
mPendSV_Entry;
|
||
}
|
||
/* 中断服务钩子 */
|
||
{
|
||
#if SYSCFG_PENDSVHOOK == __ENABLED__
|
||
pendsv_hook();
|
||
#endif
|
||
}
|
||
/* 更新全局变量副本 */
|
||
{
|
||
#if SYSCFG_SOFTRTC == __ENABLED__ || SYSCFG_GVARHOOK == __ENABLED__
|
||
s_sign_updatecopy = true;
|
||
#if SYSCFG_SOFTRTC == __ENABLED__
|
||
if(s_rtc_binary){
|
||
s_rtc_binary = false;
|
||
s_memcpy(s_rtc[1], s_rtc[0], sizeof(s_rtc[0]));
|
||
}
|
||
#endif
|
||
#if SYSCFG_GVARHOOK == __ENABLED__
|
||
gvar_hook();
|
||
#endif
|
||
s_sign_updatecopy = false;
|
||
#endif
|
||
}
|
||
/* 任务调度 */
|
||
if(s_sign_scheduling)
|
||
{
|
||
static s_u8_t _SYS_MEM_ task_queue_len = 0;
|
||
static s_u8_t _SYS_MEM_ insert_direction = 0;
|
||
static s_tasknode_tsp _SYS_MEM_ task_node[3] = {NULL, NULL, NULL};
|
||
s_tasknode_tsp _SYS_REG_ node_buff[3];
|
||
#if SYSCFG_DEBUGGING == __ENABLED__
|
||
m_tick_t _SYS_REG_ counter;
|
||
#endif
|
||
m_bit_t push_f = false;
|
||
m_bit_t rotate_f = false;
|
||
/* 调度初始化 */
|
||
mScheduler_INIT;
|
||
/* 启动任务 */
|
||
if(s_task_starter != NULL){
|
||
if(task_queue_len < OS_TASKQUEUELEN_MAX){
|
||
/* 静态创建 */
|
||
#if SYSCFG_TASKCREATEMODE == __STATIC__
|
||
node_news = 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;
|
||
if(node_news->oldpri <= (s_u8_t)(SYSCFG_TASKPRIORITY - 1)){
|
||
node_news->pri = node_news->oldpri;
|
||
}
|
||
else{
|
||
node_news->pri = SYSCFG_TASKPRIORITY - 2;
|
||
#if SYSCFG_DEBUGGING == __ENABLED__
|
||
s_alarm.outrange_taskpriority = true;
|
||
#endif
|
||
}
|
||
node_news->blocktype = 0;
|
||
node_news->ptr = NULL;
|
||
#if SYSCFG_DEBUGGING == __ENABLED__
|
||
node_news->usedtime[0] = 0;
|
||
node_news->usedtime[1] = 0;
|
||
node_news->stacklen_max = MCUCFG_BASICSTACKSIZE;
|
||
#endif
|
||
node_news->counter = 0;
|
||
s_delay_loader[node_news->tid] = 0;
|
||
}
|
||
/* 平衡创建 */
|
||
#elif SYSCFG_TASKCREATEMODE == __BALANCE__
|
||
node_news = s_task_starter;
|
||
if(node_news->stacksize < MCUCFG_BASICSTACKSIZE){
|
||
node_news->stacksize = MCUCFG_BASICSTACKSIZE;
|
||
#if SYSCFG_DEBUGGING == __ENABLED__
|
||
node_news->realloc = true;
|
||
#endif
|
||
}
|
||
#if SYSCFG_DEBUGGING == __ENABLED__
|
||
else{
|
||
node_news->realloc = false;
|
||
}
|
||
#endif
|
||
node_news->bsp = NULL;
|
||
node_news->bsp = (s_u8_t *)s_malloc(node_news->stacksize);
|
||
if(node_news->bsp != NULL){
|
||
mTaskStack_INIT;
|
||
if(node_news->oldpri <= (s_u8_t)(SYSCFG_TASKPRIORITY - 1)){
|
||
node_news->pri = node_news->oldpri;
|
||
}
|
||
else{
|
||
node_news->pri = SYSCFG_TASKPRIORITY - 2;
|
||
#if SYSCFG_DEBUGGING == __ENABLED__
|
||
s_alarm.outrange_taskpriority = true;
|
||
#endif
|
||
}
|
||
node_news->blocktype = 0;
|
||
node_news->ptr = NULL;
|
||
#if SYSCFG_DEBUGGING == __ENABLED__
|
||
node_news->usedtime[0] = 0;
|
||
node_news->usedtime[1] = 0;
|
||
node_news->stacklen_max = MCUCFG_BASICSTACKSIZE;
|
||
#endif
|
||
node_news->counter = 0;
|
||
s_delay_loader[node_news->tid] = 0;
|
||
}
|
||
else{
|
||
#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;
|
||
}
|
||
/* 动态创建 */
|
||
#elif SYSCFG_TASKCREATEMODE == __DYNAMIC__
|
||
node_news = NULL;
|
||
node_news = (s_tasknode_tsp)s_malloc(sizeof(s_tasknode_ts));
|
||
if(node_news != NULL){
|
||
node_news->stacksize = s_task_starter->stacksize;
|
||
if(node_news->stacksize < MCUCFG_BASICSTACKSIZE){
|
||
node_news->stacksize = MCUCFG_BASICSTACKSIZE;
|
||
#if SYSCFG_DEBUGGING == __ENABLED__
|
||
node_news->realloc = true;
|
||
#endif
|
||
}
|
||
#if SYSCFG_DEBUGGING == __ENABLED__
|
||
else{
|
||
node_news->realloc = false;
|
||
}
|
||
#endif
|
||
node_news->bsp = NULL;
|
||
node_news->bsp = (s_u8_t *)s_malloc(node_news->stacksize);
|
||
if(node_news->bsp != NULL){
|
||
mTaskStack_INIT;
|
||
node_news->tid = s_task_starter->tid;
|
||
if(s_task_starter->oldpri <= (s_u8_t)(SYSCFG_TASKPRIORITY - 1)){
|
||
node_news->pri = s_task_starter->oldpri;
|
||
}
|
||
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->ptr = NULL;
|
||
#if SYSCFG_DEBUGGING == __ENABLED__
|
||
node_news->name = s_task_starter->name;
|
||
node_news->usedtime[0] = 0;
|
||
node_news->usedtime[1] = 0;
|
||
node_news->stacklen_max = MCUCFG_BASICSTACKSIZE;
|
||
#endif
|
||
node_news->saferuntime = s_task_starter->saferuntime;
|
||
node_news->counter = 0;
|
||
node_news->hand = s_task_starter;
|
||
s_task_starter->node = node_news;
|
||
s_delay_loader[node_news->tid] = 0;
|
||
}
|
||
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;
|
||
}
|
||
#endif
|
||
/* 新任务加入任务队列 */
|
||
if(!task_queue_len){
|
||
init_taskqueue;
|
||
}
|
||
else{
|
||
init_node_midd;
|
||
if(node_curr != node_tail && node_news->pri <= node_curr->pri){
|
||
do{
|
||
move_backward;
|
||
}while(node_curr != node_tail && node_news->pri <= node_curr->pri);
|
||
}
|
||
else if(node_curr != node_head && node_news->pri > node_curr->pri){
|
||
do{
|
||
move_forward;
|
||
}while(node_curr != node_head && node_news->pri > node_curr->pri);
|
||
}
|
||
if(node_news->pri > node_curr->pri){
|
||
insert_forward;
|
||
}
|
||
else if(node_curr == node_tail && node_curr->pri == 0){
|
||
insert_forward;
|
||
}
|
||
else{
|
||
insert_backward;
|
||
}
|
||
}
|
||
task_queue_len++;
|
||
s_startup_code = OS_ECODE_NOERROR;
|
||
}
|
||
else{
|
||
#if SYSCFG_DEBUGGING == __ENABLED__
|
||
s_fault.failed_startuptask = true;
|
||
s_alarm.overflow_taskqueue = true;
|
||
#endif
|
||
s_startup_code = OS_ECODE_OVERFLOW_TASKQUEUE;
|
||
}
|
||
__STARTUP_END:
|
||
s_task_starter = NULL;
|
||
if(s_sign_return) return;
|
||
s_task_current->blocktype = s_startup_code;
|
||
}
|
||
/**
|
||
* \brief 任务优先级调整
|
||
* \detail 如果任务优先级发生改变,执行服务时已从任务队列中移除并加入到临时链表。
|
||
* 在此,从临时链表中依次取出各任务,并根据任务优先级重新加入到任务队列。
|
||
*/
|
||
if(s_taskpri_tail != NULL){
|
||
node_temp = s_taskpri_tail;
|
||
do{
|
||
node_news = node_temp;
|
||
node_temp = node_temp->last;
|
||
init_node_midd;
|
||
if(node_curr != node_tail && node_news->pri <= node_curr->pri){
|
||
do{
|
||
move_backward;
|
||
}while(node_curr != node_tail && node_news->pri <= node_curr->pri);
|
||
}
|
||
else if(node_curr != node_head && node_news->pri > node_curr->pri){
|
||
do{
|
||
move_forward;
|
||
}while(node_curr != node_head && node_news->pri > node_curr->pri);
|
||
}
|
||
if(node_news->pri > node_curr->pri){
|
||
insert_forward;
|
||
}
|
||
else if(node_curr == node_tail && node_curr->pri == 0){
|
||
insert_forward;
|
||
}
|
||
else{
|
||
insert_backward;
|
||
}
|
||
}while(node_temp != NULL);
|
||
s_taskpri_tail = NULL;
|
||
}
|
||
/**
|
||
* \brief 查找就绪
|
||
* \detail 更新任务状态并同步查找可以运行的、优先级最高的任务。
|
||
*/
|
||
init_node_head;
|
||
while(true){
|
||
switch(node_curr->status){
|
||
case OS_STATUS_BLOCKED:
|
||
if(!s_delay_loader[node_curr->tid]){
|
||
node_curr->status = OS_STATUS_READY;
|
||
preemptive_or_rotate;
|
||
}
|
||
else if(node_curr->blocktype != OS_BLOCKED_DELAY){
|
||
switch(node_curr->blocktype & 0x0F){
|
||
case 1:
|
||
if(*(s_u8_t *)node_curr->ptr){
|
||
node_curr->status = OS_STATUS_FLOATING;
|
||
preemptive_or_rotate;
|
||
}
|
||
break;
|
||
case 2:
|
||
if(*(s_u16_t *)node_curr->ptr){
|
||
node_curr->status = OS_STATUS_FLOATING;
|
||
preemptive_or_rotate;
|
||
}
|
||
break;
|
||
case 4:
|
||
if(*(s_u32_t *)node_curr->ptr){
|
||
node_curr->status = OS_STATUS_FLOATING;
|
||
preemptive_or_rotate;
|
||
}
|
||
break;
|
||
case 0x0F:
|
||
if(!*(s_u8_t *)node_curr->ptr){
|
||
node_curr->status = OS_STATUS_FLOATING;
|
||
preemptive_or_rotate;
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
break;
|
||
case OS_STATUS_FLOATING:
|
||
if(!s_delay_loader[node_curr->tid]){
|
||
node_curr->status = OS_STATUS_READY;
|
||
preemptive_or_rotate;
|
||
}
|
||
else{
|
||
switch(node_curr->blocktype & 0x0F){
|
||
case 1:
|
||
if(*(s_u8_t *)node_curr->ptr){
|
||
preemptive_or_rotate;
|
||
}
|
||
else{
|
||
node_curr->status = OS_STATUS_BLOCKED;
|
||
}
|
||
break;
|
||
case 2:
|
||
if(*(s_u16_t *)node_curr->ptr){
|
||
preemptive_or_rotate;
|
||
}
|
||
else{
|
||
node_curr->status = OS_STATUS_BLOCKED;
|
||
}
|
||
break;
|
||
case 4:
|
||
if(*(s_u32_t *)node_curr->ptr){
|
||
preemptive_or_rotate;
|
||
}
|
||
else{
|
||
node_curr->status = OS_STATUS_BLOCKED;
|
||
}
|
||
break;
|
||
case 0x0F:
|
||
if(!*(s_u8_t *)node_curr->ptr){
|
||
preemptive_or_rotate;
|
||
}
|
||
else{
|
||
node_curr->status = OS_STATUS_BLOCKED;
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
break;
|
||
case OS_STATUS_READY:
|
||
preemptive_or_rotate;
|
||
break;
|
||
case OS_STATUS_DELETED:
|
||
if(node_curr != s_task_current){
|
||
node_remove;
|
||
#if SYSCFG_TASKCREATEMODE != __STATIC__
|
||
s_free(node_curr->bsp);
|
||
#endif
|
||
#if SYSCFG_TASKCREATEMODE == __DYNAMIC__
|
||
((s_taskhand_tsp)node_curr->hand)->node = NULL;
|
||
s_free(node_curr);
|
||
#endif
|
||
}
|
||
break;
|
||
#if SYSCFG_SAFERUNTIME == __ENABLED__
|
||
case OS_STATUS_OVERTIME:
|
||
if(!s_sign_timeout[node_curr->tid]) {
|
||
node_curr->status = OS_STATUS_READY;
|
||
preemptive_or_rotate;
|
||
}
|
||
break;
|
||
#endif
|
||
}
|
||
move_backward;
|
||
/* 当前任务优先级组查询完毕 -> 当前任务预处理 */
|
||
if(rotate_f && node_curr->pri != s_task_current->pri){
|
||
goto __TASKING_PREPROCESS;
|
||
}
|
||
}
|
||
|
||
/* 准备任务调度(首次任务调度 -> 新任务预处理)*/
|
||
__TASK_SCHEDULING:
|
||
if(s_task_current == NULL){
|
||
goto __NEWTASK_PREPROCESS;
|
||
}
|
||
|
||
/* 当前任务预处理 */
|
||
__TASKING_PREPROCESS:{
|
||
mTaskStack_LEN;
|
||
/* 每调度监控(假定入栈)*/
|
||
#if SYSCFG_DEBUGGING == __ENABLED__
|
||
if(s_task_current->stacklen_max < stacklen){
|
||
s_task_current->stacklen_max = stacklen;
|
||
if(s_task_current->stacksize < stacklen){
|
||
s_alarm.overflow_taskstack_future = true;
|
||
}
|
||
}
|
||
#endif
|
||
}
|
||
|
||
/* 开始任务调度 */
|
||
if(true){
|
||
/* 1、新任务与当前任务优先级不同 -> 当前任务后处理 */
|
||
if(node_news->pri != s_task_current->pri){
|
||
goto __TASKING_POSTPROCESS;
|
||
}
|
||
/* 2、当前任务可以运行 && 时间片未到期 -> 返回 */
|
||
if(s_tick_counter < OS_TIMESHARING && s_task_current->status <= OS_STATUS_FLOATING){
|
||
s_task_current->status = OS_STATUS_READY;
|
||
return;
|
||
}
|
||
/* 3、当前任务不可运行 || 时间片已到期 -> 时间片轮转调度 */
|
||
node_curr = s_task_current;
|
||
move_backward;
|
||
while(node_last != node_tail && node_last->pri == node_curr->pri){
|
||
if(node_curr->status > OS_STATUS_FLOATING){
|
||
move_backward;
|
||
}
|
||
else{
|
||
node_news = node_curr;
|
||
goto __TASKING_POSTPROCESS;
|
||
}
|
||
}
|
||
/* 4、新任务仍为当前任务,说明时间片已到期 -> 返回 */
|
||
if(node_news == s_task_current){
|
||
s_task_current->status = OS_STATUS_READY;
|
||
s_tick_counter = 0;
|
||
return;
|
||
}
|
||
}
|
||
|
||
/* 当前任务后处理 */
|
||
__TASKING_POSTPROCESS:{
|
||
if(s_task_current->status < OS_STATUS_STOPPED){
|
||
sPUSH_Monitor;
|
||
}
|
||
else if(s_task_current->status == OS_STATUS_DELETED){
|
||
node_curr = s_task_current;
|
||
node_remove;
|
||
#if SYSCFG_TASKCREATEMODE != __STATIC__
|
||
s_free(node_curr->bsp);
|
||
#endif
|
||
#if SYSCFG_TASKCREATEMODE == __DYNAMIC__
|
||
((s_taskhand_tsp)node_curr->hand)->node = NULL;
|
||
s_free(node_curr);
|
||
#endif
|
||
}
|
||
}
|
||
|
||
/* 新任务预处理 */
|
||
__NEWTASK_PREPROCESS:{
|
||
node_news->status = OS_STATUS_READY;
|
||
s_tick_counter = 0;
|
||
#if SYSCFG_DEBUGGING == __ENABLED__
|
||
if(s_taskmgr_binary) counter = mSysTick_Counter;
|
||
#endif
|
||
}
|
||
|
||
/* 当前任务入栈 */
|
||
if(push_f){
|
||
#if SYSCFG_SAFERUNTIME == __ENABLED__
|
||
if(s_task_current->pri > node_news->pri){
|
||
s_task_current->counter = 0;
|
||
}
|
||
#endif
|
||
#if SYSCFG_DEBUGGING == __ENABLED__
|
||
if(s_taskmgr_binary) mUsedTime_END;
|
||
#endif
|
||
mTaskStack_PUSH;
|
||
}
|
||
|
||
/* 新任务出栈 */
|
||
if(true){
|
||
#if SYSCFG_DEBUGGING == __ENABLED__
|
||
if(s_taskmgr_binary) mUsedTime_INIT;
|
||
#endif
|
||
mTaskStack_POP;
|
||
}
|
||
}
|
||
}
|