FreeRTOS操作系统学习——调试与优化

本文介绍了在FreeRTOS中如何优化任务栈空间,包括使用任务使用栈大小检查、调试手段如打印断言和trace、以及如何检测和防止栈溢出。还探讨了如何通过任务统计和更快的定时器来提高性能监控。
摘要由CSDN通过智能技术生成

本文介绍

在FreeRTOS中,我们经常会运用到栈这个技术,我们对某个任务分配空间时,往往不确定分配多大空间的栈。任务拿到分配的栈后,大多数情况下,使用率都达不到80%,为了节省栈空间的开销,我们可以通过查询任务使用到的栈大小,人为的优化栈的大小。

调试

FreeRTOS 提供了很多调试手段:

  • 打印
  • 断言: configASSERT
  • Trace
  • Hook 函数(回调函数)
打印

printf: FreeRTOS 工程里使用了 microlib,里面实现了 printf 函数。我们可以使用printf来输出信息。

断言

一般的 C 库里面,断言就是一个函数:

void assert(scalar expression);

它的作用是:确认 expression 必须为真,如果 expression 为假的话就中止程序。在FreeRTOS里,使用configASSERT(),示例:

void vPortValidateInterruptPriority( void )
{
uint32_t ulCurrentInterrupt;
uint8_t ucCurrentPriority;
/* Obtain the number of the currently executing interrupt. */
ulCurrentInterrupt = vPortGetIPSR();
/* Is the interrupt number a user defined interrupt? */
if( ulCurrentInterrupt >= portFIRST_USER_INTERRUPT_NUMBER )
	{
		/* Look up the interrupt's priority. */
		ucCurrentPriority = pcInterruptPriorityRegisters[ ulCurrentInterrupt ];
		configASSERT( ucCurrentPriority >= ucMaxSysCallPriority );
	}
};
Trace

FreeRTOS 中定义了很多 trace 开头的宏,这些宏被放在系统个关键位置。
它们一般都是空的宏,这不会影响代码:不影响编程处理的程序大小、不影响运行时间。
我们要调试某些功能时,可以修改宏:修改某些标记变量、打印信息等待。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Malloc Hook 函数

编程时,一般的逻辑错误都容易解决。难以处理的是内存越界、栈溢出等。内存越界经常发生在堆的使用过程总:堆,就是使用malloc得到的内存。并没有很好的方法检测内存越界,但是可以提供一些回调函数:

/*
使用 pvPortMalloc 失败时,
如果在 FreeRTOSConfig.h 里配置configUSE_MALLOC_FAILED_HOOK 为 1,会调用:
*/
void vApplicationMallocFailedHook( void );
栈溢出 Hook 函数

在切换任务(vTaskSwitchContext)时调用 taskCHECK_FOR_STACK_OVERFLOW 来检测栈是否溢出,如果溢出会调用:

void vApplicationStackOverflowHook( TaskHandle_t xTask, char * pcTaskName );

检测栈溢出的方法

在这里插入图片描述
在这里插入图片描述

优化

在 Windows 中,当系统卡顿时我们可以查看任务管理器找到最消耗 CPU 资源的程序。在FreeRTOS中,我们也可以查看任务使用CPU的情况、使用栈的情况,然后针对性地进行优化。这就是查看"任务的统计"信息。

栈任务使用情况

在创建任务时分配了栈,可以填入固定的数值比如 0xa5,以后可以使用以下函数查看"栈的高水位",也就是还有多少空余的栈空间:

UBaseType_t uxTaskGetStackHighWaterMark( TaskHandle_t xTask );

在这里插入图片描述

任务运行时间统计

对于同优先级的任务,它们按照时间片轮流运行:你执行一个 Tick,我执行一个 Tick。
是否可以在Tick中断函数中,统计当前任务的累计运行时间?不行!很不精确,因为有更高优先级的任务就绪时,当前任务还没运行一个完整的Tick就被抢占了。
我们需要比Tick更快的时钟,比如Tick周期时1ms,我们可以使用另一个定时器,让它发生中断的周期时0.1ms甚至更短。使用这个定时器来衡量一个任务的运行时间,原理如下图所示:
在这里插入图片描述

配置流程
#define configGENERATE_RUN_TIME_STATS 1
#define configUSE_TRACE_FACILITY 1
#define configUSE_STATS_FORMATTING_FUNCTIONS 1

初始化更快的定时器:启动调度器时
在这里插入图片描述
在任务切换时统计运行时间

在这里插入图片描述

函数说明

uxTaskGetSystemState:获得任务的统计信息

UBaseType_t uxTaskGetSystemState
( 
TaskStatus_t * const pxTaskStatusArray,
const UBaseType_t uxArraySize,
uint32_t * const pulTotalRunTime 
);

在这里插入图片描述
vTaskList :获得任务的统计信息,形式为可读的字符串。
注意,pcWriteBuffer 必须足够大。

 void vTaskList( signed char *pcWriteBuffer );

信息格式如下
在这里插入图片描述
vTaskGetRunTimeStats:获得任务的运行信息,形式为可读的字符串。
注意, pcWriteBuffer 必须足够大。

void vTaskGetRunTimeStats( signed char *pcWriteBuffer );

信息格式如下
在这里插入图片描述

  • 35
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
FreeRTOS是一个开源的实时操作系统(RTOS),专注于嵌入式系统的开发。它提供了一套简单而强大的API,用于管理任务、调度、内存管理、通信和定时器等功能。如果你想学习FreeRTOS操作系统,下面是一些步骤和资源可以帮助你入门: 1. 了解嵌入式系统和实时操作系统的基本概念:在开始学习FreeRTOS之前,建议你对嵌入式系统和实时操作系统有一定的了解。掌握任务调度、并发性、内存管理和通信等基本概念对于学习FreeRTOS非常重要。 2. 下载和安装FreeRTOS:你可以从FreeRTOS官方网站(www.freertos.org)下载最新版本的FreeRTOS。根据你的目标平台选择合适的版本,并按照相关文档进行安装。 3. 学习FreeRTOS的API:阅读FreeRTOS的官方文档,学习其提供的API和功能。文档中包含了详细的说明、示例代码和应用案例,可以帮助你理解和使用FreeRTOS。 4. 实践编写示例应用:通过编写一些简单的示例应用程序来熟悉FreeRTOS的使用。从创建任务、任务调度、同步和通信等方面开始,逐步扩展你的应用程序,深入理解FreeRTOS的特性和功能。 5. 参考示例代码和案例:FreeRTOS社区中有许多示例代码和案例可以参考,这些示例代码可以帮助你更好地理解FreeRTOS的应用场景和解决方案。 6. 加入社区和论坛:参与FreeRTOS的社区和论坛讨论,与其他开发者交流经验和问题。这样你可以获得更多的支持和指导,加速你的学习过程。 以上是学习FreeRTOS操作系统的一般步骤和建议。希望对你有所帮助!如有更多问题,请随时提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值