Files
cosyos/System/os_taskmgr.c
零中断延迟的RTOS b1c9be47e2 update System/os_taskmgr.c.
Signed-off-by: 零中断延迟的RTOS <cosyos@139.com>
2025-04-15 09:52:11 +00:00

597 lines
14 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 V1.2.2
* @date 2025.04.15
******************************************************************************/
#include "os_var.h"
#if SYSCFG_DEBUGGING == __ENABLED__
#include "os_api.h"
#include "sv_com.h"
#include "sv_create.h"
#include "sv_task.h"
#include "ur_api.h"
#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_(const char 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_(const char *s)
{
while(*s){
*mptr++ = *s++;
}
}
/**
\brief 字符串长度
\param[in] s 字符串指针
\return 字符串长度
*/
static s_u8_t _strlen_(const char *s)
{
s_u8_t i = 0;
while(*s++){
i++;
}
return i;
}
/**
\brief u8转字符串
\param[in] var u8型数据
\return 无
*/
static void _u8str_(const s_u8_t 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_(const s_u16_t 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_(const s_u16_t 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_(const s_u16_t 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_(const s_u8_t 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
#define _taskname "\xC8\xCE\xCE\xF1\xB9\xDC\xC0\xED\xC6\xF7" /*!< "任务管理器" */
uCreateTask_TimQry
(
OS_TMID_TASKMGR, s_sign_taskmgr, true,
Taskmgr, SYSCFG_TASKPRIORITY - 2, SYSCFG_STACKSIZE_TASKMGR, 0, _taskname
)
{
static char _XDATA_MEM_ *p[2];
mptr = s_taskmgr_sendbuff;
/* 标题1 */
_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);
p[0] = mptr; /*!< 缓存CPU总使用率开始指针 */
_spccpy_(OS_TASKMGR_LEN_CPU + OS_TASKMGR_LEN_RAM - 8);
_strcpy_("CosyOS-3");
_strcpy_("\r\n");
/* 标题2 */
_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"); /*!< "内存" */
_strcpy_("\r\n");
/* - */
_chrncpy_('-', OS_TASKMGR_LEN_LINE);
_strcpy_("\r\n");
/* 正文 */
p[1] = mptr; /*!< 缓存正文开始指针 */
while(true){
static s_timqry_t upspeed = (SYSCFG_TASKMGR_UPSPEED * 1000UL) / SYSCFG_SYSTICK_CYCLE;
static s_tasknode_ts node_temp;
s_tasknode_tsp node_curr;
s_u16_t numerator1 = 10000;
s_u8_t i = SYSCFG_TASKPRIORITY;
#if SYSCFG_TASKPC_MONITOR == __ENABLED__
m_pc_t pc = s_pc;
#endif
mptr = p[1];
__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_tasknode_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_BLOCKED){
_spccpy_(OS_TASKMGR_LEN_STA - 3);
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_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 - 4
- _u16len_((s_u16_t)node_temp.stacklen_max)
- _u16len_((s_u16_t)node_temp.stacksize)
)
);
_u16str_(node_temp.stacklen_max);
_strcpy_(str);
_strcpy_("B/");
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
}
/* CPU总使用率 */
if(true){
char _XDATA_MEM_ *p0 = mptr;
mptr = p[0];
_used_ratio_(numerator1);
mptr = p0;
}
_strcpy_("\r\n"); /*!< null-line */
/* PSV-FIFO */
_strcpy_("PSV-FIFO: ");
#if SYSCFG_PENDSVFIFO_MONITOR == __ENABLED__
if(mPendSV_FIFO_DepthMAX > MCUCFG_PENDSVFIFO_DEPTH){
s_fault.overflow_pendsvfifo = true;
}
_u16str_(mPendSV_FIFO_DepthMAX);
_strcpy_(str);
_strcpy_("/");
_u16str_(MCUCFG_PENDSVFIFO_DEPTH);
_strcpy_(str);
_spccpy_(
(s_u8_t)(
OS_TASKMGR_LEN_LINE - 20 - 10 - 1
- _u16len_((s_u16_t)mPendSV_FIFO_DepthMAX)
- _u16len_((s_u16_t)MCUCFG_PENDSVFIFO_DEPTH)
)
);
#else
_strcpy_("null");
_spccpy_(OS_TASKMGR_LEN_LINE - 20 - 10 - 4);
#endif
_strcpy_("| ");
/* 任务pc值 */
_strcpy_("\xC8\xCE\xCE\xF1pc\xD6\xB5: ");
#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");
/* 运行时间 */
_strcpy_("\xD4\xCB\xD0\xD0\xCA\xB1\xBC\xE4: ");
#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_("| ");
/* 滴答时间 */
_strcpy_("\xB5\xCE\xB4\xF0\xCA\xB1\xBC\xE4: ");
#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) && defined(MCUCFG_SYSTICK_CLKDIV) \
&& (MCUCFG_SYSCLK > 0) && (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");
/* 系统警告 */
_strcpy_("\xCF\xB5\xCD\xB3\xBE\xAF\xB8\xE6: ");
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, ");
}
mptr -= 2;
}
else{
_strcpy_("\xCE\xDE");
}
_strcpy_("\r\n");
/* 系统异常 */
_strcpy_("\xCF\xB5\xCD\xB3\xD2\xEC\xB3\xA3: ");
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{
_strcpy_("\xCE\xDE");
}
_strcpy_("\r\n");
/* 当前时间 */
#if SYSCFG_RTC_SHOW == __ENABLED__
if(true){
s_rtc_ts rtc;
mSysIRQ_Disable();
rtc = s_rtc;
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
_strcpy_("\r\n"); /*!< null-line */
_chrcpy_('\0'); /*!< string-tail */
/* - */
mSysIRQ_Disable();
upspeed = s_timqry_handle[OS_TMID_TASKMGR]->reload;
s_debug_sendtype |= OS_DEBUG_SEND_TASKMGR;
#if SYSCFG_DEBUG_SENDLEN == __ENABLED__
s_taskmgr_sendlen = (size_t)(mptr - s_taskmgr_sendbuff - 1);
#endif
sv_suspend_task(s_task_current);
su_kernel_unlock0_psv();
}
}
#undef _taskname
#endif