一、开机死机原因
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 系统栈的范围开机前先赋值 动态看被改变的地址确定系统栈最大使用多少空间