ARM上移植實時操作系統大家可能比較熟悉,且例程較多,對于RISC-V內核的單片機,可能相對比較陌生。下面結合WCH沁恒微電子的赤菟V103(CH32V103)和赤菟V307(CH32V307)兩款RISC-V內核芯片來詳細說下針對RISC-V平臺,移植實時操作系統的注意點。
之所以選擇赤菟V103和赤菟V307兩個芯片主要是其極具代表性:首先,直觀上其外設的使用方法和我們之前熟悉的F103,F107等是兼容的,這樣降低了我們使用和移植時的難度,基于WCH提供的外設庫,我們以前上層的代碼甚至于不用修改可直接使用。其次,赤菟V103是WCH RISC-V青稞內核家族中的青稞V3A內核,V307為青稞V4F內核,青稞V3內核支持RV32IMAC指令集,即除支持RISC-V基本的32位整數指令集外,還支持硬件乘除法,原子指令,壓縮指令。青稞V4F在青稞V3A的基礎上增加了單精度硬件浮點,并且其性能也比青稞V3A高。除此所有的青稞V4內核還支持自定義壓縮指令-XW擴展,包括以下指令c.lbu/c.lhu/c.sb/c.sh/c.lbusp/c.lhusp/c.sbsp/c.shsp。
這里需要注意的是一般情況下,移植RTOS的時需要關閉硬件壓棧,因為在切換任務時,我們希望自己控制出棧入棧的內容。但是針對青稞V4F核,CSR 0x804中有增加控制位(bit5)GIHWSTKNEN(全局中斷和硬件壓棧關閉使能),可以進中斷時置位該位,關閉中斷和硬件壓棧,我們手動保存當前線程棧,恢復新線程棧,中斷mret返回后,硬件自動清除該位,恢復中斷和硬件壓棧使能。這樣即可保證RTOS下,硬件壓棧可正常使用,保證RTOS下的中斷響應速度。
今天聊下需要移植RTOS時RISC-V內核單片機 需要保存的寄存器 。
RISC-V寄存器如下圖1所示,其中x0-x31為整形寄存器,f0-f31為浮點寄存器(青稞V3沒有浮點寄存器)。 所有帶caller的寄存器,當發生中斷時需要保存,值得注意的是,WCH的硬件壓棧保存的寄存器僅僅保存整數的16個caller saved 寄存器。 正常一個中斷函數的寄存器保存我們不用關心,編譯器會幫我們做的很好。 但是當我們從一個匯編入口進中斷函數的時候這些過程就不得不由我們自己來實現。 寄存器中幾個相對特殊的x0恒為0,x1是返回地址寄存器ra,函數調用時用來存放返回地址,x2為堆棧指針sp,x3為gp全局指針,用來尋址全局變量。
圖1 RISC-V寄存器
RISC-V內核進中斷需要保存caller saved(顧名思義,調用者需要保存)的寄存器。 當不開啟硬件浮點時,編譯器會把16個寄存器在中斷函數開始時存入堆棧,中斷返回前恢復,如下圖2和圖3所示。 我們內核支持硬件壓棧,硬件保存和恢復的也正是這16個寄存器。 使用硬件壓棧時需要使能硬件功能,即硬件壓棧使能(不同芯片配置位置不同,詳見手冊中斷章節),同時也需要通知編譯器不自動生成圖2和圖3中的軟件出入棧的代碼,即在MRS聲明中斷函數時由__attribute__((interrupt("WCH-Interrupt-fast")))方式定義編譯器不自動添加軟件出入棧代碼, 由__attribute__((interrupt()))方式定義編譯器添加軟件出入棧的代碼。
圖2 整形寄存器入棧
圖3 整形寄存器出棧
當開啟硬件壓棧并且編譯器中聲明使用硬件壓棧后,中斷函數匯編代碼如下圖4所示。 可見進入中斷后直接執行的中斷代碼,形如圖2和圖3中的16個寄存器的入棧和出棧由硬件在中斷開始和結束時自動完成。 同時也可以看出整個中斷函數可以減少34條指令。
圖4 開啟硬件壓棧后中斷函數匯編代碼
由此也可知道前文說的一般中斷切換上下文時不開啟硬件壓棧的原因:開啟后中斷返回時硬件會復寫16個caller saved寄存器。
當開啟硬件浮點時,除了上述16個整形還會增加20個浮點寄存器,如下圖5所示。 由此也可以看出,硬件壓棧只對整形的寄存器生效。
圖5 浮點寄存器出入棧
-
單片機
+關注
關注
6035文章
44554瀏覽量
634650 -
ARM
+關注
關注
134文章
9084瀏覽量
367386 -
RTOS
+關注
關注
22文章
811瀏覽量
119595 -
實時操作系統
+關注
關注
1文章
197瀏覽量
30753 -
RISC-V
+關注
關注
45文章
2270瀏覽量
46129
發布評論請先 登錄
相關推薦
評論