最近使用keil开发STM32,跑ucos操作系统时,串口使用printf()函数打印浮点型(float)数值,总是出错,无法打印等,但是没有加载操作系统时候,printf()函数正常。
查询资料,发现主要有以下2个原因(第二个原因尤其需要注意):
1、μcos操作系统是使用自己的任务堆栈来管理任务的上下文切换,堆栈空间可能不足以支持printf()函数所需要的堆栈帧大小,这可能导致堆栈溢出或者堆栈损坏,并导致异常。
解决方法:增加任务的堆栈大小。可以在创建任务时使用OSTaskCreate()
函数的第二个参数来指定堆栈大小。增加堆栈大小可能会占用更多的RAM,因此需要权衡资源利用率和堆栈要求。一般推荐堆栈大小为128、256、512等。
2、当没有操作系统时,系统堆栈是8字节对齐的;但是使用ucos系统时,用户任务不一定是8字节对齐,故需要使用__align(8)将任务堆栈按照8字节强制对齐。
作用是:着每个任务堆栈单元都将按照8字节边界对齐存储。这样做的目的是满足某些数据类型(如浮点数,64位整数等)的对齐要求。
解决如图:
/* stack size define */
#define APP_TASK_START_STK_SIZE 512
#define APP_TASK_1_STK_SIZE 512
#define APP_TASK_2_STK_SIZE 512
#define APP_TASK_3_STK_SIZE 512
#define APP_TASK_4_STK_SIZE 512
#define APP_TASK_5_STK_SIZE 512
#define APP_TASK_6_STK_SIZE 512
/* STACKS stack define */
__align(8) static CPU_STK AppTaskStartStk[ APP_TASK_START_STK_SIZE ];
__align(8) static CPU_STK AppTask1Stk [ APP_TASK_1_STK_SIZE ];
__align(8) static CPU_STK AppTask2Stk [ APP_TASK_2_STK_SIZE ];
__align(8) static CPU_STK AppTask3Stk [ APP_TASK_3_STK_SIZE ];
__align(8) static CPU_STK AppTask4Stk [ APP_TASK_4_STK_SIZE ];
__align(8) static CPU_STK AppTask5Stk [ APP_TASK_5_STK_SIZE ];
__align(8) static CPU_STK AppTask6Stk [ APP_TASK_6_STK_SIZE ];
参考: