Files
cosyos/System/os_handler.c
零中断延迟的RTOS 6bbc248393 update CosyOS-内核文件.
Signed-off-by: 零中断延迟的RTOS <cosyos@139.com>
2025-06-27 08:33:54 +00:00

700 lines
18 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**************************************************************************//**
* @item CosyOS-III Kernel
* @file os_handler.c
* @brief tCosyTick_Handler and sPendSV_Handler
* @author 迟凯峰
* @version V1.3.3
* @date 2025.06.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 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
{
#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__
#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_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_delay){
if(~s_task_current->timer){
s_task_current->timer--;
if(!s_task_current->timer){
s_sign_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_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_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_taskque(node_news);
s_task_queue_count++;
if(s_task_status0 == OS_STATUS_READY){
sv_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);
#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
/* 每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_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_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 == __COOPERATIVE__
while(true){
if(node_news->status <= OS_STATUS_FLOATING){
break;
}
node_news = node_news->next;
}
#endif
/* 时间片轮转调度 */
#if SYSCFG_SAMEPRISCHEDULE == __TIMESHARING__
while(true){
s_tasknode_tsp _SYS_REG_ node_temp sKill_W(=OS_NULL);
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_blocklist(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;
}
}