UCOS系统使用
问题1:printf打印浮点型数据问题
在不使用UCOS系统的时候,pirntf和以很正常的打印整型,短整型,浮点型类的数据,但是在使用UCOS系统之后,printf打印整型和短整型数据还是没有问题的,但是打印浮点型数据的时候就会出现很严重的问题,乱码。经过分析与资料查找,得知,硬件堆栈的数据对齐方式是8位的,但是如果使用UCOS的话,每个任务都有自己的任务堆栈,这些堆栈的对齐方式可不是8位的,但是printf读取浮点型数据的时候是以8位对齐的方式来读取的,因此在打印UCOS系统下的浮点型数据的时候机会出现严重的乱码问题。
以下实在网络上收集的资料,以及解决的办法:
1. 问题描述:
当使用uocsprintf(),sprintf()打印浮点数问题会出问题,但是裸机不会出问题
我现在使用STM32跑UCOS,在使用sprintf打印float类型时候,不管是何值最后都是0.0,但是类型是int,short类型时没有问题。网上查到是任务堆栈8字节对齐就可以了。
当没有操作系统时,系统堆栈是8字节对齐的,但是当使用ucos时,用户任务不一定是8字节对齐.
Task1-LED1 中的堆栈起始指针0x200004A4,不是8字节对齐,所以但在Task-LED1任务中调用printf等系列函数就会出现问题.
2. 解决方法
我用的是IAR,通过#pragma data_alignment指定对齐字节数
#pragmadata_alignment=8
OS_STK Task1_LED1_Stk[Task1_LED1_Stk_Size];
#pragmadata_alignment=8
OS_STKTask2_backlight_Stk[Task2_backlight_Stk_Size];
3. 8字节对齐原因
这事儿的历史在于ARM本身不支持非对齐数据存取;因此在有了64Bit的数据操作指令后,指令要求8字节对齐。进而,在编译器的某个版本之后(RVCT3?),AAPCS就要求堆栈8字节对齐。
是先有8字节对齐的AAPCS,然后才有的CM3。先后顺序要注意。CM3 r2p0之前,自动压栈也不要求8对齐,r2p0好像才是强制对齐的。
printf的8对齐是C运行库要求的,和硬件无关,C RTL手册有写,可以去阅读。其根源在于AAPCS要求;而AAPCS根源在于LDRD这类指令。
换句话,未来如果128Bit数据操作有了,ARM还不支持非对其,那AAPCS可能升级为16字节对齐。
供参考,CM3和C-RTL对齐的问题。
问题2:include.h 和 uc_global.h文件问题
该问题我已经在原子的论坛上发表了一次,有个人自己的分析http://www.openedv.com/posts/list/0/49136.htm?privmsg=32560&&sysid=4#281258
问题3:内存块定义不当导致循环中断错误(有网上资料得知循环中断错误一般是由数组等的溢出导致的)
当时的情况;
这里是建立了一个内存管理创建函数,但是这个在编译的时候虽然是没有说明错误,然而在使用的时候直接就会到至程序运行到中断死循环。导致这个的原因网上说是数组一类的东西溢出,我查找了半天还是没有结果,创建内存块是要给消息队列使用的,因此我最后找到了内存块的身上,之后我进行了这样的修改:
只是将数组的建立从函数的内部放到了函数的外部,经过分析我大概的知道是这么个回事。我门都知道,在函数内部创建的变量数组等等,在其所在的函数运行完毕之后它们所占有的内存就会被释放掉,然而,我门要创建内存块就是希望不要释放而是一直使用,因此,当我门调用获取一个存储块使用的时候就会导致错误,因为我门申请的内存在这个函数运行完毕之后已经释放掉了,因此我门要将数组创建在函数的外部,这样这个内存区域就不会内释放掉了。