FreeRTOS 调试方法(printf---打印任务执行情况)
以下转载自安富莱电子: http://forum.armfly.com/forum.php
本章节为大家介绍 FreeRTOS 的调试方法,这里的调试方法主要是教会大家如何获取任务的执行情况,通过获取的任务信息,可以进一步的配置和优化工程,这种方法非常实用,建议初学者必须掌握。
串口打印调试说明
很多时候,我们需要了解任务的执行状态,任务栈的使用情况以及各个任务的 CPU 使用率,这时就
需要用到官方提供的两个函数 vTaskList和vTaskGetRunTimeStats。用户就可以通过这两个函数获得任
务的执行情况。
获取了任务执行情况后,可以通过串口将其打印出来,当然,也可以通过任何其它方式将其显示出来。
本教程配套的例子统一采用串口打印的方式显示任务的执行情况。另外有一点要特别注意,这种调试方式
仅限测试目的,实际项目中不要使用,这种测试方式比较影响系统实时性。
为了获取 FreeRTOS 的任务信息,需要创建一个定时器,这个定时器的时间基准精度要高于系统时钟
节拍,这样得到的任务信息才准确。这里提供的函数仅用于测试目的,切不可将其用于实际项目,原因有两点:
1. FreeRTOS 的系统内核没有对总的计数时间做溢出保护。
2. 定时器中断是 50us 进入一次,比较影响系统性能。
这里使用的是 32 位变量来保存 50us 一次的计数值,最大支持计数时间:2^32 * 50us / 3600s =
59.6 分钟。 运行时间超过了 59.6 分钟将不准确。
具体在 FreeRTOS 的工程中如何做才可以实现任务信息获取呢?
使能相关宏定义
需要在 FreeRTOSConfig.h 文件中使能如下宏定义:
/***freertosconfig.h***/ extern volatile uint32_t ulHighFrequencyTimerTicks ;
/* Run time and task stats gathering related definitions. */
#define configUSE_TRACE_FACILITY 1
#define configGENERATE_RUN_TIME_STATS 1
#define configUSE_STATS_FORMATTING_FUNCTIONS 1
#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() (ulHighFrequencyTimerTicks = 0ul)
#define portGET_RUN_TIME_COUNTER_VALUE() ulHighFrequencyTimerTicks
之前的博客:

使能了宏定义之后,必要完成portCONFIGURE_TIMER_FOR_RUN_TIME_STATS()和portGET_RUN_TIME_COUNTER_VALUE()的定义,那么我们究竟应该如何定义并使用它们呢?
freertos官方网站给了提示(点击这里查看更多):


本次实验采用上面的做法,下面还有一个例子,但是没有上面好用:

现在我使用第一种方式,STM32F429,TIM6基本定时器,产生一个50us周期的中断,进一次中断,计数器的值加1:

由于在进入
/* 第三步:启动FreeRTOS,开始多任务调度,启动成功则不返回 */
vTaskStartScheduler();(在这个函数中调用了portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() )
这个函数之前,定时器计数已经执行计数功能很多次了,为了保证我们的基石相对准确,我们在启动freertos的API函数中将其置零,这也就是为什么那个宏#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() 要这样操作这个计数器ulHighFrequencyTimerTicks=0UL;这样从任务开启时,计数器从零开始计数,而portGET_RUN_TIME_COUNTER_VALUE()是为了得到最后的计数值,可以是一个函数,返回之前用户自定义的计数器的值,也可以直接把那个计数器的值进行宏替换,在uxTaskGetSystemState()函数调用形式如下:

可以知道,我们只是需要这个计数器的值作为右值最后打印显示。(一个比较好的参考,点击这里)-(stack overflow参考)-(博客参考)。
有了前面的铺垫之后,再来说说我们的验证试验:
功能描述:按下K1按键,打印出任务信息,函数如下:
static void vTaskWork(void *pvParameters)
{ uint8_t pcWriteBuffer[]; while()
{ if (key1_flag==)
{
key1_flag=;
/* K1键按下 打印任务执行情况 */ printf("=======================================================\r\n");
printf("任务名 任务状态 优先级 剩余栈 任务序号\r\n");
vTaskList((char *)&pcWriteBuffer);
printf("%s\r\n", pcWriteBuffer); printf("\r\n任务名 运行计数 使用率\r\n");
vTaskGetRunTimeStats((char *)&pcWriteBuffer);
printf("%s\r\n", pcWriteBuffer); /* 其他的键值不处理 */ } vTaskDelay();
}
}
任务一,执行打印,任务二,LED闪烁,任务三,蜂鸣器
static void AppTaskCreate(void)
{ xTaskCreate(vTaskWork, /* 任务函数 */
"vTaskWork", /* 任务名 */
, /* 任务栈大小,单位word,也就是4字节 */
NULL, /* 任务参数 */
, /* 任务优先级*/
&xHandleTaskWork ); /* 任务句柄 */ xTaskCreate( vTaskLed1, /* 任务函数 */
"vTaskLed1", /* 任务名 */
, /* 任务栈大小,单位word,也就是4字节 */
NULL, /* 任务参数 */
, /* 任务优先级*/
&xHandleTaskLED1); /* 任务句柄 */ xTaskCreate( vTaskBeep, /* 任务函数 */
"vTaskBeep", /* 任务名 */
, /* 任务栈大小,单位word,也就是4字节 */
NULL, /* 任务参数 */
, /* 任务优先级*/
&xHandleTaskBeep ); /* 任务句柄 */ }
void vTaskLed1(void *pvParameters)
{
/* 任务都是一个无限,不能返回 */
while()
{
LED3_ON;
/* 阻塞延时,单位ms */
vTaskDelay( );
LED3_OFF;
vTaskDelay( );
}
}
void vTaskBeep(void *pvParameters)
{
/* 任务都是一个无限循环,不能返回 */
while()
{
BEEP_ON;
/* 阻塞延时,单位ms */
vTaskDelay( );
BEEP_OFF;
vTaskDelay( );
}
}
基本硬件初始化:
static void BSP_Init(void)
{
/*
* STM32中断优先级分组为4,即4bit都用来表示抢占优先级,范围为:0~15
* 优先级分组只需要分组一次即可,以后如果有其他的任务需要用到中断,
* 都统一用这个优先级分组,千万不要再分组,切忌。
*/
NVIC_PriorityGroupConfig( NVIC_PriorityGroup_4 ); /* LED 初始化 */
LED_GPIO_Config();
/*串口初始化*/
Debug_USART_Config();
/*按键初始化*/
EXTI_Key_Config();
/*定时器6初始化*/
TIMx_Configuration();
/* 蜂鸣器初始化 */
Beep_GPIO_Config();
}
关于裸机部分的外设初始化配置不再赘述。这样,下载程序之后,LED灯闪烁并且蜂鸣器鸣叫,在按下k1按键时,串口输出如下:

有了这个可以知道,我们512字的任务栈空间实在有点浪费,最后的剩余栈单位也是字。
最后,关于vTaskList((char *)&pcWriteBuffer);vTaskGetRunTimeStats((char *)&pcWriteBuffer);这个缓冲区的大小,官网说的,一个任务,大约40个字节足够,我们取50字节,所以定义的缓冲区大小uint8_t pcWriteBuffer[500];可以足够打印10个任务状态。
FreeRTOS 调试方法(printf---打印任务执行情况)的更多相关文章
- 【RTOS】基于V7开发板的最新版FreeRTOS V10.2.0程序模板,含MDK和IAR,支持串口打印任务执行情况
模板下载: 链接:https://pan.baidu.com/s/1N32Hx7cTbDoRinuzTUB3zw 提取码:6aox 1.MDK使用MDK5.26及其以上版本. 2.IAR使用IAR ...
- 【安富莱专题教程第7期】终极调试组件Event Recorder,各种Link通吃,支持时间和功耗测量,printf打印,RTX5及中间件调试
说明:1.继前面的专题教程推出SEGGER的RTT,JScope,Micrium的uC/Probe之后,再出一期终极调试方案Event Recoder,之所以叫终极解决方案,是因为所有Link通吃. ...
- Linux内核调试方法总结【转】
转自:http://my.oschina.net/fgq611/blog/113249 内核开发比用户空间开发更难的一个因素就是内核调试艰难.内核错误往往会导致系统宕机,很难保留出错时的现场.调试内核 ...
- 【转】Linux内核调试方法总结
目录[-] 一 调试前的准备 二 内核中的bug 三 内核调试配置选项 1 内核配置 2 调试原子操作 四 引发bug并打印信息 1 BUG()和BUG_ON() 2 dump_sta ...
- linux设备驱动程序第四部分:从如何定位oops对代码的调试方法,驱动线
在一个我们谈到了如何编写一个简单的字符设备驱动程序,我们不是神,编写肯定会失败的代码,在这个过程中,我们需要继续写代码调试.在普通c应用.我们经常使用printf输出信息.或者使用gdb要调试程序,然 ...
- Perl的调试方法
来源: http://my.oschina.net/alphajay/blog/52172 http://www.cnblogs.com/baiyanhuang/archive/2009/11/09/ ...
- VxWorks操作系统shell命令与调试方法总结
VxWorks下的调试手段 主要介绍在Tornado集成开发环境下的调试方法,和利用支撑定位问题的步骤.思路. 1 Tornado的调试工具 嵌入式实时操作系统VxWorks和集成开发 ...
- 【安富莱】【RL-TCPnet网络教程】第11章 RL-TCPnet调试方法
第11章 RL-TCPnet调试方法 本章节为大家讲解RL-TCPnet的调试方法,RL-TCPnet的调试功能其实就是通过串口打印实时监控运行状态.而且RL-TCPnet的调试设置比较简单 ...
- Linux内核调试方法总结
Linux内核调试方法总结 一 调试前的准备 二 内核中的bug 三 内核调试配置选项 1 内核配置 2 调试原子操作 四 引发bug并打印信息 1 BUG()和BUG_ON() 2 ...
随机推荐
- 怎么删除桌面右键"打开好桌道壁纸"
“好桌道”是一款优秀的桌面美化工具,其中的子程序“好桌道壁纸”是其重要的组成部分,但是在卸载其子程序“好桌道壁纸”时,往往会在桌面的鼠标右键中残留下“打开好桌道壁纸”项,下面解密通过修改注册表的方式彻 ...
- jQuery数组处理全解
jQuery的数组处理.便捷.功能齐全.最近的项目中用到的比较多,深感实用,一步到位的封装了很多原生JavaScript数组不能企及的功能.最近时间紧迫,今天抽了些时间回过头来看jQuery中文文档中 ...
- perforce 使用教程(zz)
http://www.perforce.com/documentation/perforce_technical_documentation http://blog.csdn.net/brucexu1 ...
- Linux CentOS7 系统目录详解
1.目录结构 2.文件类型 LINUX有四种基本文件系统类型:普通文件.目录文件.连接文件和特殊文件,可用file命令来识别. 普通文件:如文本文件.C语言元代码.SHELL脚本.二进制的可执行文件 ...
- SSH免密码登陆以及穿越跳板机
1. 免密码直连 [user@hostA ~] $ssh hostB STEP1. 在hostA上生成RSA公钥私钥(在~/.ssh/下生成RSA私钥id_rsa,公钥id_rsa.pub) [us ...
- .NET破解之爱奇迪(一)
今天无意中看到了wuhuacong(伍华聪)的专栏,界面写得还是很炫的感觉,于是在广州爱奇迪官网下载一个来试一下——客户关系管理系统.下面是成果: 00.总体把握 里面有Logon窗口(为什么不是Lo ...
- SQL语言 之 事务控制
一.概述 事务是一些数据库操作的集合,这些操作由一组相关的SQL语句组成(只能是 DML 语句),它们是一个有机的整体,要么全部成功执行,要么全部不执行.事务时数据库并发控制和恢复技术的基本单位. 事 ...
- setsockopt之 TCP_KEEPIDLE/TCP_KEEPINTVL/TCP_KEEPCNT
setsockopt之 TCP_KEEPIDLE/TCP_KEEPINTVL/TCP_KEEPCNT /*检测网线非法断开*/ setsockopt(iSockFd, SOL_SOCKET, S ...
- iOS 设置app语言中文,比如 copy中文,拍照按钮cancel 中文
iOS 设置app语言中文,比如 copy中文,拍照按钮cancel 中文 一:如何设置项目中文环境 targets--->Locatization native development reg ...
- input 禁止 复制 粘贴 剪切 操作
1.代码 <Input onCopy={(e)=>{ // 禁止拷贝 e.preventDefault(); }} onPaste={(e)=>{ // 禁止粘贴 e.prevent ...