概述
一、sprintf浮点数问题
最近遇到了一个问题,就是ucosii中浮点数调用printf显示不正常,但是裸机上对浮点数支持正常,以下是详细情况。pragma data_alignment
在ucos中调用printf调试浮点数的时候,在内存中表示正确,但是打印数据就都为0.00,其他整形数据表示正常。
定义了一个float类型的变量i,在内存中的数据是这样的,如下图所示:
但是当调用printf打印的时候,会发现打印结果是这样的:
在裸机上的运行结果是完全正常的,也就是说问题是出在ucos上。
经查资料得知,这是由于用户任务堆栈没有八字节对齐导致的,运行裸机程序时,系统的默认堆栈式八字节对齐的,但是ucos的用户任务堆栈就不是这样了。
将用户堆栈八字节对齐即可。
解决方案:
1、IAR下的解决方案:
通过#pragma data_alignment指定对齐字节数
例如:
#pragma data_alignment=8
OS_STK Task1_LED1_Stk[Task1_LED1_Stk_Size];
#pragma data_alignment=8
OS_STK Task2_backlight_Stk[Task2_backlight_Stk_Size];
2、Keil MDK下的解决方案:
在任务堆栈声明前面加入强制八字节对齐命令,如下:
__align(8) static OS_STK TaskEquipmentStk[TASK_EQUIPMENT_STK_SIZE]; //任务堆栈
__align(8) static OS_STK TaskUartRcvStk[TASK_UARTRCV_STK_SIZE];
__align(8) static OS_STK TaskFileRcvStk[TASK_FILERCV_STK_SIZE];
__align(8) static OS_STK TaskFtpStk[ TASK_FTP_STK_SIZE ];
__align(8) static OS_STK TaskErrorRateRS485Stk[ TASK_ERROR_RATE_RS485_STK_SIZE ];
原因详解
这事儿的历史在于ARM本身不支持非对齐数据存取;因此在有了64Bit的数据操作指令后,指令要求8字节对齐。
进而,在编译器的某个版本之后(RVCT3?),AAPCS就要求堆栈8字节对齐。
是先有8字节对齐的AAPCS,然后才有的CM3。先后顺序要注意。CM3 r2p0之前,自动压栈也不要求8对齐,r2p0好像才是强制对齐的。
printf的8对齐是C运行库要求的,和硬件无关,C RTL手册有写,可以去阅读。其根源在于AAPCS要求;而AAPCS根源在于LDRD这类指令。pragma data_alignment
换句话,未来如果128Bit数据操作有了,ARM还不支持非对其,那AAPCS可能升级为16字节对齐。
二、功能比较
消息队列可以存放多个消息,可以设置先进先出或者后进先出,但是需要控制好时序,因为不能像信号量集一样去滤波(识别)信号。
邮箱进行传递单一数据,但是有指向性,可利用性好;
信号量使用时,在累增,只能通过非0来进行动作;信号量集则是通过16位数据的对应值来进行识别;
三、堆栈异常
尽量避免将空的指针数据进行循环;
最后
以上就是痴情石头为你收集整理的UCOSII移植问题-IAR的全部内容,希望文章能够帮你解决UCOSII移植问题-IAR所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复