[原创] 【NXP Rapid IoT评测】FreeRTOS调试方法(任务执行情况输出)

dvd1478   2019-3-24 17:04 楼主
          NXP Rapid IoT源代码中很丰富,虽然知道使用FreeRTOS的但是代码的嵌套异常的复杂,对分析起来带来了困难。所以想通过FreeRTOS自身的vTaskList与 vTaskGetRunTimeStats 输出自身运行任务的情况          效果如下:
2.png
上面截图中打印出来的任务状态字母 B, R, D, S 对应如下含义:
#define tskBLOCKED_CHAR         ( 'B' )    任务阻塞
#define tskREADY_CHAR              ( 'R' )    任务就绪
#define tskDELETED_CHAR          ( 'D' )    任务删除
#define tskSUSPENDED_CHAR     ( 'S' )    任务挂起
另外要注意剩余栈的单位是 word,即 4 字节。



一、修改宏
.\RapidIot_Base\middleware\wireless\framework\Common\rtos\FreeRTOS\config\FreeRTOSConfig.h 修改以下宏
  1. /* Run time and task stats gathering related definitions. */
  2. #define configUSE_TRACE_FACILITY                                   1
  3. #define configGENERATE_RUN_TIME_STATS                           1
  4. #define configUSE_STATS_FORMATTING_FUNCTIONS           1

  5. /* Ensure stdint is only used by the compiler, and not the assembler. */
  6. #if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__)
  7.   #include <stdint.h>
  8.   extern volatile uint32_t ulHighFrequencyTimerTicks;
  9. #endif

  10. #define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS()  (ulHighFrequencyTimerTicks = 0ul)
  11. #define portGET_RUN_TIME_COUNTER_VALUE()           ulHighFrequencyTimerTicks



二、添加以下代码
  1. /*
  2. *********************************************************************************************************
  3. *
  4. *        模块名称 : FreeRTOS任务信息
  5. *        文件名称 :
  6. *        版    本 : V1.0
  7. *        说    明 : 为了获取FreeRTOS的任务信息,需要创建一个定时器,这个定时器的时间基准精度要高于
  8. *              系统时钟节拍。这样得到的任务信息才准确。
  9. *              本文件提供的函数仅用于测试目的,切不可将其用于实际项目,原因有两点:
  10. *               1. FreeRTOS的系统内核没有对总的计数时间做溢出保护。
  11. *               2. 定时器中断是50us进入一次,比较影响系统性能。
  12. *              --------------------------------------------------------------------------------------
  13. *              本文件使用的是32位变量来保存50us一次的计数值,最大支持计数时间:
  14. *              2^32 * 50us / 3600s = 59.6分钟。使用中测试的任务运行计数和任务占用率超过了59.6分钟将不准确。
  15. *
  16. *
  17. *********************************************************************************************************
  18. */
  19. #include <string.h>

  20. #include "fsl_pit.h"
  21. #include "clock_config.h"

  22. #include "fsl_os_abstraction.h"
  23. #include "fsl_os_abstraction_free_rtos.h"
  24. //#include "cmsis_os.h"
  25. #include "FreeRTOS.h"
  26. #include "task.h"
  27. #include "timers.h"
  28. #include "queue.h"
  29. #include "semphr.h"
  30. #include "event_groups.h"

  31. #include "shell.h"
  32. #include "atmosphere_platform.h"
  33. /* 定时器频率,50us一次中断 */
  34. #define  timerINTERRUPT_FREQUENCY        20000

  35. /* 中断优先级 */
  36. #define  timerHIGHEST_PRIORITY                2

  37. /* 被系统调用 */
  38. volatile uint32_t ulHighFrequencyTimerTicks = 0UL;

  39. static int8_t shell_cmdTaskInfo(uint8_t argc, char * argv[]);
  40. const cmd_tbl_t CommandTask_Ver =
  41. {       .name = "taskinfo",
  42.         .maxargs = 2,
  43.         .repeatable = 1,
  44.         .cmd = shell_cmdTaskInfo,
  45.         .usage = "print FreeRTOS Info ",
  46. #if SHELL_USE_AUTO_COMPLETE
  47.         .complete = NULL,
  48. #endif
  49.         .help = NULL };

  50. static int8_t shell_cmdTaskInfo(uint8_t argc, char * argv[])
  51. {
  52.     char* pcWriteBuffer=NULL;
  53.     pcWriteBuffer = (char*) ATMO_Malloc(512);
  54.     if (pcWriteBuffer)
  55.     {
  56.         shell_write("=================================================\r\n");
  57.         shell_write("Task            State  Prio  ReStack  Num\r\n");
  58.         vTaskList((char *) pcWriteBuffer);
  59.         shell_writeN(pcWriteBuffer,strlen(pcWriteBuffer));
  60.         shell_write("\r\nTask            Count           Usage\r\n");
  61.         vTaskGetRunTimeStats((char *) pcWriteBuffer);
  62.         shell_writeN(pcWriteBuffer,strlen(pcWriteBuffer));
  63.         ATMO_Free(pcWriteBuffer);
  64.     } else {
  65.         shell_write("FreeRtos TaskInfo Error\r\n");
  66.     }
  67.     return CMD_RET_SUCCESS;
  68. }

  69. /*
  70. *********************************************************************************************************
  71. *        函 数 名: vSetupTimerTest
  72. *        功能说明: 创建定时器
  73. *        形    参: 无
  74. *        返 回 值: 无
  75. *********************************************************************************************************
  76. */
  77. void vAFreeRtosTaskInfoInit(void)
  78. {
  79.     /* Structure of initialize PIT */
  80.     pit_config_t pitConfig;

  81.     /*
  82.      * pitConfig.enableRunInDebug = false;
  83.      */
  84.     PIT_GetDefaultConfig(&pitConfig);

  85.     /* Init pit module */
  86.     PIT_Init(PIT, &pitConfig);

  87.     /* Set timer period for channel 0 */
  88.     PIT_SetTimerPeriod(PIT, kPIT_Chnl_0,
  89.             USEC_TO_COUNT(50U, CLOCK_GetFreq(kCLOCK_BusClk)));

  90.     /* Enable timer interrupts for channel 0 */
  91.     PIT_EnableInterrupts(PIT, kPIT_Chnl_0, kPIT_TimerInterruptEnable);

  92.     /* Enable at the NVIC */
  93.     EnableIRQ(PIT0_IRQn);

  94.     shell_register_function((cmd_tbl_t *)&CommandTask_Ver);
  95. }

  96. /*
  97. *********************************************************************************************************
  98. *        函 数 名: PIT0_IRQHandler
  99. *        功能说明: PIT0中断服务程序。
  100. *        形    参: 无
  101. *        返 回 值: 无
  102. *********************************************************************************************************
  103. */
  104. void PIT0_IRQHandler(void)
  105. {
  106.     /* Clear interrupt flag.*/
  107.     PIT_ClearStatusFlags(PIT, kPIT_Chnl_0, kPIT_TimerFlag);
  108.     ulHighFrequencyTimerTicks++;
  109. }

  110. /********************************************* (END OF FILE) *********************************/



调用初始化函数void vAFreeRtosTaskInfoInit(void),然后通过串口输出 taskinfo,就能输出相应的任务情况
2.png

通过上述的调试,获取相应的创建任务的情况 以及相关的任务函数 分别如下:
1、
.\RapidIot_Base\middleware\wireless\framework\OSAbstraction\Source\fsl_os_abstraction_free_rtos.c
int main (void) 创建 startup_task 任务

2、
.\RapidIot_Base\rtos\freertos\Source\tasks.c
void vTaskStartScheduler( void )创建  IDLE  任务

3、
.\RapidIot_Base\rtos\freertos\Source\timers.c
BaseType_t xTimerCreateTimerTask( void ) 创建 prvTimerTask任务

4、
.\app_src\app_emwin.c
void emWinTaskInit(void)创建  emWinTask  任务

5、
.\RapidIot_Base\middleware\wireless\framework\SerialManager\Source\SerialManager.c
void SerialManager_Init( void ) 创建 SerialManagerTask 任务

6、
.\RapidIot_Base\middleware\wireless\framework\TimersManager\Source\TimersManager.c
void TMR_Init(void)  创建 TMR_Task任务

7、
.\RapidIot_Base\middleware\wireless\framework\SerialManager\Source\USB_VirtualCom\virtual_com.c
void* VirtualCom_Init(uint8_t param)创建  USB_DeviceTask任务

8、
.\gpio\gpio_mk64f.c
ATMO_GPIO_Status_t ATMO_MK64F_GPIO_Init(ATMO_DriverInstanceData_t *instance)
创建 ATMO_MK64F_GPIO_RXQueueChecker  ATMO_MK64F_GPIO_ButtonResetChecker任务

9、
.\interval\interval_mk64f.c
ATMO_INTERVAL_Status_t ATMO_MK64F_INTERVAL_Init(ATMO_DriverInstanceData_t *instance)
ATMO_INTERVAL_Status_t ATMO_MK64F_INTERVAL_AddCallbackInterval(ATMO_DriverInstanceData_t *instance, ATMO_Callback_t cb, unsigned int interval, ATMO_INTERVAL_Handle_t *intervalHandle)
创建 intervalTask 任务







此内容由EEWORLD论坛网友dvd1478原创,如需转载或用于商业用途需征得作者同意并注明出处


回复评论 (2)

多谢楼主分享,看上去很不错!
点赞  2019-3-25 11:13
真的很有用啊。
点赞  2019-3-26 08:55
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复