CH32V307 例程問題

1、對于Freertos例程,啟動文件里面修改了使用八級嵌套,但是主函數(shù)里面還是采用的NVIC_PriorityGroup_2(還發(fā)現(xiàn)了別的青稞內核處理器這個地方的問題,建議更新下例程)image.png

2、對于INT例程種的Interrupt_Nest八級中斷嵌套例程,手動修改代碼為全使用硬件壓棧,并把觸發(fā)放在while死循環(huán)種,任然可以一直觸發(fā)所有的八級中斷,和手冊描述不符,這里希望作出解釋。image.pngimage.png

您好,感謝你的反饋建議,后續(xù)會對EVT例程進行修改。關于配置中斷系統(tǒng)控制寄存器(INTSYSCR)為0x1f,即配置使能硬件壓棧和中斷嵌套功能,中斷嵌套深度配置為8級, 注意該寄存器位4的介紹:硬件壓棧深度為 3 級,當配置嵌套等級大于 3 級,若該位設置 1,需要將低優(yōu)先級的三級中斷配置為硬件壓棧,高優(yōu)先級配置為軟件壓棧,如下圖。但你的程序中全部配置成了硬件壓棧,因此是有問題的,建議你可以直接參考我們EVT例程,那個是沒問題的。

image.png

?


您好,我的意思是八級嵌套,我全部用硬件壓棧,但是程序能夠正常運行,按道理只支持三級硬件壓棧,這樣沒有問題嗎


你好,根據(jù)我的測試結果,如果您同時觸發(fā)的中斷大于三個會hard fault

比如你有4個中斷ABCD

如果你按照 A進入 A退出 B進入 B退出 C進入 C退出 D進入 D退出

是不會有問題的

如果你按照 A進入 B進入 C進入 C退出 D進入 D退出 B退出?A退出

也不會有問題,因為棧里最多只有ABC或者ABD,一共有三層

但是你如果A進入 B進入 C進入 D進入,那在D進入的時候會有HARDFAULT


向您的這個測試只出發(fā)一個wwdg是不會出問題的


您好,您用的是CH32V307嗎,我這邊只是更改了八級嵌套中斷例程,全部改成了硬件中斷,但是測試時正常運行,不知道為什么。



您好,您說的“但是你如果A進入 B進入 C進入 D進入,那在D進入的時候會有HARDFAULT”,我這邊并不會進入HARDFAULT,而是八級嵌套中斷正常按照順序執(zhí)行。


你好

1.開啟了硬件壓棧之后,所有中斷都會使用硬件壓棧,如果3級嵌套,硬件壓棧滿了,則不會繼續(xù)硬件壓棧,此時如果要繼續(xù)中斷嵌套,則需要高優(yōu)先級的中斷,使用軟件壓棧,防止數(shù)據(jù)丟失。

2.__attribute__((interrupt("WCH-Interrupt-fast")));這個聲明是告訴編譯器,這個中斷不需要軟件壓棧。

3.例程都改為硬件壓棧的聲明,可以正常運行,原因是例程的中斷函數(shù)比較簡單,沒有用到太多通用寄存器,即使沒有保存上下文,也可以正常運行,如果代碼復雜一點,就會運行混亂。


也就是說,我測試出來的hard fault不是因為壓棧壓不進去觸發(fā)的,而是壓棧沒壓進去,然后恢復現(xiàn)場的時候恢復了一坨不知道是什么東西的東西到寄存器組里,然后因為這一坨異常的數(shù)據(jù)觸發(fā)的hardfault




image.png

V307 八級中斷全硬件壓棧,逐個分析了進中斷前的寄存器值和退出中斷后的寄存器值,不知道是不是使用的官方里程簡單,從上圖分析出,返回寄存器ra的值,在第八級中斷退出的前5次中,一直沒有更新,始終是第八級中斷退出的地方,但是sp和fp還是會正常更新,逐步返回到前一級的硬件壓棧值,個人這里有兩種猜測:

第一種:可能是中斷嵌套例程太簡單,沒有干涉到sp和fp寄存器,但是個人覺得這種猜測不合理;

第二種:就是硬件壓棧的時候,超過硬件壓棧三級后,對于ra寄存器,在最后一級中斷退出時,每退一次,重復賦值自身ra值,直到退到嵌套次數(shù)小于等于三次后,再次退出時,就開始賦值第二級嵌套的ra值,第二級嵌套退出時,賦值第一級嵌套的ra值,這樣退出下去。個人感覺有點不是很合理,就是為什么sp和fp寄存器的值能夠保存,但是ra寄存器的值,卻沒有,這個地方是內核設計的時候,就設計成超過最大壓棧次數(shù)后,最后一級中斷退出的時候重復更新自身ra值,直到嵌套深度小于等于三級壓棧。

上述也只是個人的一個猜測,本人不是IC設計行業(yè)的,也只能根據(jù)現(xiàn)象來反推和猜測了,如有錯誤,您指出并回復即可。


以下是V307 四級中斷全硬件壓棧的進出棧寄存器分析,確實能過夠得出第二種結論,再第四級中斷退出時,由于超過了最大三級硬件壓棧次數(shù),因此更新自身ra值,但是sp和fp還是屬于正常更新,之后由于嵌套深度為三級,因此再次退出時,可以正常更新ra值,之后就是順利的退出過程。

image.png


你好

代碼里會操作這些寄存器,需要配合匯編指令去分析,mret指令是中斷退出的指令,寄存器mepc存放著mret的下一條指令地址。

如果想研究壓棧出棧時的變化,可以在反匯編的窗口,在mret和mepc的位置打上斷點,在執(zhí)行mret前,修改通用寄存器的值,然后執(zhí)行到下一條指令的時候,查看通用寄存器的變化,從而反推硬件壓棧和軟件壓棧的不同之處。


您說的這個,我看了反匯編,懂您說的意思。

但是,我上面那個問題,您可以再仔細回答下么。


你好,我暫時看不懂你的問題,只能談談我的理解。

sp是堆棧的指針,在不斷的加加減減,自己就在不斷更新,這里就一個堆棧,所以不需要保存。

fp不大了解,看匯編中的行為,像是對變量尋址用的,也在頻繁的使用,并且有和堆棧交互的痕跡。

ra是函數(shù)調用的返回地址,在調用函數(shù)的時候之前會修改,所以需要在壓棧出棧的時候進行操作,否則就丟失了。


您好,這個問題,可能需要設計這個內核的來回答一下,也很感謝您的耐心解答。

這個問題關鍵點在于,硬件壓棧到出棧,為什么溢出后,在逐級退出的時候,對于溢出的那幾級,從現(xiàn)象上看是重復最后那級的ra值,而退到三級(包含三級)以內后,又能夠正確的出棧ra值,這個可能需要設計這個內核的人來解釋下。


額外說明:

對于說程序進hardfault,這里個人給出一種猜測,如果配置了大于三級的硬件壓棧,在這種情況下,介于最高級和三級中間那幾級里面的程序并沒有正常執(zhí)行完,因此,可能導致最后退回到主程序里面時,出現(xiàn)問題,從而進入hardfault。


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

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