CH57x的32位寄存器的問題

1623554085469005.png

1623554085116158.png

隨便選了個(gè)32位寄存器,LCD的,使用數(shù)據(jù)變量指針指向,沒啥問題,打印都正常。

1623554186116162.png

1623554199182620.png

定義個(gè)測試用的結(jié)構(gòu)體(一開始用的聯(lián)合體,以為聯(lián)合體的問題,結(jié)果結(jié)構(gòu)體一樣的出錯(cuò)),很簡單,賦值卻出錯(cuò)。

RAM賦值.PNG還是同樣的程序,把地址換成RAM 的地址,哎,又好了。證明結(jié)構(gòu)體訪問沒啥問題。

結(jié)構(gòu)體指針.PNG以為結(jié)構(gòu)體不能這樣寫,結(jié)果使用結(jié)構(gòu)體指向,也是正常的。

結(jié)構(gòu)體指針指向變量.PNG然后結(jié)構(gòu)體指向同樣的數(shù)值的變量,不行,就奇了踏馬的怪了。

數(shù)據(jù)指針指向變量.PNG

數(shù)據(jù)變量指針指向又行了。


也不能說不能用結(jié)構(gòu)體寫,我寫了好多個(gè)外設(shè)了,8位16位寄存器用的好好的,USB通訊正常的很。

寫TMR,來個(gè)32位寄存器,就出了這個(gè)問題。

頭都要搞暈了。

不會(huì)匯編,不然去扒keil生成的匯編了,看是不是編譯器優(yōu)化了什么。

官方有無大佬解釋一下?


嘗試按照描述復(fù)現(xiàn), 卻始終沒能復(fù)現(xiàn)樓主問題,

建議直接提供能復(fù)現(xiàn)的工程,包括原始能復(fù)現(xiàn)問題的固件.


發(fā)送到哪個(gè)郵箱?


發(fā)了有段時(shí)間了,有無音信?


大概看了下代碼:

不同表現(xiàn)的代碼是:

????uint32_t?temp?=?0x4000200C;
????TEST_T?*test?=?(TEST_T?*)0x4000200C;
????test->VAL?=?100;

這種寫法本身并沒有問題,至于為什么產(chǎn)生問題,我們看下匯編差異:

//正常
;;;95?????//---------------------------------------------------???
;;;96?????????uint32_t?temp?=?0x4000200C;;
000016??4c0b??????????????LDR??????r4,|L1.68|
;;;97?????????TEST_T?*test?=?(TEST_T?*)0x4000200C;
000018??4625??????????????MOV??????r5,r4
;;;98?????????test->VAL?=?100;
00001a??2064??????????????MOVS?????r0,#0x64
00001c??6028??????????????STR??????r0,[r5,#0]
;;;99?????//----------------------------------------------------??


//不正常
;;;95?????//---------------------------------------------------???
;;;96?????????uint32_t?temp?=?0x4000200C;;
000016??4c0c??????????????LDR??????r4,|L1.72|
;;;97?????????TEST_T?*test?=?(TEST_T?*)0x4000200C;
000018??4625??????????????MOV??????r5,r4
;;;98?????????test->VAL?=?100;
00001a??4629??????????????MOV??????r1,r5
00001c??2064??????????????MOVS?????r0,#0x64
00001e??f7fffffe??????????BL???????__aeabi_uwrite4
;;;99?????//----------------------------------------------------

從匯編結(jié)果上看, 只有最后一句不一樣, 正常的是調(diào)用了STR指令;

而異常的是調(diào)用了一個(gè)函數(shù)__aeabi_uwrite4,

這里,已經(jīng)能基本確確定問題了:

__aeabi_uwrite4 是處理非對齊的 uint32_t 時(shí)候用的,其實(shí)現(xiàn)相當(dāng)于按uint8_t 或者uint16_t去拼數(shù)據(jù), 而32bit的寄存器并不能這樣操作(可以定義一個(gè)uint8_t 的數(shù)組去指向這些寄存器,按uint8_t 寫去測試).


至于為什么你的工程 會(huì)調(diào)用?__aeabi_uwrite4, 經(jīng)查發(fā)現(xiàn),你在你做的頭文件里面,有使用按照1字節(jié)對齊的約束:#pragma pack( 1 ),但是這個(gè)文件后面并沒有恢復(fù) 到默認(rèn)對齊到4字節(jié), 而導(dǎo)致但凡include 你這個(gè)頭文件后的的 結(jié)構(gòu)體定義, 編譯器都會(huì)按照#pragma pack( 1) 的方式處理, 最終編譯時(shí)候 使用了__aeabi_uwrite4 操作test->VAL.



解決方法:

1,#pragma pack( 1 )約束相關(guān)的類型后, 使用#pragma pack( 4 ), 或者#pragma pack() 恢復(fù)默認(rèn)對齊到4字節(jié)

2, 按照下面方式定義 TEST_T

#pragma?pack(?4?)
typedef?struct
{
????uint32_t?VAL;
}TEST_T;
#pragma?pack(?1?)





哦哦,又學(xué)到了新知識(shí)


感謝指導(dǎo)


只有登錄才能回復(fù),可以選擇微信賬號登錄

国产91精品新入口,国产成人综合网在线播放,九热这里只有精品,本道在线观看,美女视频a美女视频,韩国美女激情视频,日本美女pvp视频