/**************************************************************************//** * @item CosyOS-III Kernel * @file os_taskmgr.c * @brief 任务管理器(Taskmgr) * @author 迟凯峰 * @version v3.0.0 * @date 2026.07.21 ******************************************************************************/ #include "CosyOS.H" #if (SYSCFG_DEBUGGING == __ENABLED__) #include /** \brief 字符串内存 \details 字符串缓存 str[8] 的内存存储域。 \note 对于 8051/251 来说,用户可自定义该内存,以寻求在性能和资源之间取得平衡。 该内存默认被定义为 _SYS_MEM_,即 DATA 存储区,以实现高性能。 */ #define _STR_MEM_ _SYS_MEM_ static char _STR_MEM_ str[8]; /*!< 字符串缓存 */ static char _XDATA_MEM_ * _SYS_MEM_ mptr; /*!< 指向任务管理器发送缓存的可移动指针 */ /** \brief 字符拷贝 \param[in] c 字符 \return 无 */ #define _chrcpy_(c) *mptr++ = c /** \brief 字符n拷贝 \param[in] c 字符 \param[in] n 字符的数量 \return 无 */ static void _chrncpy_(char const c, s_u8_t n) { do{ *mptr++ = c; }while(--n); } /** \brief 空格拷贝 \param[in] n 空格的数量 \return 无 */ static void _spccpy_(s_u8_t n) { do{ *mptr++ = ' '; }while(--n); } /** \brief 字符串拷贝 \param[in] s 字符串指针 \return 无 */ static void _strcpy_(char const *s) { while(*s){ *mptr++ = *s++; } } /** \brief 字符串长度 \param[in] s 字符串指针 \return 字符串长度 */ static s_u8_t _strlen_(char const *s) { s_u8_t i = 0; while(*s++){ i++; } return i; } /** \brief u8转字符串 \param[in] var u8型数据 \return 无 */ static void _u8str_(s_u8_t const var) { char _STR_MEM_ *ptr = str; if(var >= 100){ *ptr++ = var / 100 + '0'; goto Lable_2; } if(var >= 10){ *ptr++ = var / 10 + '0'; goto Lable_1; } else{ *ptr++ = var /**/+ '0'; goto Lable_0; } Lable_2: *ptr++ = (var % 100) / 10 + '0'; Lable_1: *ptr++ = (var % 10) /**/+ '0'; Lable_0: *ptr = '\0'; } /** \brief u16转字符串 \param[in] var u16型数据 \return 无 */ static void _u16str_(s_u16_t const var) { char _STR_MEM_ *ptr = str; if(var >= 10000){ *ptr++ = var / 10000 + '0'; goto Lable_4; } if(var >= 1000){ *ptr++ = var / 1000 + '0'; goto Lable_3; } if(var >= 100){ *ptr++ = var / 100 + '0'; goto Lable_2; } if(var >= 10){ *ptr++ = var / 10 + '0'; goto Lable_1; } else{ *ptr++ = var /**/+ '0'; goto Lable_0; } Lable_4: *ptr++ = (var % 10000) / 1000 + '0'; Lable_3: *ptr++ = (var % 1000) / 100 + '0'; Lable_2: *ptr++ = (var % 100) / 10 + '0'; Lable_1: *ptr++ = (var % 10) /**/+ '0'; Lable_0: *ptr = '\0'; } /** \brief u16长度 \param[in] var u16型数据 \return 长度 */ static s_u8_t _u16len_(s_u16_t const var) { if(var >= 10000) return 5; if(var >= 1000) return 4; if(var >= 100) return 3; if(var >= 10) return 2; return 1; } /** \brief cpu使用率 \param[in] num 分子(分母:10000) \return 无 */ static void _used_ratio_(s_u16_t const num) { s_u8_t i; if(!num){ str[0] = '0'; str[1] = '\0'; i = 2; } else{ _u16str_(num); i = _strlen_(str); if(i > 2){ str[i-0] = str[i-1]; str[i-1] = str[i-2]; str[i-2] = '.'; str[i+1] = '\0'; i += 2; } else{ if(i == 1){ str[2] = '0'; str[3] = str[0]; } else{ str[2] = str[0]; str[3] = str[1]; } str[0] = '0'; str[1] = '.'; str[4] = '\0'; i = 5; } } _spccpy_((s_u8_t)(OS_TASKMGR_LEN_CPU - i)); _strcpy_(str); _chrcpy_('%'); } #if (SYSCFG_TASKPC_MONITOR == __ENABLED__) /** \brief u8转十六进制字符串 \param[in] var u8型数据 \return 无 \note 用于输出任务PC,十六进制字母为大写。 */ static void _u8str16_(s_u8_t const var) { str[0] = (var >> 4) + '0'; str[1] = (var & 0x0F) + '0'; if(str[0] > '9') str[0] += 0x07; if(str[1] > '9') str[1] += 0x07; *mptr++ = str[0]; *mptr++ = str[1]; } #endif /** \brief 任务管理器 \param[in] 定时器ID OS_TMID_TASKMGR \param[in] 定时查询事件 s_taskmgr_sign \param[in] 自动重装载 true \param[in] 任务名称 Taskmgr \param[in] 任务优先级 SYSCFG_TASKPRIORITY - 2 \param[in] 任务栈大小 SYSCFG_STACKSIZE_TASKMGR \param[in] 安全运行时 0 \param[in] 任务名称文本
遗产模式:"Taskmgr"
标准/兼容模式:[中文:"任务管理器",英文:"Taskmgr"] \return 无 \note 定时查询任务 */ #if (SYSCFG_DEBUG_LANGUAGE == 0) #define _taskname "Taskmgr" #else #define _taskname "\xC8\xCE\xCE\xF1\xB9\xDC\xC0\xED\xC6\xF7" /*!< "任务管理器" */ #endif uCreateTask_TimQry ( OS_TMID_TASKMGR, s_taskmgr_sign, true, Taskmgr, SYSCFG_TASKPRIORITY - 2, SYSCFG_STACKSIZE_TASKMGR, 0, _taskname ) { static char _XDATA_MEM_ *p[2]; mptr = s_taskmgr_sendbuff; /* 标题1 */ #if (SYSCFG_DEBUG_LANGUAGE == 0) _strcpy_("Taskmgr"); _spccpy_(OS_TASKMGR_LEN_LINE - OS_TASKMGR_LEN_CPU - OS_TASKMGR_LEN_RAM - 7); #else _strcpy_("\xC8\xCE\xCE\xF1\xB9\xDC\xC0\xED\xC6\xF7"); /*!< "任务管理器" */ _spccpy_(OS_TASKMGR_LEN_LINE - OS_TASKMGR_LEN_CPU - OS_TASKMGR_LEN_RAM - 10); #endif p[0] = mptr; /*!< 缓存CPU总使用率开始指针 */ _spccpy_(OS_TASKMGR_LEN_CPU + OS_TASKMGR_LEN_RAM); _strcpy_("\r\n"); /* 标题2 */ #if (SYSCFG_DEBUG_LANGUAGE == 0) _strcpy_("Name"); /*!< "Name" */ _spccpy_(SYSCFG_TASKNAMELEN_MAX - 1); _strcpy_("PRI"); /*!< "PRI" */ _spccpy_(OS_TASKMGR_LEN_STA - 3); _strcpy_("STA"); /*!< "STA" */ _spccpy_(OS_TASKMGR_LEN_CPU - 3); _strcpy_("CPU"); /*!< "CPU" */ _spccpy_(OS_TASKMGR_LEN_RAM - 3); _strcpy_("RAM"); /*!< "RAM" */ #else _strcpy_("\xC3\xFB\xB3\xC6"); /*!< "名称" */ _spccpy_(SYSCFG_TASKNAMELEN_MAX - 4); _strcpy_("\xD3\xC5\xCF\xC8\xBC\xB6"); /*!< "优先级" */ _spccpy_(OS_TASKMGR_LEN_STA - 4); _strcpy_("\xD7\xB4\xCC\xAC"); /*!< "状态" */ _spccpy_(OS_TASKMGR_LEN_CPU - 3); _strcpy_("CPU"); /*!< "CPU" */ _spccpy_(OS_TASKMGR_LEN_RAM - 4); _strcpy_("\xC4\xDA\xB4\xE6"); /*!< "内存" */ #endif _strcpy_("\r\n"); /* - */ _chrncpy_('-', OS_TASKMGR_LEN_LINE); _strcpy_("\r\n"); /* 正文 */ p[1] = mptr; /*!< 缓存正文开始指针 */ while(true){ #if (SYSCFG_TASKPC_MONITOR == __ENABLED__) m_pc_t pc = s_pc; #endif s_u8_t i = (s_u8_t)(SYSCFG_TASKPRIORITY); s_u16_t numerator1 = 10000; s_u32_t upspeed; s_taskctrl_tsp node_curr; static s_taskctrl_ts node_temp; mptr = p[1]; mSysIRQ_Disable(); upspeed = s_taskmgr_upspeed; s_taskmgr_upspeed = 0; mSysIRQ_Enable(); __TASKQUE_NEXT: do{ node_curr = s_task_queue[--i]; }while(node_curr == OS_NULL); while(true){ s_u16_t numerator2; mSysIRQ_Disable(); s_memcpy(&node_temp, node_curr, sizeof(s_taskctrl_ts)); node_curr->usedtime[0] = 0; node_curr->usedtime[1] = 0; mSysIRQ_Enable(); /* 名称 */ _strcpy_(node_temp.name); if(SYSCFG_TASKNAMELEN_MAX > _strlen_(node_temp.name)){ _spccpy_((s_u8_t)(SYSCFG_TASKNAMELEN_MAX - _strlen_(node_temp.name))); } /* 优先级 */ _u8str_ (node_temp.pri); _spccpy_((s_u8_t)(OS_TASKMGR_LEN_PRI - _strlen_(str))); _strcpy_(str); /* 状态 */ if(node_temp.status == OS_STATUS_READY){ _spccpy_(OS_TASKMGR_LEN_STA); } else if(node_temp.status == OS_STATUS_FLOATING || node_temp.status == OS_STATUS_BLOCKED){ _spccpy_(OS_TASKMGR_LEN_STA - 4); if(node_temp.status == OS_STATUS_FLOATING){ _chrcpy_('~'); } else{ _chrcpy_(' '); } switch(node_temp.blocktype){ case OS_BLOCKED_DELAY: _strcpy_("dly"); break; case OS_BLOCKED_BINARY: _strcpy_("bin"); break; case OS_BLOCKED_MUTEX: _strcpy_("mut"); break; case OS_BLOCKED_SEMAPHORE: _strcpy_("sem"); break; case OS_BLOCKED_TASKMSG: _strcpy_(" tm"); break; case OS_BLOCKED_FETION: _strcpy_("fet"); break; case OS_BLOCKED_MAIL: _strcpy_("mal"); break; case OS_BLOCKED_MSG: _strcpy_("msg"); break; case 1: _strcpy_("gro"); break; case 2: _strcpy_("gro"); break; case 4: _strcpy_("gro"); break; } } else{ _spccpy_(OS_TASKMGR_LEN_STA - 1); if(node_temp.status == OS_STATUS_TIMEOUT){ _chrcpy_('O'); } else if(node_temp.status & OS_STATUS_SUSPENDED){ _chrcpy_('^'); } else if(node_temp.status == OS_STATUS_STOPPED){ _chrcpy_('!'); } else{ _chrcpy_('X'); } } /* CPU */ numerator2 = ( ((node_temp.usedtime[0] * 10000UL) / upspeed) + ((node_temp.usedtime[1] * 10000UL) / upspeed / MCUCFG_SYSTICK_COUNT1CYC) ); _used_ratio_(numerator2); if(!node_temp.pri){ numerator1 -= numerator2; } /* 内存 */ _spccpy_( (s_u8_t)( OS_TASKMGR_LEN_RAM - 3 - _u16len_((s_u16_t)node_temp.stacklen_max) - _u16len_((s_u16_t)node_temp.stacksize) ) ); _u16str_(node_temp.stacklen_max); _strcpy_(str); _strcpy_("/"); switch(node_temp.create){ case 0: _chrcpy_('s'); break; case 1: _chrcpy_('m'); break; case 2: _chrcpy_('r'); break; } _u16str_(node_temp.stacksize); _strcpy_(str); _chrcpy_('B'); _strcpy_("\r\n"); /* 下一任务 */ #if (SYSCFG_SAMEPRISCHEDULE) if(node_curr == s_task_queue[i]->last){ if(!i) break; goto __TASKQUE_NEXT; } else{ node_curr = node_temp.next; } #else if(true){ if(!i) break; goto __TASKQUE_NEXT; } #endif } if(true){ char _XDATA_MEM_ *p0 = mptr; /* CPU总使用率 */ mptr = p[0]; _used_ratio_(numerator1); /* Stack Mode // Main Stack */ #if (MCUCFG_TASKSTACK_MODE == __PSP__) mptr += OS_TASKMGR_LEN_RAM - 3; _strcpy_("PSP"); #else if(true){ static s_u8_t i = 15; i = (i + 1) & 15; if(i < 8){ #if (MCUCFG_TASKSTACK_MODE == __MSP__) _spccpy_(OS_TASKMGR_LEN_RAM - 3); _strcpy_("MSP"); #elif (MCUCFG_TASKSTACK_MODE == __MSP_PSP__) _spccpy_(OS_TASKMGR_LEN_RAM - 7); _strcpy_("MSP+PSP"); #endif } else{ mptr += OS_TASKMGR_LEN_RAM - _u16len_(m_stacklen_max) - _u16len_(m_stacksize) - 2; _u16str_(m_stacklen_max); _strcpy_(str); _strcpy_("/"); _u16str_(m_stacksize); _strcpy_(str); _chrcpy_('B'); } } #endif mptr = p0; } _strcpy_("\r\n"); /*!< null-line */ /* PSV-FIFO */ _strcpy_("PSV-FIFO: "); #if (SYSCFG_PENDSVFIFO_MONITOR == __ENABLED__) if(mPendSV_FIFO_DepthMAX > SYSCFG_PENDSVFIFO_DEPTH){ s_fault.overflow_pendsvfifo = true; } _u16str_(mPendSV_FIFO_DepthMAX); _strcpy_(str); _strcpy_("/"); _u16str_(SYSCFG_PENDSVFIFO_DEPTH); _strcpy_(str); _strcpy_(","); _u16str_(mPendSV_FIFO_CountMAX); _strcpy_(str); _strcpy_("/"); _u16str_(SYSCFG_PENDSVFIFO_COUNT); _strcpy_(str); _spccpy_( (s_u8_t)( OS_TASKMGR_LEN_LINE - 20 - 10 - 3 - _u16len_((s_u16_t)mPendSV_FIFO_DepthMAX) - _u16len_((s_u16_t)SYSCFG_PENDSVFIFO_DEPTH) - _u16len_((s_u16_t)mPendSV_FIFO_CountMAX) - _u16len_((s_u16_t)SYSCFG_PENDSVFIFO_COUNT) ) ); #else _strcpy_("null"); _spccpy_(OS_TASKMGR_LEN_LINE - 20 - 10 - 4); #endif _strcpy_("| "); /* 任务pc值 */ #if (SYSCFG_DEBUG_LANGUAGE == 0) _strcpy_("task-pc: "); #else _strcpy_("\xC8\xCE\xCE\xF1pc\xD6\xB5: "); #endif #if (SYSCFG_TASKPC_MONITOR == __ENABLED__) #if (MCUCFG_PCLEN > 2) _u8str16_((s_u8_t)(pc >> 24)); _u8str16_((s_u8_t)(pc >> 16)); #endif _u8str16_((s_u8_t)(pc >> 8)); _u8str16_((s_u8_t)(pc)); #else _strcpy_("null"); #endif _strcpy_("\r\n"); /* 运行时间 */ #if (SYSCFG_DEBUG_LANGUAGE == 0) _strcpy_("run-time: "); #else _strcpy_("\xD4\xCB\xD0\xD0\xCA\xB1\xBC\xE4: "); #endif #if (SYSCFG_RUNTIME_COUNT == __ENABLED__) if(true){ s_runtime_ts runtime; mSysIRQ_Disable(); runtime = s_runtime; mSysIRQ_Enable(); _u16str_(runtime.day); _strcpy_(str); _chrcpy_('-'); if(runtime.hour < 10) _chrcpy_('0'); _u8str_(runtime.hour); _strcpy_(str); _chrcpy_(':'); if(runtime.minute < 10) _chrcpy_('0'); _u8str_(runtime.minute); _strcpy_(str); _chrcpy_(':'); if(runtime.second < 10) _chrcpy_('0'); _u8str_(runtime.second); _strcpy_(str); _spccpy_((s_u8_t)(OS_TASKMGR_LEN_LINE - 20 - 10 - 9 - _u16len_(runtime.day))); } #else _strcpy_("null"); _spccpy_(OS_TASKMGR_LEN_LINE - 20 - 10 - 4); #endif _strcpy_("| "); /* 滴答时间 */ #if (SYSCFG_DEBUG_LANGUAGE == 0) _strcpy_("systick: "); #else _strcpy_("\xB5\xCE\xB4\xF0\xCA\xB1\xBC\xE4: "); #endif #if (SYSCFG_SYSTICKTIME_COUNT == __ENABLED__) mSysIRQ_Disable(); if(s_tick_count2){ s_u32_t counter1 = s_tick_count1; s_u32_t counter2 = s_tick_count2; s_tick_count1 = 0; s_tick_count2 = 0; mSysIRQ_Enable(); counter2 = (counter1 * 100) / counter2; #if defined (MCUCFG_SYSCLK) && (MCUCFG_SYSCLK > 0) \ && defined (MCUCFG_SYSTICK_CLKDIV) && (MCUCFG_SYSTICK_CLKDIV > 0) counter2 = (counter2 * MCUCFG_SYSTICK_CLKDIV) / MCUCFG_SYSCLK; #elif defined (MCUCFG_SYSTICK_CLK) && (MCUCFG_SYSTICK_CLK > 0) counter2 = counter2 / MCUCFG_SYSTICK_CLK; #else #error SysTick CLK undefined! #endif _u16str_((s_u16_t)(counter2 / 100)); _strcpy_(str); _chrcpy_('.'); _u8str_((s_u8_t)((counter2 % 100) / 10)); _strcpy_(str); _u8str_((s_u8_t)(counter2 % 10)); _strcpy_(str); _strcpy_("us"); } else{ mSysIRQ_Enable(); } #else _strcpy_("null"); #endif _strcpy_("\r\n"); /* 系统警告 */ #if (SYSCFG_DEBUG_LANGUAGE == 0) _strcpy_("warning: "); #else _strcpy_("\xCF\xB5\xCD\xB3\xBE\xAF\xB8\xE6: "); #endif if(*(s_u8_t *)&s_alarm){ if(s_alarm.overflow_msgqueue){ _strcpy_("omq, "); } if(s_alarm.timeout_saferuntime){ _strcpy_("srt, "); } if(s_alarm.outrange_taskpriority){ _strcpy_("otp, "); } if(s_alarm.realloc_taskstack){ _strcpy_("rts, "); } if(s_alarm.overflow_taskstack){ _strcpy_("ots, "); } if(s_alarm.task_repeated_startup){ _strcpy_("trs, "); } mptr -= 2; } else{ #if (SYSCFG_DEBUG_LANGUAGE == 0) _strcpy_("null"); #else _strcpy_("\xCE\xDE"); #endif } _strcpy_("\r\n"); /* 系统异常 */ #if (SYSCFG_DEBUG_LANGUAGE == 0) _strcpy_("fault: "); #else _strcpy_("\xCF\xB5\xCD\xB3\xD2\xEC\xB3\xA3: "); #endif if(*(s_u8_t *)&s_fault){ if(s_fault.mallocfailed_msgnode){ _strcpy_("mmn, "); } if(s_fault.mallocfailed_tasknode){ _strcpy_("mtn, "); } if(s_fault.mallocfailed_taskstack){ _strcpy_("mts, "); } if(s_fault.reallocfailed_taskstack){ _strcpy_("rts, "); } if(s_fault.overflow_taskstack){ _strcpy_("ots, "); } if(s_fault.failed_startuptask){ _strcpy_("fst, "); } if(s_fault.error_recvmsg_int){ _strcpy_("erm, "); } #if (SYSCFG_PENDSVFIFO_MONITOR == __ENABLED__) if(s_fault.overflow_pendsvfifo){ _strcpy_("opd, "); } #endif mptr -= 2; } else{ #if (SYSCFG_DEBUG_LANGUAGE == 0) _strcpy_("null"); #else _strcpy_("\xCE\xDE"); #endif } _strcpy_("\r\n"); /* 当前时间 */ #if (SYSCFG_RTC_SHOW == __ENABLED__) if(true){ s_rtc_ts rtc; mSysIRQ_Disable(); if(true){ #if (SYSCFG_SOFTRTC == __ENABLED__) rtc = s_rtc; #else void rtc_hook(s_rtc_ts *t); rtc_hook(&rtc); #endif } mSysIRQ_Enable(); _spccpy_(OS_TASKMGR_LEN_LINE - 24); _u8str_(rtc.yeah); _strcpy_(str); if(rtc.year < 10) _chrcpy_('0'); _u8str_(rtc.year); _strcpy_(str); _chrcpy_('.'); if(rtc.month < 10) _chrcpy_('0'); _u8str_(rtc.month); _strcpy_(str); _chrcpy_('.'); if(rtc.date < 10) _chrcpy_('0'); _u8str_(rtc.date); _strcpy_(str); _chrcpy_('-'); if(rtc.hour < 10) _chrcpy_('0'); _u8str_(rtc.hour); _strcpy_(str); _chrcpy_(':'); if(rtc.minute < 10) _chrcpy_('0'); _u8str_(rtc.minute); _strcpy_(str); _chrcpy_(':'); if(rtc.second < 10) _chrcpy_('0'); _u8str_(rtc.second); _strcpy_(str); _chrcpy_(' '); _strcpy_("\xD6\xDC"); switch(rtc.day){ case 1: _strcpy_("\xD2\xBB"); break; case 2: _strcpy_("\xB6\xFE"); break; case 3: _strcpy_("\xC8\xFD"); break; case 4: _strcpy_("\xCB\xC4"); break; case 5: _strcpy_("\xCE\xE5"); break; case 6: _strcpy_("\xC1\xF9"); break; case 7: _strcpy_("\xC8\xD5"); break; } _strcpy_("\r\n"); } #endif _spccpy_((s_u8_t)(OS_TASKMGR_LEN_LINE - 11 - _strlen_(COSYOS3_VERSION))); _strcpy_("CosyOS-III "); _strcpy_(COSYOS3_VERSION); _strcpy_("\r\n\r\n"); /*!< null-line */ _chrcpy_('\0'); /*!< string-tail */ /* - */ mSysIRQ_Disable(); s_debug_sendtype |= OS_DEBUG_SEND_TASKMGR; #if (SYSCFG_DEBUG_SENDLEN == __ENABLED__) s_taskmgr_sendlen = (s_u16_t)(mptr - s_taskmgr_sendbuff - 1); #endif sa_suspend_task(s_task_current); su_kernel_unlock0_psv(); } } #undef _taskname #endif