CH32V307 指針強(qiáng)轉(zhuǎn)問題

*(uint16_t *)(&cmd.D_len+1+cmd.D_len)=activeParams.ES_Num.Val++;
cmd是一個(gè)結(jié)構(gòu)體,定義時(shí)用到過?__attribute__ ((packed)),比較復(fù)雜,我就不貼出來了。上邊那行代碼在stm32? cubeIDE中編譯后下載到stm32單片機(jī)中沒有問題。CH32V307中編譯無問題,下載到單片機(jī)后,運(yùn)行就進(jìn)?HardFault_Handler。

把代碼改成:? ?

? ? uint8_t *p=&cmd.D_len+1+cmd.D_len;

? ? p[0]=activeParams.ES_Num.byte.LB;

? ? p[1]=activeParams.ES_Num.byte.HB;

運(yùn)行就沒有問題了??礃幼邮侵羔槍ぶ返膶R問題。后來又做測試,發(fā)現(xiàn)?1?如果是1,3,5,都不行,如果是2,4,6,程序可以正常運(yùn)行。

請問:這是兩種內(nèi)核的區(qū)別么?如果我還是想用最開始那種代碼寫,有啥辦法能解決嗎?謝謝!


您好,RISC-V內(nèi)核是不支持非對齊訪問的,你之前那種寫法可能需要改一下。


能具體解釋一下什么情況下算是非對齊訪問嗎?


struct? __attribute__ ((packed))

{

? ?uint8_t a;

? ?uint16_t b;

? ?uint16_t c;

}t;

t.b=30;這算是非對齊訪問嗎?謝謝!


您好,關(guān)于非對齊訪問:如果被訪問的內(nèi)存地址不按照被訪問的數(shù)據(jù)類型的位寬對齊,稱為非對齊訪問。比如int型占4個(gè)字節(jié),則訪問int型數(shù)據(jù)的內(nèi)存地址需要按照4字節(jié)對齊。在進(jìn)行指針轉(zhuǎn)換或使用packed屬性或者編譯選項(xiàng)時(shí)容易發(fā)生非對齊訪問,從而導(dǎo)致alignment fault。你一開始的問題應(yīng)該就是由于上面所說原因?qū)е碌?。?樓回復(fù)上面的訪問也是非對齊訪問,但若按照對應(yīng)的大小訪問,不用指針,編譯器會(huì)進(jìn)行優(yōu)化,因此不會(huì)報(bào)錯(cuò)。


CH32V303,程序無規(guī)律進(jìn)入?HardFault_Handler ,IDE左側(cè)的Debug窗口,只有一個(gè)HardFault_Handler?函數(shù)顯示,并沒有像用程序暫停后,可以看到程序運(yùn)行的上下文,無法分析是什么引起。在網(wǎng)上找資料使用__get_MCAUSE(),查看,都集中在下圖的異常。上面的貼子說是RISV不支持非對齊問,然后編譯還無錯(cuò)誤,在我看來,這能不能算是編譯器自己有bug?我是用高級語言寫程序,對于內(nèi)核確實(shí)不了解,這些關(guān)于對齊的內(nèi)核的特性編譯器自己不能解決么?還需要我自己在寫程序時(shí)保證?如果必須要由我來保證,那我到底要如何寫程序來保證呢? 請沁恒技術(shù)給些建議吧!謝謝!

image.png



如果實(shí)在解決不了,可否用下圖所述的解決方式?目前問題是我不知道引起異常的指令是幾個(gè)字節(jié)長的,mepc加幾要如何確定呢?可有這方面的demo代碼參考嗎?


image.pngimage.png


另外,如果我把單片機(jī)換成沁恒的ARM核的,是不是就不會(huì)存在這種問題了?


您好,HardFault_Handler的排查思路可參考該貼:https://www.cnblogs.com/wchmcu/p/17545931.html



目前項(xiàng)目上遇到困難,迫切希望廠家能提供一些有價(jià)值的支持。我的程序里大量用到強(qiáng)制類型轉(zhuǎn)換,肯請廠家技術(shù)能給我一個(gè)準(zhǔn)確的判斷,如果你們的RISC_V核的單片機(jī)及其編譯器,只要是我用的強(qiáng)制類型轉(zhuǎn)換,就不能保證不進(jìn)入HardFault_Handler,并也無其它解決方法,那我就不費(fèi)勁了,我還是改用arm核的單片機(jī)了,省得在這里互相浪費(fèi)時(shí)間 。


你好,RISCV的匯編指令有如下特點(diǎn)

*(u8*)(addr)=value;????????對應(yīng)sb 地址可以是11結(jié)尾

*(u16*)(addr)=value;????? 對應(yīng)sh 地址不能是11結(jié)尾,可以是10或00,即必須是2字節(jié)對齊

*(u32*)(addr)=value;????? 對應(yīng)sw 地址必須是00結(jié)尾,即必須是4字節(jié)對齊

如果用*(u16*)無法確定后面的地址是否為2字節(jié)對齊,可以先判斷一下,是2字節(jié)就直接用u16寫,不是2字節(jié)對齊就拆成2次,用u8去寫,判斷條件if((u32)addr%2==0)。

簡單點(diǎn)就直接用u8寫2次。



首先需要強(qiáng)調(diào)一點(diǎn)您的代碼在ARM上跑不會(huì)出問題,是因?yàn)锳RM支持非對齊訪問,而RISCV不支持非對齊訪問,其次并不是說在RISCV開發(fā)過程中不能用強(qiáng)轉(zhuǎn),而是需要注意如果是按*(uint16*)兩字節(jié)訪問,那么地址的增量也必須是兩字節(jié),也就是*(uint16_t *)(&cmd.D_len+2+cmd.D_len)=activeParams.ES_Num.Val++;您所說的代碼中的大量強(qiáng)轉(zhuǎn)也需要注意這一點(diǎn)。


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

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