Files
cosyos/System/os_handler.c
零中断延迟的RTOS ddbec84cbc update 内核文件.
Signed-off-by: 零中断延迟的RTOS <cosyos@139.com>
2026-02-01 18:58:41 +00:00

681 lines
18 KiB
C
Raw Permalink 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 V2.3.0
* @date 2026.02.01
******************************************************************************/
#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_stacklen_t _SYS_MEM_ s_taskstacklen;
#endif
__IAR_WEAK void tCosyTick_Handler(void) MCUCFG_SYSTICK_ATTRIBUTE
{
#if (OS_TIMINTTOTAL > 0 || OS_TIMQRYTOTAL > 0)
s_u8_t _SYS_REG_ i;
#endif
#if (SYSCFG_SYSTICKTIME_COUNT == __ENABLED__)
m_tick_t ticktemp_s sKill_W(=0);
#endif
s_tasknode_tsp _SYS_REG_ htask;
/* 清除中断标志位 */
mSysTick_Clear();
/* 系统滴答开始时刻 */// 此刻定义为系统滴答开始时刻 for 系统滴答时间统计。
#if (SYSCFG_SYSTICKTIME_COUNT == __ENABLED__)
if(s_taskmgr_sign){
ticktemp_s = MCUCFG_SYSTICK_CURRVALUE;
}
#endif
/* 软件RTC */
#if (SYSCFG_SOFTRTC == __ENABLED__)
#define counter s_rtc_counter
if(true){
if(counter < 1000000UL / SYSCFG_SYSTICK_CYCLE - 1){
counter++;
if(counter == 1000000UL / SYSCFG_SYSTICK_CYCLE / 2){
s_sign_every.halfsec = true;
}
}
else{
counter = 0;
s_sign_every.halfsec = true;
s_sign_every.second = true;
if(s_rtc.second < 59) s_rtc.second++;
else{
s_rtc.second = 0;
s_sign_every.minute = true;
if(s_rtc.minute < 59) s_rtc.minute++;
else{
s_rtc.minute = 0;
s_sign_every.hour = true;
if(s_rtc.hour < 23) s_rtc.hour++;
else{
s_rtc.hour = 0;
s_sign_every.day = true;
if(s_rtc.day < 7) s_rtc.day++;
else s_rtc.day = 1;
if(s_rtc.date < (s_rtc.month == 2 ? s_month2day : s_month0day[s_rtc.month])) s_rtc.date++;
else{
s_rtc.date = 1;
s_sign_every.month = true;
if(s_rtc.month < 12) s_rtc.month++;
else{
s_rtc.month = 1;
s_sign_every.year = true;
if(s_rtc.year < 99) s_rtc.year++;
else{
s_rtc.year = 0;
s_rtc.yeah++;
}
}
}
}
}
}
}
}
#undef counter
#endif
/* 运行时间统计 */
#if (SYSCFG_RUNTIME_COUNT == __ENABLED__)
if(true){
static m_rtccount_t _SYS_MEM_ counter = 0;
if(counter < 1000000UL / SYSCFG_SYSTICK_CYCLE - 1){
counter++;
}
else{
counter = 0;
if(s_runtime.second < 59) s_runtime.second++;
else{
s_runtime.second = 0;
if(s_runtime.minute < 59) s_runtime.minute++;
else{
s_runtime.minute = 0;
if(s_runtime.hour < 23) s_runtime.hour++;
else{
s_runtime.hour = 0;
s_runtime.day++;
}
}
}
}
}
#endif
/* 滴答钩子 */
#if (SYSCFG_TICKHOOK == __ENABLED__)
if(true){
void tick_hook(void);
tick_hook();
}
#endif
/* 任务管理器 */
#if (SYSCFG_DEBUGGING == __ENABLED__)
if(s_debug_recvlen){
void os_debug_recv(void);
os_debug_recv();
s_debug_recvlen = 0;
}
if(s_debug_sendsign){
s_debug_sendsign = false;
tTimQry_ms(OS_TMID_DEBUGGER, 10);
}
#endif
/* 定时中断 */
#if (OS_TIMINTTOTAL > 0)
i = OS_TIMINTTOTAL;
while(i--){
if(s_timint_handle[i]->timer){
s_timint_handle[i]->timer--;
if(!s_timint_handle[i]->timer){
if(s_timint_handle[i]->autoreload){
s_timint_handle[i]->timer = s_timint_handle[i]->reload;
}
if(s_timint_handle[i]->hookortask){
sResumeTask_TimInt(i);
}
else{
sCallHook_TimInt(i);
}
}
}
}
#endif
/* 定时查询 */
#if (OS_TIMQRYTOTAL > 0)
i = OS_TIMQRYTOTAL;
while(i--){
if(s_timqry_handle[i]->timer && s_timqry_handle[i]->timer < (s_timqry_t)~0){
s_timqry_handle[i]->timer--;
}
if(!s_timqry_handle[i]->timer){
if((*s_timqry_handle[i]->event)()){
if(s_timqry_handle[i]->autoreload){
s_timqry_handle[i]->timer = s_timqry_handle[i]->reload;
}
else{
s_timqry_handle[i]->timer = ~0;
}
if(s_timqry_handle[i]->hookortask){
sResumeTask_TimQry(i);
}
else{
sCallHook_TimQry(i);
}
}
}
}
#endif
/* 任务定时器 */// 定时器链表中的任务状态:就绪、浮动、阻塞、挂起。
if(true){
s_timer_pointer = (s_timer_pointer + 1) & (OS_TIMESLOTNUM - 1UL);
htask = s_timer_list[s_timer_pointer];
if(htask != OS_NULL){
bool loop_sign = true;
s_tasknode_tsp _SYS_REG_ hnext sKill_W(=OS_NULL);
s_tasknode_tsp _SYS_REG_ htail = htask->last_t;
__TIMER_LOOP:
if(htask == htail){
loop_sign = false;
}
else{
hnext = htask->next_t;
}
if(htask->status < OS_STATUS_SUSPENDED){
if( htask->timer.cycle){
htask->timer.cycle--;
}
else if(htask->status == OS_STATUS_READY){
sa_remove_timerlist(htask);
s_sign_delay = false;
}
else{
sa_clear_block(htask);
}
}
if(loop_sign){
htask = hnext;
goto __TIMER_LOOP;
}
}
}
/* 时间片 */
#if (SYSCFG_SAMEPRISCHEDULE == __TIMESHARING__)
if(s_task_current->tc_counter < OS_TIMESHARING(s_task_current)){
s_task_current->tc_counter++;
}
else{
s_sign_schedule.every[1] = false;
}
#endif
/* 安全运行时 */// 超时链表中的任务状态:超时、超时|挂起、停止、删除。
#if (SYSCFG_SAFERUNTIME == __ENABLED__)
if(!s_timeout_sign){
htask = s_timeout_list;
while(htask != OS_VOID){
if(htask->status == OS_STATUS_TIMEOUT){
htask->srt_counter = 0;
sa_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){
sa_free_task(htask);
}
}
s_timeout_list = htask->next_o;
htask->next_o = OS_NULL;
htask = s_timeout_list;
}
}
htask = s_task_current;
if(htask->pri && htask->saferuntime){
htask->srt_counter++;
if(htask->srt_counter > htask->saferuntime){
if(htask->status == OS_STATUS_READY){
htask->next_o = s_timeout_list;
s_timeout_list = htask;
sa_remove_ready(htask);
htask->status = OS_STATUS_TIMEOUT;
s_timeout_sign = true;
#if (SYSCFG_DEBUGGING == __ENABLED__)
s_alarm.timeout_saferuntime = true;
#endif
}
}
}
#endif
/* 任务管理器 */
#if (SYSCFG_DEBUGGING == __ENABLED__)
if(s_taskmgr_sign){
/* CPU使用时间计数 */
usedtime[0]++;
s_taskmgr_upspeed++;
/* 系统滴答时间统计 */// 此刻定义为系统滴答结束时刻。
#if (SYSCFG_SYSTICKTIME_COUNT == __ENABLED__)
if(true){
m_tick_t ticktemp_e = MCUCFG_SYSTICK_CURRVALUE;
#if (MCUCFG_SYSTICK_COUNTMODE == 1 || MCUCFG_SYSTICK_COUNTMODE == 3)
if(ticktemp_e > ticktemp_s){
s_tick_count1 += ticktemp_e - ticktemp_s;
}
#elif (MCUCFG_SYSTICK_COUNTMODE == 2 || MCUCFG_SYSTICK_COUNTMODE == 4)
if(ticktemp_s > ticktemp_e){
s_tick_count1 += ticktemp_s - ticktemp_e;
}
#endif
s_tick_count2++;
}
#endif
}
#endif
/* 触发任务调度 */
if(!s_sign_schedule.total){
mPendSV_Set();
}
}
#if (SYSCFG_DEBUGGING == __ENABLED__)
__IAR_WEAK void _cpu_usedtime_(m_tick_t ticktemp_0) MCUCFG_OSIT_ATTRIBUTE
{
#if (MCUCFG_SYSTICK_COUNTMODE == 1 || MCUCFG_SYSTICK_COUNTMODE == 3)
if(usedtime[0]){
s_task_current->usedtime[0] += usedtime[0] - 1;
usedtime[0] = 0;
usedtime[1] = (MCUCFG_SYSTICK_MAXVALUE - usedtime[1]) + (ticktemp_0 - MCUCFG_SYSTICK_MINVALUE);
}
else if(ticktemp_0 < usedtime[1]){
usedtime[0] = ~0;
usedtime[1] = (MCUCFG_SYSTICK_MAXVALUE - usedtime[1]) + (ticktemp_0 - MCUCFG_SYSTICK_MINVALUE);
}
else{
usedtime[1] = (ticktemp_0 - usedtime[1]);
}
#elif (MCUCFG_SYSTICK_COUNTMODE == 2 || MCUCFG_SYSTICK_COUNTMODE == 4)
if(usedtime[0]){
s_task_current->usedtime[0] += usedtime[0] - 1;
usedtime[0] = 0;
usedtime[1] = (usedtime[1] - MCUCFG_SYSTICK_MINVALUE) + (MCUCFG_SYSTICK_MAXVALUE - ticktemp_0);
}
else if(usedtime[1] < ticktemp_0){
usedtime[0] = ~0;
usedtime[1] = (usedtime[1] - MCUCFG_SYSTICK_MINVALUE) + (MCUCFG_SYSTICK_MAXVALUE - ticktemp_0);
}
else{
usedtime[1] = (usedtime[1] - ticktemp_0);
}
#endif
s_task_current->usedtime[0] += (s_task_current->usedtime[1] + usedtime[1]) / MCUCFG_SYSTICK_COUNT1CYC;
s_task_current->usedtime[1] = (s_task_current->usedtime[1] + usedtime[1]) % MCUCFG_SYSTICK_COUNT1CYC;
}
#endif
__IAR_WEAK void _float_to_ready_(s_tasknode_tsp htask) MCUCFG_OSIT_ATTRIBUTE
{
htask->status = OS_STATUS_READY;
// if(htask->next_b != OS_NULL){
sa_remove_blocklist(htask);
// }
if(htask->next_t != OS_NULL){
sa_remove_timerlist(htask);
}
}
__IAR_WEAK s_tasknode_tsp _SYS_MEM_ s_task_news/**/sZeroInstall;
__IAR_WEAK s_u8_t _start_task_(void) MCUCFG_OSIT_ATTRIBUTE
{
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_ecode = 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;
node_news->entry = s_task_starter->entry;
#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_ecode = OS_ECODE_MALLOCFAIL_TASKSTACK;
goto __STARTUP_END;
}
}
else{
#if (SYSCFG_DEBUGGING == __ENABLED__)
s_fault.failed_startuptask = true;
s_fault.mallocfailed_tasknode = true;
#endif
s_startup_ecode = 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.slots = 0;
node_news->timer.cycle = 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;
node_news->next_o = OS_NULL;
#endif
node_news->last_b = OS_NULL;
node_news->next_b = OS_NULL;
node_news->last_t = OS_NULL;
node_news->next_t = OS_NULL;
#if (SYSCFG_SAMEPRISCHEDULE && SYSCFG_MUTEX == __ENABLED__)
node_news->link = OS_NULL;
#endif
sa_insert_taskque(node_news);
s_task_queue_count++;
if(s_task_status0 == OS_STATUS_READY){
sa_add_ready(node_news);
}
s_startup_ecode = OS_ECODE_NOERROR;
__STARTUP_END:
s_task_starter = OS_NULL;
if(node_news == Starter){
if(s_startup_ecode == OS_ECODE_NOERROR){
#if (SYSCFG_DEBUGGING == __ENABLED__)
if(s_taskmgr_sign){
usedtime[1] = MCUCFG_SYSTICK_CURRVALUE;
}
#endif
mUserReg_RESc();
s_task_news = Starter;
return 1;
}
else return 0;
}
else return 2;
}
void pendsv_hook(void);
#if (SYSCFG_MCUCORE == 80251)
#pragma functions(static)
#endif
__IAR_WEAK s_u8_t sPendSV_Handler(void) MCUCFG_OSIT_ATTRIBUTE
{
/* 中断挂起服务_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_startup){
s_sign_startup = true;
if(s_task_starter != OS_NULL){
s_u8_t r = _start_task_();
if(r < 2) return r;
}
}
/* 任务调度 */
if(s_sign_schedule.total) return 0;
else{
#if (SYSCFG_DEBUGGING == __ENABLED__)
m_tick_t _SYS_REG_ ticktemp_0 sKill_W(=0);
m_bit_t push_sign = false; /*!< 入栈信号 */
#else
#define push_sign true
#endif
s_u8_t _SYS_REG_ pri;
s_tasknode_tsp _SYS_REG_ node_news;
s_sign_schedule.every[1] = true;
/* 抢占式调度(选择就绪)*/
if(true){
#if (SYSCFG_TASKPRIORITY > 64)
s_u8_t table_index = s_task_pickmap[s_task_table_index >> (SYSCFG_TASKPICKBITMAP & 1)];
s_u8_t bytes_index = s_task_pickmap[s_task_bytes_index[table_index] >> (SYSCFG_TASKPICKBITMAP & 1)];
s_u8_t bit_index = s_task_pickmap[s_task_ready_table[table_index][bytes_index] >> (SYSCFG_TASKPICKBITMAP & 1)];
pri = (table_index << 6) + (bytes_index << 3) + bit_index;
#elif (SYSCFG_TASKPRIORITY > 8)
s_u8_t bytes_index = s_task_pickmap[s_task_bytes_index >> (SYSCFG_TASKPICKBITMAP & 1)];
s_u8_t bit_index = s_task_pickmap[s_task_ready_table[bytes_index] >> (SYSCFG_TASKPICKBITMAP & 1)];
pri = (bytes_index << 3) + bit_index;
#else
pri = s_task_pickmap[s_task_ready_table >> (SYSCFG_TASKPICKBITMAP & 1)];
#endif
node_news = s_task_queue[pri];
}
/* 协作式调度 */
#if (SYSCFG_SAMEPRISCHEDULE == __COOPERATIVE__)
while(true){
if(node_news->status <= OS_STATUS_FLOATING){
break;
}
node_news = node_news->next;
}
/* 时间片轮转调度 */
#elif (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->blocktype){
node_news->blocktype = 0;
if(node_news->status == OS_STATUS_FLOATING){ /* 浮动变就绪 */
_float_to_ready_(node_news);
}
mSysIRQ_Disable(); /* 内核上锁 */// 使服务层临界区连续。
}
/* 新任务仍为当前任务 -> 返回 */
if(node_news == s_task_current){
return 0;
}
/* 新任务轮转至其优先级组首节点 */
#if (SYSCFG_SAMEPRISCHEDULE)
if(node_news != s_task_queue[pri]){
s_task_queue[pri] = node_news;
}
#endif
/* 入栈监控 */
#if (SYSCFG_DEBUGGING == __ENABLED__)
if(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){
push_sign = true;
s_task_current->create = 2;
s_alarm.realloc_taskstack = true;
}
else{
sa_stop_task(s_task_current);
s_fault.reallocfailed_taskstack = true;
}
}
else{
sa_stop_task(s_task_current);
s_fault.overflow_taskstack = true;
}
#else
sa_stop_task(s_task_current);
s_fault.overflow_taskstack = true;
#endif
}
else{
push_sign = true;
}
}
#endif
/* 任务切换时刻 */// 此刻定义为任务切换时刻 for CPU使用率统计。
#if (SYSCFG_DEBUGGING == __ENABLED__)
if(s_taskmgr_sign){
ticktemp_0 = MCUCFG_SYSTICK_CURRVALUE;
}
#endif
/* 当前任务入栈-预处理 */
if(push_sign){
#if (SYSCFG_SAFERUNTIME == __ENABLED__)
if(s_task_current->pri > node_news->pri){
s_task_current->srt_counter = 0;
}
#endif
#if (SYSCFG_DEBUGGING == __ENABLED__)
if(s_taskmgr_sign){
_cpu_usedtime_(ticktemp_0);
}
#endif
mUserReg_SAVEc();
}
/* 新任务出栈-预处理 */
if(true){
#if (SYSCFG_DEBUGGING == __ENABLED__)
if(s_taskmgr_sign){
usedtime[1] = ticktemp_0;
}
#endif
mUserReg_RESc();
s_task_news = node_news;
}
return (s_u8_t)push_sign + 1;
}
}