FreeRtos下创建任务失败原因记录
一 问题背景
使用stm32f103 + freertos创建三个任务,如下:程序运行不正常,经过debug,发现第三个任务KeyTask没有创建成功。原因呢大概率是栈空间不够,通过将三个任务的栈传参都改成128,发现三个任务均创建成功,那么确认是栈空间不足导致。最终修改方法是将宏configTOTAL_HEAP_SIZE 由3072改为4096。但是有个疑问,为什么栈空间不足,要修改堆大小?本文即看了一些资料后,有了个认识,做个总结
osThreadDef(mail_station, mail_station_task, osPriorityNormal, 0, 128);mail_stationHandle = osThreadCreate(osThread(mail_station), NULL);/* definition and creation of TaskDisplay */osThreadDef(TaskDisplay, displayTask, osPriorityNormal, 0, 256);TaskDisplayHandle = osThreadCreate(osThread(TaskDisplay), NULL);/* definition and creation of TaskKey */osThreadDef(TaskKey, keyTask, osPriorityNormal, 0, 256);TaskKeyHandle = osThreadCreate(osThread(TaskKey), NULL);
二 栈和堆的差别
栈特点
- 自动分配释放,编译器管理
- 连续内存,栈访问更快
- 生命周期函数调用结束即销毁
- 一般用于局部变量,函数传参,函数返回值
- 无内存碎片
- 每个线程有独立的栈
堆特点
- 手动分配malloc,手动释放free,操作不当可能内存泄漏
- 通常空间更大,但是分配不连续,通过链表管理
- 若定义全局指针引用,则可跨函数存在
- 频繁分配释放可能造成内存碎片—明明有内存,但是无法分配大内存
三 freertos下堆内存管理
freertos提供了多种堆内存分配算法,分别存放于heap1.c~heap5.c几个文件中,每个文件各放了一种分配方案;stm32CubeIDE freertos中间件默认采用的是heap4方案,该方案在嵌入式场景中更加通用,可动态分配且有碎片化管理。
在配置文件中,configTOTAL_HEAP_SIZE定义了系统堆内存的大小;如果任务创建采用动态分配,那么每个任务的任务栈,其实也是从系统堆里面分配的。所以当你创建任务越多,分配的任务栈越多,那么加起来就可能造成系统堆空间不够用,这个时候我们就应该增加系统堆内存大小。