Files
cosyos/System/os_taskmgr.c
T
零中断延迟的RTOSandGitee 9dde142350 update CosyOS-内核文件.
Signed-off-by: 零中断延迟的RTOS <cosyos@139.com>
2026-07-21 12:07:30 +00:00

713 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_taskmgr.c
* @brief 任务管理器(Taskmgr
* @author 迟凯峰
* @version v3.0.0
* @date 2026.07.21
******************************************************************************/
#include "CosyOS.H"
#if (SYSCFG_DEBUGGING == __ENABLED__)
#include <string.h>
/**
\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] 任务名称文本<br>
遗产模式:"Taskmgr"<br>
标准/兼容模式:[中文:"任务管理器",英文:"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