首页 > 编程语言 >UcOs-III 源码阅读: os_stat.c

UcOs-III 源码阅读: os_stat.c

时间:2024-10-31 12:19:38浏览次数:3  
标签:stat EN UcOs 0u CFG 源码 endif OS CPU

//作用:包含统计任务的代码,用来计算全局CPU使用率以及每个任务的CPU使用率;

/*
*********************************************************************************************************
*                                              uC/OS-III
*                                        The Real-Time Kernel
*
*                    Copyright 2009-2022 Silicon Laboratories Inc. www.silabs.com
*
*                                 SPDX-License-Identifier: APACHE-2.0
*
*               This software is subject to an open source license and is distributed by
*                Silicon Laboratories Inc. pursuant to the terms of the Apache License,
*                    Version 2.0 available at www.apache.org/licenses/LICENSE-2.0.
*
*********************************************************************************************************
*/

/*
*********************************************************************************************************
*                                           STATISTICS MODULE
*
* File    : os_stat.c
* Version : V3.08.02
*********************************************************************************************************
*/

#define  MICRIUM_SOURCE
#include "os.h"

#ifdef VSC_INCLUDE_SOURCE_FILE_NAMES
const  CPU_CHAR  *os_stat__c = "$Id: $";
#endif


#if (OS_CFG_STAT_TASK_EN > 0u)

/*
************************************************************************************************************************
*                                                   RESET STATISTICS
*
* Description: This function is called by your application to reset the statistics.
*
* Argument(s): p_err      is a pointer to a variable that will contain an error code returned by this function.
*
*                             OS_ERR_NONE            The call succeeded
*
* Returns    : none
*
* Note(s)    : none
************************************************************************************************************************
*/

// 重置操作系统统计信息
void OSStatReset(OS_ERR *p_err)
{
    // 调试配置部分
#if (OS_CFG_DBG_EN > 0u)
    OS_TCB *p_tcb; // 指向任务控制块的指针
#if (OS_MSG_EN > 0u)
    OS_MSG_Q *p_msg_q; // 指向消息队列的指针
#endif
#if (OS_CFG_Q_EN > 0u)
    OS_Q *p_q; // 指向队列的指针
#endif
#endif
    CPU_SR_ALLOC(); // 分配状态寄存器空间

    // 安全关键配置
#ifdef OS_SAFETY_CRITICAL
    if (p_err == (OS_ERR *)0) {
        OS_SAFETY_CRITICAL_EXCEPTION();
        return;
    }
#endif

    // 进入临界区
    CPU_CRITICAL_ENTER();
#if (OS_CFG_STAT_TASK_EN > 0u)
    OSStatTaskCPUUsageMax = 0u; // 重置任务统计的最大CPU使用率
#if (OS_CFG_TS_EN > 0u)
    OSStatTaskTimeMax = 0u; // 重置任务统计的最大时间
#endif
#endif

#if (OS_CFG_TS_EN > 0u) && (OS_CFG_TICK_EN > 0u)
    OSTickTime = 0u; // 重置系统滴答时间
    OSTickTimeMax = 0u; // 重置最大系统滴答时间
#endif

#if (OS_CFG_TMR_EN > 0u)
#if (OS_CFG_TS_EN > 0u)
    OSTmrTaskTime = 0u; // 重置定时器任务时间
    OSTmrTaskTimeMax = 0u; // 重置最大定时器任务时间
#endif
#endif

#ifdef CPU_CFG_INT_DIS_MEAS_EN
#if (OS_CFG_TS_EN > 0u)
    OSIntDisTimeMax = 0u; // 重置最大中断禁用时间
    CPU_StatReset(); // 重置CPU特定的性能监控器
#endif
#endif

#if (OS_CFG_SCHED_LOCK_TIME_MEAS_EN > 0u)
    OSSchedLockTimeMax = 0u; // 重置最大调度锁定时间
#endif

#if ((OS_MSG_EN > 0u) && (OS_CFG_DBG_EN > 0u))
    OSMsgPool.NbrUsedMax = 0u; // 重置消息池的最大使用数量
#endif
    // 退出临界区
    CPU_CRITICAL_EXIT();

#if (OS_CFG_DBG_EN > 0u)
    // 进入临界区
    CPU_CRITICAL_ENTER();
    p_tcb = OSTaskDbgListPtr; // 获取任务调试列表指针
    CPU_CRITICAL_EXIT();
    // 重置每个任务的统计信息
    while (p_tcb != (OS_TCB *)0) {
        // 进入临界区
        CPU_CRITICAL_ENTER();

#ifdef CPU_CFG_INT_DIS_MEAS_EN
        p_tcb->IntDisTimeMax = 0u; // 重置任务的最大中断禁用时间
#endif

#if (OS_CFG_SCHED_LOCK_TIME_MEAS_EN > 0u)
        p_tcb->SchedLockTimeMax = 0u; // 重置任务的最大调度锁定时间
#endif

#if (OS_CFG_TASK_PROFILE_EN > 0u)
#if (OS_CFG_TASK_Q_EN > 0u)
        p_tcb->MsgQPendTimeMax = 0u; // 重置任务的消息队列等待最大时间
#endif
        p_tcb->SemPendTimeMax = 0u; // 重置任务的信号量等待最大时间
        p_tcb->CtxSwCtr = 0u; // 重置任务的上下文切换计数
        p_tcb->CPUUsage = 0u; // 重置任务的CPU使用率
        p_tcb->CPUUsageMax = 0u; // 重置任务的最大CPU使用率
        p_tcb->CyclesTotal = 0u; // 重置任务的总周期数
        p_tcb->CyclesTotalPrev = 0u; // 重置任务的前一个总周期数
#if (OS_CFG_TS_EN > 0u)
        p_tcb->CyclesStart = OS_TS_GET(); // 重置任务的起始周期
#endif
#endif

#if (OS_CFG_TASK_Q_EN > 0u)
        p_msg_q = &p_tcb->MsgQ; // 获取任务的消息队列
        p_msg_q->NbrEntriesMax = 0u; // 重置消息队列的最大条目数
#endif
        p_tcb = p_tcb->DbgNextPtr; // 获取下一个任务控制块
        // 退出临界区
        CPU_CRITICAL_EXIT();
    }
#endif

#if (OS_CFG_Q_EN > 0u) && (OS_CFG_DBG_EN > 0u)
    // 进入临界区
    CPU_CRITICAL_ENTER();
    p_q = OSQDbgListPtr; // 获取队列调试列表指针
    CPU_CRITICAL_EXIT();
    // 重置消息队列的统计信息
    while (p_q != (OS_Q *)0) {
        // 进入临界区
        CPU_CRITICAL_ENTER();
        p_msg_q = &p_q->MsgQ; // 获取队列的消息队列
        p_msg_q->NbrEntriesMax = 0u; // 重置消息队列的最大条目数
        p_q = p_q->DbgNextPtr; // 获取下一个队列
        // 退出临界区
        CPU_CRITICAL_EXIT();
    }
#endif

    *p_err = OS_ERR_NONE; // 设置错误代码为无错误
}


/*
************************************************************************************************************************
*                                                DETERMINE THE CPU CAPACITY
*
* Description: This function is called by your application to establish CPU usage by first determining how high a 32-bit
*              counter would count to in 1/10 second if no other tasks were to execute during that time.  CPU usage is
*              then determined by a low priority task which keeps track of this 32-bit counter every second but this
*              time, with other tasks running.  CPU usage is determined by:
*
*                                             OS_Stat_IdleCtr
*                 CPU Usage (%) = 100 * (1 - ------------------)
*                                            OS_Stat_IdleCtrMax
*
* Argument(s): p_err      is a pointer to a variable that will contain an error code returned by this function.
*
*                             OS_ERR_NONE              The call was successful
*                             OS_ERR_OS_NOT_RUNNING    If uC/OS-III is not running yet
*
* Returns    : none
*
* Note(s)    : none
************************************************************************************************************************
*/

/**
 * @brief 初始化CPU使用率统计任务
 *
 * 该函数用于初始化统计CPU使用率的任务, 包括校验参数有效性、同步时钟滴答、
 * 清空空闲计数器、计算最大空闲计数器值、恢复定时器任务等步骤。
 *
 * @param p_err 指向错误代码的指针,用于返回函数执行结果
 */
void  OSStatTaskCPUUsageInit (OS_ERR  *p_err)
{
    OS_ERR   err;
    OS_TICK  dly;
    CPU_SR_ALLOC();

    // 显式初始化err,以便于静态分析
    err = OS_ERR_NONE;

    // 安全关键代码检查:确保p_err参数有效
#ifdef OS_SAFETY_CRITICAL
    if (p_err == (OS_ERR *)0) {
        OS_SAFETY_CRITICAL_EXCEPTION();
        return;
    }
#endif

    // 检查操作系统是否正在运行
#if (OS_CFG_INVALID_OS_CALLS_CHK_EN > 0u)
    if (OSRunning != OS_STATE_OS_RUNNING) {
       *p_err = OS_ERR_OS_NOT_RUNNING;
        return;
    }
#endif

    // 暂停定时器任务,如果配置支持
#if ((OS_CFG_TMR_EN > 0u) && (OS_CFG_TASK_SUSPEND_EN > 0u))
    OSTaskSuspend(&OSTmrTaskTCB, &err);
    if (err != OS_ERR_NONE) {
       *p_err = err;
        return;
    }
#endif

    // 同步时钟滴答,确保时间准确性
    OSTimeDly(2u,
              (OS_OPT  )OS_OPT_TIME_DLY,
              (OS_ERR *)&err);
    if (err != OS_ERR_NONE) {
       *p_err = err;
        return;
    }

    // 进入临界区,清空空闲计数器
    CPU_CRITICAL_ENTER();
    OSStatTaskCtr = 0u;
    CPU_CRITICAL_EXIT();

    // 计算最大空闲计数器值
    dly = 0u;
    if (OSCfg_TickRate_Hz > OSCfg_StatTaskRate_Hz) {
        dly = (OS_TICK)(OSCfg_TickRate_Hz / OSCfg_StatTaskRate_Hz);
    }
    if (dly == 0u) {
        dly =  (OSCfg_TickRate_Hz / 10u);
    }

    // 延时以确定最大空闲计数器值
    OSTimeDly(dly,
              OS_OPT_TIME_DLY,
              &err);

    // 恢复定时器任务,如果配置支持
#if ((OS_CFG_TMR_EN > 0u) && (OS_CFG_TASK_SUSPEND_EN > 0u))
    OSTaskResume(&OSTmrTaskTCB, &err);
    if (err != OS_ERR_NONE) {
       *p_err = err;
        return;
    }
#endif

    // 进入临界区,初始化统计任务的相关变量
    CPU_CRITICAL_ENTER();
#if (OS_CFG_TS_EN > 0u)
    OSStatTaskTimeMax = 0u;
#endif

    // 存储最大空闲计数器值,设置统计任务就绪状态
    OSStatTaskCtrMax  = OSStatTaskCtr;
    OSStatTaskRdy     = OS_STATE_RDY;
    CPU_CRITICAL_EXIT();

    // 设置错误代码为无错误
   *p_err             = OS_ERR_NONE;
}


/*
************************************************************************************************************************
*                                                    STATISTICS TASK
*
* Description: This task is internal to uC/OS-III and is used to compute some statistics about the multitasking
*              environment.  Specifically, OS_StatTask() computes the CPU usage.  CPU usage is determined by:
*
*                                                   OSStatTaskCtr
*                 OSStatTaskCPUUsage = 100 * (1 - ------------------)     (units are in %)
*                                                  OSStatTaskCtrMax
*
* Arguments  : p_arg     this pointer is not used at this time.
*
* Returns    : none
*
* Note(s)    : 1) This task runs at a priority level higher than the idle task.
*
*              2) You can disable this task by setting the configuration #define OS_CFG_STAT_TASK_EN to 0.
*
*              3) You MUST have at least a delay of 2/10 seconds to allow for the system to establish the maximum value
*                 for the idle counter.
*
*              4) This function is INTERNAL to uC/OS-III and your application should not call it.
************************************************************************************************************************
*/

/**
 * @brief 操作系统统计任务函数
 *
 * 该函数是操作系统的一个任务,负责收集和记录系统的运行统计信息。通过传入的参数来执行具体的操作。
 *
 * @param p_arg 指向任务参数的指针。根据具体实现的不同,这个参数可以用来传递各种类型的数据。
 *              例如,它可以是一个结构体的指针,包含任务需要的所有参数。
 */
void  OS_StatTask (void  *p_arg)
{
#if (OS_CFG_DBG_EN > 0u)
#if (OS_CFG_TASK_PROFILE_EN > 0u)
    OS_CPU_USAGE usage;
    OS_CYCLES    cycles_total;
    OS_CYCLES    cycles_div;
    OS_CYCLES    cycles_mult;
    OS_CYCLES    cycles_max;
#endif
    OS_TCB      *p_tcb;
#endif
    OS_TICK      ctr_max;
    OS_TICK      ctr_mult;
    OS_TICK      ctr_div;
    OS_ERR       err;
    OS_TICK      dly;
#if (OS_CFG_TS_EN > 0u)
    CPU_TS       ts_start;
#endif
#if (OS_CFG_STAT_TASK_STK_CHK_EN > 0u) && (OS_CFG_ISR_STK_SIZE > 0u)
    CPU_STK     *p_stk;
    CPU_INT32U   free_stk;
    CPU_INT32U   size_stk;
#endif
    CPU_SR_ALLOC();


    (void)p_arg;                                                /* Prevent compiler warning for not using 'p_arg'       */

    while (OSStatTaskRdy != OS_TRUE) {
        OSTimeDly(2u * OSCfg_StatTaskRate_Hz,                   /* Wait until statistic task is ready                   */
                  OS_OPT_TIME_DLY,
                  &err);
    }
    OSStatReset(&err);                                          /* Reset statistics                                     */

    dly = (OS_TICK)0;                                           /* Compute statistic task sleep delay                   */
    if (OSCfg_TickRate_Hz > OSCfg_StatTaskRate_Hz) {
        dly = (OSCfg_TickRate_Hz / OSCfg_StatTaskRate_Hz);
    }
    if (dly == 0u) {
        dly =  (OSCfg_TickRate_Hz / 10u);
    }

    for (;;) {
#if (OS_CFG_TS_EN > 0u)
        ts_start        = OS_TS_GET();
#ifdef  CPU_CFG_INT_DIS_MEAS_EN
        OSIntDisTimeMax = CPU_IntDisMeasMaxGet();
#endif
#endif

        CPU_CRITICAL_ENTER();                                   /* ---------------- OVERALL CPU USAGE ----------------- */
        OSStatTaskCtrRun   = OSStatTaskCtr;                     /* Obtain the of the stat counter for the past .1 second*/
        OSStatTaskCtr      = 0u;                                /* Reset the stat counter for the next .1 second        */
        CPU_CRITICAL_EXIT();

        if (OSStatTaskCtrMax > OSStatTaskCtrRun) {              /* Compute CPU Usage with best resolution               */
            if (OSStatTaskCtrMax < 400000u) {                   /* 1 to       400,000                                   */
                ctr_mult = 10000u;
                ctr_div  =     1u;
            } else if (OSStatTaskCtrMax <   4000000u) {         /* 400,000 to     4,000,000                             */
                ctr_mult =  1000u;
                ctr_div  =    10u;
            } else if (OSStatTaskCtrMax <  40000000u) {         /* 4,000,000 to    40,000,000                           */
                ctr_mult =   100u;
                ctr_div  =   100u;
            } else if (OSStatTaskCtrMax < 400000000u) {         /* 40,000,000 to   400,000,000                          */
                ctr_mult =    10u;
                ctr_div  =  1000u;
            } else {                                            /* 400,000,000 and up                                   */
                ctr_mult =     1u;
                ctr_div  = 10000u;
            }
            ctr_max            = OSStatTaskCtrMax / ctr_div;
            OSStatTaskCPUUsage = (OS_CPU_USAGE)((OS_TICK)10000u - ((ctr_mult * OSStatTaskCtrRun) / ctr_max));
            if (OSStatTaskCPUUsageMax < OSStatTaskCPUUsage) {
                OSStatTaskCPUUsageMax = OSStatTaskCPUUsage;
            }
        } else {
            OSStatTaskCPUUsage = 0u;
        }

        OSStatTaskHook();                                       /* Invoke user definable hook                           */


#if (OS_CFG_DBG_EN > 0u)
#if (OS_CFG_TASK_PROFILE_EN > 0u)
        cycles_total = 0u;

        CPU_CRITICAL_ENTER();
        p_tcb = OSTaskDbgListPtr;
        CPU_CRITICAL_EXIT();
        while (p_tcb != (OS_TCB *)0) {                          /* ---------------- TOTAL CYCLES COUNT ---------------- */
            CPU_CRITICAL_ENTER();
            p_tcb->CyclesTotalPrev = p_tcb->CyclesTotal;        /* Save accumulated # cycles into a temp variable       */
            p_tcb->CyclesTotal     = 0u;                        /* Reset total cycles for task for next run             */
            CPU_CRITICAL_EXIT();

            cycles_total          += p_tcb->CyclesTotalPrev;    /* Perform sum of all task # cycles                     */

            CPU_CRITICAL_ENTER();
            p_tcb                  = p_tcb->DbgNextPtr;
            CPU_CRITICAL_EXIT();
        }
#endif


#if (OS_CFG_TASK_PROFILE_EN > 0u)
                                                                /* ------------ INDIVIDUAL TASK CPU USAGE ------------- */
        if (cycles_total > 0u) {                                /* 'cycles_total' scaling ...                           */
            if (cycles_total < 400000u) {                       /* 1 to       400,000                                   */
                cycles_mult = 10000u;
                cycles_div  =     1u;
            } else if (cycles_total <   4000000u) {             /* 400,000 to     4,000,000                             */
                cycles_mult =  1000u;
                cycles_div  =    10u;
            } else if (cycles_total <  40000000u) {             /* 4,000,000 to    40,000,000                           */
                cycles_mult =   100u;
                cycles_div  =   100u;
            } else if (cycles_total < 400000000u) {             /* 40,000,000 to   400,000,000                          */
                cycles_mult =    10u;
                cycles_div  =  1000u;
            } else {                                            /* 400,000,000 and up                                   */
                cycles_mult =     1u;
                cycles_div  = 10000u;
            }
            cycles_max  = cycles_total / cycles_div;
        } else {
            cycles_mult = 0u;
            cycles_max  = 1u;
        }
#endif
        CPU_CRITICAL_ENTER();
        p_tcb = OSTaskDbgListPtr;
        CPU_CRITICAL_EXIT();
        while (p_tcb != (OS_TCB *)0) {
#if (OS_CFG_TASK_PROFILE_EN > 0u)                               /* Compute execution time of each task                  */
            usage = (OS_CPU_USAGE)(cycles_mult * p_tcb->CyclesTotalPrev / cycles_max);
            if (usage > 10000u) {
                usage = 10000u;
            }
            p_tcb->CPUUsage = usage;
            if (p_tcb->CPUUsageMax < usage) {                   /* Detect peak CPU usage                                */
                p_tcb->CPUUsageMax = usage;
            }
#endif

#if (OS_CFG_STAT_TASK_STK_CHK_EN > 0u)
            OSTaskStkChk( p_tcb,                                /* Compute stack usage of active tasks only             */
                         &p_tcb->StkFree,
                         &p_tcb->StkUsed,
                         &err);
#endif

            CPU_CRITICAL_ENTER();
            p_tcb = p_tcb->DbgNextPtr;
            CPU_CRITICAL_EXIT();
        }
#endif

                                                                /*------------------ Check ISR Stack -------------------*/
#if (OS_CFG_STAT_TASK_STK_CHK_EN > 0u) && (OS_CFG_ISR_STK_SIZE > 0u)
        free_stk  = 0u;
#if (CPU_CFG_STK_GROWTH == CPU_STK_GROWTH_HI_TO_LO)
        p_stk     = OSCfg_ISRStkBasePtr;                        /*   Start at the lowest memory and go up               */
#if (OS_CFG_TASK_STK_REDZONE_EN > 0u)
        p_stk    += OS_CFG_TASK_STK_REDZONE_DEPTH;
        size_stk  = OSCfg_ISRStkSize - OS_CFG_TASK_STK_REDZONE_DEPTH;
#else
        size_stk  = OSCfg_ISRStkSize;
#endif
        while ((*p_stk == 0u) && (free_stk < size_stk)) {       /*   Compute the number of zero entries on the stk      */
            p_stk++;
            free_stk++;
        }
#else
        p_stk     = OSCfg_ISRStkBasePtr + OSCfg_ISRStkSize - 1u;/*   Start at the highest memory and go down            */
#if (OS_CFG_TASK_STK_REDZONE_EN > 0u)
        p_stk    -= OS_CFG_TASK_STK_REDZONE_DEPTH;
        size_stk  = OSCfg_ISRStkSize - OS_CFG_TASK_STK_REDZONE_DEPTH;
#else
        size_stk  = OSCfg_ISRStkSize;
#endif
        while ((*p_stk == 0u) && (free_stk < size_stk)) {       /*   Compute the number of zero entries on the stk      */
            free_stk++;
            p_stk--;
        }
#endif
        OSISRStkFree = free_stk;
        OSISRStkUsed = OSCfg_ISRStkSize - free_stk;
#endif

        if (OSStatResetFlag == OS_TRUE) {                       /* Check if need to reset statistics                    */
            OSStatResetFlag  = OS_FALSE;
            OSStatReset(&err);
        }

#if (OS_CFG_TS_EN > 0u)
        OSStatTaskTime = OS_TS_GET() - ts_start;                /*----- Measure execution time of statistic task -------*/
        if (OSStatTaskTimeMax < OSStatTaskTime) {
            OSStatTaskTimeMax = OSStatTaskTime;
        }
#endif

        OSTimeDly(dly,
                  OS_OPT_TIME_DLY,
                  &err);
    }
}


/*
************************************************************************************************************************
*                                              INITIALIZE THE STATISTICS
*
* Description: This function is called by OSInit() to initialize the statistic task.
*
* Argument(s): p_err     is a pointer to a variable that will contain an error code returned by this function.
*
*                            OS_ERR_STAT_STK_INVALID       If you specified a NULL stack pointer during configuration
*                            OS_ERR_STAT_STK_SIZE_INVALID  If you didn't specify a large enough stack.
*                            OS_ERR_STAT_PRIO_INVALID      If you specified a priority for the statistic task equal to or
*                                                          lower (i.e. higher number) than the idle task.
*                            OS_ERR_xxx                    An error code returned by OSTaskCreate()
*
* Returns    : none
*
* Note(s)    : This function is INTERNAL to uC/OS-III and your application should not call it.
************************************************************************************************************************
*/

/**
 * @brief 初始化统计任务
 *
 * 本函数负责初始化统计任务的相关参数,并创建统计任务
 * 统计任务用于收集系统运行时的信息,如CPU利用率等
 *
 * @param p_err 指向错误代码的指针,用于返回函数执行结果
 */
void  OS_StatTaskInit (OS_ERR  *p_err)
{
    // 初始化统计任务的计数器和标志
    OSStatTaskCtr    = 0u;
    OSStatTaskCtrRun = 0u;
    OSStatTaskCtrMax = 0u;
    OSStatTaskRdy    = OS_STATE_NOT_RDY;                        /* 统计任务尚未就绪                          */
    OSStatResetFlag  = OS_FALSE;

    // 如果配置了堆栈检查,则初始化中断服务程序堆栈使用情况变量
#if (OS_CFG_STAT_TASK_STK_CHK_EN > 0u) && (OS_CFG_ISR_STK_SIZE > 0u)
    OSISRStkFree     = 0u;
    OSISRStkUsed     = 0u;
#endif

    // 检查统计任务的堆栈指针是否有效
    if (OSCfg_StatTaskStkBasePtr == (CPU_STK *)0) {
       *p_err = OS_ERR_STAT_STK_INVALID;
        return;
    }

    // 检查统计任务的堆栈大小是否符合最小要求
    if (OSCfg_StatTaskStkSize < OSCfg_StkSizeMin) {
       *p_err = OS_ERR_STAT_STK_SIZE_INVALID;
        return;
    }

    // 检查统计任务的优先级是否在有效范围内
    if (OSCfg_StatTaskPrio >= (OS_CFG_PRIO_MAX - 1u)) {
       *p_err = OS_ERR_STAT_PRIO_INVALID;
        return;
    }

    // 创建统计任务
    OSTaskCreate(&OSStatTaskTCB,
#if  (OS_CFG_DBG_EN == 0u)
                 (CPU_CHAR   *)0,
#else
                 (CPU_CHAR   *)"uC/OS-III Stat Task",
#endif
                  OS_StatTask,
                 (void       *)0,
                  OSCfg_StatTaskPrio,
                  OSCfg_StatTaskStkBasePtr,
                  OSCfg_StatTaskStkLimit,
                  OSCfg_StatTaskStkSize,
                  0u,
                  0u,
                 (void       *)0,
                 (OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR),
                  p_err);
}

#endif

标签:stat,EN,UcOs,0u,CFG,源码,endif,OS,CPU
From: https://www.cnblogs.com/lanlincmos/p/18517459

相关文章