freertos程序死机原因

本文探讨了实时操作系统(RTOS)中遇到的任务栈溢出和堆溢出问题,分析了导致这两种情况的原因,并提供了相应的调试方法。栈溢出主要由于任务函数过大或局部变量数组过占空间,而堆溢出则可能源于全局变量或大内存分配。解决策略包括减小任务规模、使用固定大小数组和常量优化,以及调整堆栈大小。通过示例代码展示了如何定位并修复栈溢出问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、开机死机原因

1.一般是某任务栈溢出所致
栈溢出一般有两个原因:

1).此任务函数的代码量太大,或调用了某个比较大的函数。
2).此任务的函数内有比较大的局部变量的数组

调试方法:

1、先关闭所有任务再逐个打开,确定哪个任务导致的死机
2、先看看有没有较大的数据,再用水印函数看看函数的剩余栈。
uxTaskGetStackHighWaterMark(Task_sendModebuHandle )
创建任务的使用说明
一般栈要开的大一些 大于500,正常printf()函数打印时会占用很大ram(打印全局变量时会占用400左右,打印常量时很少 40)

举例:打开此任务函数时死机,原因是 uint8_t buff[1050]太大栈溢出所致

  osThreadDef(Task_sendModebu, sevSendModebus, osPriorityLow, 0, 256);
  Task_sendModebuHandle = osThreadCreate(osThread(Task_sendModebu), NULL);
void sevSendModebus(void const *argument){
	osEvent osSendBusEvent;
	uint8_t buff[1050]={0,};
    printf_pub_var("sevSendModebus(void const * argument) 初始化结束 \r\n");
	while(1){	  
			osSendBusEvent = osMessageGet(allSendBusQHandle, portMAX_DELAY);
			if(osEventMessage==osSendBusEvent.status){//判断是否为有效消息				dataPro(buff); 
		  }
	}
}	

2.一般是堆溢出所致

1.解决方法:全局变量数组或者任务开的太大了,申请melloc大内存 解决办法:
任务调小一点或固定值的数组+const;

 ram(堆)要是不够用,可以把一些常量数组值前+const(有些单片机会把常量放进flash而不是ram)

2:调试方法 (查看栈的使用情况)
xPortGetFreeHeapSize()
API函数在调用该函数时返回堆中的空闲字节数。它可以用来优化堆大小。例如,如果在创建了所有内核对象之后,xPortGetFreeHeapSize()返回2000,那么configTOTAL_HEAP_SIZE的值可以减少2000。当使用heap_3时,xPortGetFreeHeapSize()不可用。

xPortGetMinimumEverFreeHeapSize()
API函数返回自FreeRTOS应用程序开始执行以来堆中存在的最小未分配字节数。xPortGetMinimumEverFreeHeapSize()仅在使用heap_4或heap_5时可用

3.还有一种情况是系统栈溢出所致
系统栈是指 中断函数和中断嵌套所占用的栈大小。

这是最麻烦的一种死机难调试的情况(没有查看系统栈使用情况的接口)。
测试办法:
1:直接把系统栈变大看是否变好
2:在ram 系统栈的范围开机前先赋值 动态看被改变的地址确定系统栈最大使用多少空间

详细说明
在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

非洲WIP56

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值