轉載自:http://blog.chinaunix.net/uid-21977330-id-3209252.html
1. 問題描述:
當使用uocs printf(),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指定對齊字節數
#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];
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對齊的問題。