Cortex-M與RISC-V區別

環境

Cortex-M以STM32H750為代表,RISC-V以芯來為代表

RTOS版本為RT-Thread 4.1.1


寄存器

在這里插入圖片描述


RISC-V

在這里插入圖片描述


常用匯編

RISC-V

關于STORE x4, 4(sp)這種寄存器前面帶數字的寫法,其意思為將x4的值存入sp+4這個地址,即前面的數字表示偏移的意思

反之LOAD表示從內存里面取值

la

地址加載 (Load Address). 偽指令(Pseudoinstruction), RV32I and RV64I.

la rd, symbol x[rd] = &symbol

例如將函數irq_entry()的地址放入t0中

la t0, irq_entry

mv

移動(Move). 偽指令(Pseudoinstruction), RV32I and RV64I.

mv rd, rs1 x[rd] = x[rs1]

把寄存器 x[rs1]復制到 x[rd]中。實際被擴展為 addi rd, rs1, 0

addi

加立即數(Add Immediate). I-type, RV32I and RV64I.

把符號位擴展的立即數加到寄存器 x[rs1]上,結果寫入 x[rd]。忽略算術溢出。

addi rd, rs1, immediate x[rd] = x[rs1] + sext(immediate)

add

加 (Add). R-type, RV32I and RV64I.

把寄存器 x[rs2]加到寄存器 x[rs1]上,結果寫入 x[rd]。忽略算術溢出。

add rd, rs1, rs2 x[rd] = x[rs1] + x[rs2]

壓縮形式:c.add rd, rs2; c.mv rd, rs2

Cortex-M


中斷與異常處理

中斷與異常入口

Cortex-M

Cortex-M在啟動文件中會初始化一個中斷向量表,所有的異常和中斷根據這個表的地址跳轉

; Vector Table Mapped to Address 0 at ResetAREA    RESET, DATA, READONLYEXPORT  __VectorsEXPORT  __Vectors_EndEXPORT  __Vectors_Size__Vectors       DCD     __initial_sp                      ; Top of StackDCD     Reset_Handler                     ; Reset HandlerDCD     NMI_Handler                       ; NMI HandlerDCD     HardFault_Handler                 ; Hard Fault HandlerDCD     MemManage_Handler                 ; MPU Fault HandlerDCD     BusFault_Handler                  ; Bus Fault HandlerDCD     UsageFault_Handler                ; Usage Fault HandlerDCD     0                                 ; ReservedDCD     0                                 ; ReservedDCD     0                                 ; ReservedDCD     0                                 ; ReservedDCD     SVC_Handler                       ; SVCall HandlerDCD     DebugMon_Handler                  ; Debug Monitor HandlerDCD     0                                 ; ReservedDCD     PendSV_Handler                    ; PendSV HandlerDCD     SysTick_Handler                   ; SysTick Handler; External InterruptsDCD     WWDG_IRQHandler                   ; Window WatchDog interrupt ( wwdg1_it)                                         DCD     PVD_AVD_IRQHandler                ; PVD/AVD through EXTI Line detection       

RISC-V

RISC-V的異常會跳入所有異常共享的異常處理程序入口mtvec,在啟動文件中的初始化如下:

exc_entry由匯編編寫,其中又會調用core_exception_handler()

    /** Set Exception Entry MTVEC to exc_entry* Due to settings above, Exception and NMI* will share common entry.*/la t0, exc_entrycsrw CSR_MTVEC, t0

ECLIC 的每個中斷源均可以設置成向量或者非向量處理(通過寄存器 clicintattr[i]的 shv 域),其要點如下:

當 mtvec.MODE != 6’b000011 時,處理器使用默認中斷模式

mtvec.MODE = 6’b000011 時,處理器使用ECLIC 中斷模式,推薦使用此模式。

    /* Set the interrupt processing mode to ECLIC mode */la t0, 0x3fcsrc CSR_MTVEC, t0csrs CSR_MTVEC, 0x3
  • 如果被配置成為向量處理模式,則該中斷被處理器內核響應后,處理器直接跳入該中斷的向量入口(Vector Table Entry)存儲的目標地址

  • 如果被配置成為非向量處理模式,則該中斷被處理器內核響應后,處理器直接跳入所有中斷共享的入口地址

    默認情況下異常和所有非向量中斷共享入口地址(不推薦),推薦將 CSR 寄存器 mtvt2 的最低位設置為 1,則所有非向量中斷共享的入口地址由 CSR 寄
    存器 mtvt2 的值(忽略最低 2 位的值)指定

    /** Set ECLIC non-vector entry to be controlled* by mtvt2 CSR register.* Intialize ECLIC non-vector interrupt* base address mtvt2 to irq_entry.*/la t0, irq_entrycsrw CSR_MTVT2, t0csrs CSR_MTVT2, 0x1
    

進入irq_entry后會自動關閉中斷MIE

保存完上下文之后會調用對應中斷服務程序,在跳入中斷服務程序的同時,硬件也會同時打開中斷的全局使能

中斷服務程序執行完成之后需要將中斷全局使能再次關閉,保證恢復上下文的原子性

MPIE會記錄異常發生前得MIE值,以便異常結束時恢復到原來的值

csrrw ra, CSR_JALMNXTI, ra

在跳入中斷服務程序的同時,“csrrw ra, CSR_JALMNXTI, ra”指令還會達到 JAL(Jump and Link)的效果,硬件同時更新 Link 寄存器的值為該指令的 PC 自身作為函數調用的返回地址。因此,從中斷服務程序函數返回后會回到該“csrrw ra,CSR_JALMNXTI, ra”指令重新執行,重新判斷是否還有中斷在等待(Pending),從而達到中斷咬尾的效果。如果沒有中斷在等待(Pending),則該指令相當于是個 Nop 指令不做任何操作。

對于中斷嵌套,會重新從irq_entry進入


保存上下文

Cortex-M

當Cortex-M開始響應一個中斷時,會自動完成如下操作:

  • 入棧: 自動把8個寄存器的值壓入棧

  • 取向量:從向量表中找出對應的服務程序入口地址

  • 選擇堆棧指針MSP/PSP,更新堆棧指針SP,更新連接寄存器LR,更新程序計數器PC

響應異常的第一個行動,就是自動保存現場的必要部分:依次把xPSR, PC, LR, R12以及R3‐R0由硬件自動壓入適當的堆棧中:如果當響應異常時,當前的代碼正在使用PSP,則壓入PSP,即使用線程堆棧;否則壓入MSP,使用主堆棧。一旦進入了服務例程,就將一直使用主堆棧。

壓棧順序如下:

地址(設原SP為 N-0)寄存器被保存的順序
N-4xPSR2
N-8PC1
N-12LR8
N-16R127
N-20R36
N-24R25
N-28R14
N-32 (新SP也指向這里)R03

RISC-V

RISC-V 架構的處理器在進入和退出中斷處理模式時沒有硬件自動保存和恢復上下文(通用寄存器)的操作,因此需要軟件明確地使用(匯編語言編寫的)指令進行上下文的保存和恢復。根據中斷是向量處理模式還是非向量處理模式,上下文的保存和恢復涉及到的內容會有所差異

在上述異常exc_entry和中斷irq_entry中,都有SAVE_CONTEXTRESTORE_CONTEXT來保存上下文和恢復上下文

.macro SAVE_CONTEXTcsrrw sp, CSR_MSCRATCHCSWL, sp/* Allocate stack space for context saving */addi sp, sp, -20*REGBYTESSTORE x1, 0*REGBYTES(sp)STORE x4, 1*REGBYTES(sp)STORE x5, 2*REGBYTES(sp)STORE x6, 3*REGBYTES(sp)STORE x7, 4*REGBYTES(sp)STORE x10, 5*REGBYTES(sp)STORE x11, 6*REGBYTES(sp)STORE x12, 7*REGBYTES(sp)STORE x13, 8*REGBYTES(sp)STORE x14, 9*REGBYTES(sp)STORE x15, 10*REGBYTES(sp)STORE x16, 14*REGBYTES(sp)STORE x17, 15*REGBYTES(sp)STORE x28, 16*REGBYTES(sp)STORE x29, 17*REGBYTES(sp)STORE x30, 18*REGBYTES(sp)STORE x31, 19*REGBYTES(sp)
.endm.macro RESTORE_CONTEXTLOAD x1, 0*REGBYTES(sp)LOAD x4, 1*REGBYTES(sp)LOAD x5, 2*REGBYTES(sp)LOAD x6, 3*REGBYTES(sp)LOAD x7, 4*REGBYTES(sp)LOAD x10, 5*REGBYTES(sp)LOAD x11, 6*REGBYTES(sp)LOAD x12, 7*REGBYTES(sp)LOAD x13, 8*REGBYTES(sp)LOAD x14, 9*REGBYTES(sp)LOAD x15, 10*REGBYTES(sp)LOAD x16, 14*REGBYTES(sp)LOAD x17, 15*REGBYTES(sp)LOAD x28, 16*REGBYTES(sp)LOAD x29, 17*REGBYTES(sp)LOAD x30, 18*REGBYTES(sp)LOAD x31, 19*REGBYTES(sp)addi sp, sp, 20*REGBYTEScsrrw sp, CSR_MSCRATCHCSWL, sp
.endm

還有SAVE_CSR_CONTEXTRESTORE_CSR_CONTEXT來保存和恢復這三個MCAUSE MEPC MSUBMCSR寄存器

例如下面的第一條命令表示把MCAUSE存到SP+11*4的位置,正好上面留了三個位置給CSR寄存器

/*** \brief  Macro for save necessary CSRs to stack* \details* This macro store MCAUSE, MEPC, MSUBM to stack.*/
.macro SAVE_CSR_CONTEXT/* Store CSR mcause to stack using pushmcause */csrrwi  x5, CSR_PUSHMCAUSE, 11/* Store CSR mepc to stack using pushmepc */csrrwi  x5, CSR_PUSHMEPC, 12/* Store CSR msub to stack using pushmsub */csrrwi  x5, CSR_PUSHMSUBM, 13
.endm.macro RESTORE_CSR_CONTEXTLOAD x5,  13*REGBYTES(sp)csrw CSR_MSUBM, x5LOAD x5,  12*REGBYTES(sp)csrw CSR_MEPC, x5LOAD x5,  11*REGBYTES(sp)csrw CSR_MCAUSE, x5
.endm

棧指針的切換

Cortex-M

Cortex-M有主棧MSP和線程棧PSP自動切換,默認是使用的MSP,那么疑問來了,怎么使用線程棧呢?

PendSV_Handler   PROC
switch_to_threadLDR     r1, =rt_interrupt_to_threadLDR     r1, [r1]LDR     r1, [r1]                ; load thread stack pointerLDMFD   r1!, {r4 - r11}         ; pop r4 - r11 registerMSR     psp, r1                 ; update stack pointerpendsv_exit; restore interruptMSR     PRIMASK, r2ORR     lr, lr, #0x04BX      lrENDP

在線程切換的時候,會把線程的sp——rt_interrupt_to_thread賦給psp

在進入異常服務程序后,LR的值被自動更新為特殊的EXC_RETURN,所以只需要在異常中將LR的bit2置1就可以切換PSP了

EXC_RETURN會根據進入異常前的模式和SP使用情況生成(保持進入異常前的值),理論上只用第一次線程切換時手動把MSP改成PSP

EXC_RETURN位段含義
[31:4]EXC_RETURN的標識:必須全為1
30=返回后進入Handler模式
1=返回后進入線程模式
20=從主堆棧中做出棧操作,返回后使用MSP,
1=從進程堆棧中做出棧操作,返回后使用PSP
1保留,必須為0
00=返回ARM狀態。
1=返回Thumb狀態。在CM3中必須為1

LR在函數調用時會自動更新,對于函數的返回,將LR出棧給PC即可

在異常退出時,也會將LR賦給PC,但是很顯然這不是代碼空間的地址,系統會根據標識檢測到這是一條EXC_RETURN命令,進一步根據進入中斷時入棧的PC進行返回

在這里插入圖片描述


RISC-V

在保存上下文和恢復上下文中都有如下語句:

csrrw sp, CSR_MSCRATCHCSWL, sp

mscratchcswl 寄存器用于在多個中斷 level 間切換時,交換目的寄存器與 mscratch 的值來加速中斷處理

使用帶讀操作的 CSR 指令訪問 mscratchcsw,當特權模式不變,在出現中斷程序和應用程序的切換時,有以下偽指令所示的寄存器操作:

mcause.mpil表示前一個中斷級別

mintstatus.mil表示Machine Mode 的有效中斷級別

csrrw rd, mscratchcswl, rs1// Pseudocode operation.
// 棧指針的切換只在中斷中操作,mintstatus.mil肯定不為0
// 如果mcause.mpil==0表示從線程中進入的中斷(待驗證),即判斷成立,使用mscratch和SP交換來加載主棧
// RESTORE_CONTEXT中再次調用即再次交互,把主棧存入mscratch并把線程棧交換到SP中
if ( (mcause.mpil==0!= (mintstatus.mil == 0) )
{t = rs1; rd = mscratch; mscratch = t;
} 
else 
{	// 中斷嵌套使用同一個棧,不需要改變rd = rs1; // mscratch unchanged.
}
// Usual use: csrrw sp, mscratchcswl, sp

看到這里,就會有一個疑問,第一次進中斷時,mscratch中的內容從哪里來呢?

rt_hw_context_switch_to表示沒有來源即第一次切換線程(在開始OS調度時調用,不是在中斷切換)

所以第一次切換線程時會將主棧存入mscratch,之后就不需要再管了

之后便線程棧賦值給sp

rt_hw_context_switch_to:/* Setup Interrupt Stack usingThe stack that was used by main()before the scheduler is started isno longer required after the scheduler is started.Interrupt stack pointer is stored in CSR_MSCRATCH */la t0, _spcsrw CSR_MSCRATCH, t0LOAD sp, 0x0(a0)                /* Read sp from first TCB member(a0) */

在進入中斷時,mepc 寄存器被同時更新,以反映當時遇到中斷時的 PC 值。軟件必須使用 mret指令退出中斷,執行 mret 指令后處理器將從 mepc 定義的 pc 地址重新開始執行。通過這個機制,意味著 mret 指令執行后處理器回到了當時遇到中斷時的 PC 地址,從而可以繼續執行之前被中止的程序流。
在這里插入圖片描述
在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/167762.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/167762.shtml
英文地址,請注明出處:http://en.pswp.cn/news/167762.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【LM358AD運放方波振蕩器可控輸出幅值】2022-2-25

緣由仿真如何縮小方波振蕩電路方波幅值?-有問必答-CSDN問答

使用Pytorch從零開始構建LSTM

長短期記憶(LSTM)網絡已被廣泛用于解決各種順序任務。讓我們了解這些網絡如何工作以及如何實施它們。 就像我們一樣,循環神經網絡(RNN)也可能很健忘。這種與短期記憶的斗爭導致 RNN 在大多數任務中失去有效性。不過&a…

發送一個網絡數據包的過程解析

在 ip_queue_xmit 中,也即 IP 層的發送函數里面,有三部分邏輯。第一部分,選取路由,也即我要發送這個包應該從哪個網卡出去。 這件事情主要由 ip_route_output_ports 函數完成。接下來的調用鏈為:ip_route_output_port…

改進YOLOv8 | YOLOv5系列:RFAConv續作,即插即用具有任意采樣形狀和任意數目參數的卷積核AKCOnv

RFAConv續作,構建具有任意采樣形狀的卷積AKConv 一、論文yolov5加入的方式論文 源代碼 一、論文 基于卷積運算的神經網絡在深度學習領域取得了顯著的成果,但標準卷積運算存在兩個固有缺陷:一方面,卷積運算被限制在一個局部窗口,不能從其他位置捕獲信息,并且其采樣形狀是…

Matlab進階繪圖第33期—雙曲面圖

在《Matlab論文插圖繪制模板第56期—曲面圖(Surf)》中,我分享過曲面圖的繪制模板。 然而,有的時候,需要在一張圖上繪制兩個及以上的曲面圖,且每個曲面圖使用不同的配色方案。 在Matlab中,一張…

C++基礎入門(超詳細)

話不多說,序言搞起來: 自從開始學老師布置的任務后,目前還是OpenCV,哈~哈。我就莫名問老師:“以后編程是用C還是python?”,果然還是太年輕,老師說:“兩們都要精通”。唉&…

set和map + multiset和multimap(使用+封裝(RBTree))

set和map 前言一、使用1. set(1)、模板參數列表(2)、常見構造(3)、find和count(4)、insert和erase(5)、iterator(6)、lower_bound和upper_bound 2. multiset3. map(1)、模板參數列表(2)、構造(3)、modifiers和operations(4)、operator[] 4. multimap 二、封裝RBTree迭代器原理R…

9.輸出國際象棋盤【2023.11.24】

1.問題描述 要求輸出國際象棋棋盤。 2.解決思路 國際象棋棋盤由64個黑白相間的格子組成&#xff0c;分為8行*8列。用i控制行&#xff0c;j控制列&#xff0c;根據ij的和的變化來控制輸出黑方格還是白方格。 3.代碼實現 #include<stdio.h> int main(){for(int i0;i&…

各操作系統之間的關系

請移步知乎&#xff1a; 操作系統UNIX、WINDOWS、LINUX、MC OS的聯系與區別 - 知乎 (zhihu.com) 移動端的android操作系統就人盡皆知啦&#xff0c;基于linux內核。 完畢。 適用領域&#xff1a; windows,macos:主要面向個人計算機市場 Linux、Windows Server:隨著互聯網的…

基于廣義正態分布算法優化概率神經網絡PNN的分類預測 - 附代碼

基于廣義正態分布算法優化概率神經網絡PNN的分類預測 - 附代碼 文章目錄 基于廣義正態分布算法優化概率神經網絡PNN的分類預測 - 附代碼1.PNN網絡概述2.變壓器故障診街系統相關背景2.1 模型建立 3.基于廣義正態分布優化的PNN網絡5.測試結果6.參考文獻7.Matlab代碼 摘要&#xf…

網絡安全—自學

1.網絡安全是什么 網絡安全可以基于攻擊和防御視角來分類&#xff0c;我們經常聽到的 “紅隊”、“滲透測試” 等就是研究攻擊技術&#xff0c;而“藍隊”、“安全運營”、“安全運維”則研究防御技術。 2.網絡安全市場 一、是市場需求量高&#xff1b; 二、則是發展相對成熟…

深度學習之基于Pytorch照片圖像轉漫畫風格網絡系統

歡迎大家點贊、收藏、關注、評論啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代碼。 文章目錄 一項目簡介 二、功能三、系統四. 總結 一項目簡介 以下是一個基本的設計介紹&#xff1a; 數據準備&#xff1a;收集足夠的真實照片和漫畫圖像&#xff0c;用于訓練模…

typora中的快捷鍵shift enter 和 enter的交換

1 問題&#xff1a; 我最近在用 typora 進行寫作&#xff0c;但是在合格 typora 的 markdown 編輯器很奇怪&#xff0c;它的一個回車符是兩次換行&#xff0c;而用 shfit ent 找了半天都不知道怎么解決的這個問題&#xff0c;然后我就去了這個 typora 在 github 開源的問題倉庫…

hive 報錯return code 40000 from org.apache.hadoop.hive.ql.exec.MoveTask解決思路

參考學習 https://github.com/apache/hive/blob/2b57dd27ad61e552f93817ac69313066af6562d9/ql/src/java/org/apache/hadoop/hive/ql/ErrorMsg.java#L47 為啥學習error code 開發過程中遇到以下錯誤&#xff0c;大家覺得應該怎么辦&#xff1f;從哪方面入手呢&#xff1f; 1.百…

解決在Windows10或Windows11下無權限修改hosts文件

解決在Windows10或Windows11下無權限修改hosts文件&#xff0c;無法寫入內容 1、首先在開始菜單中找到這個 2、接著輸入&#xff1a; C:\Windows\System32\drivers\etc3、再次輸入以下命令行&#xff1a;notepad hosts &#xff0c;并回車&#xff1a; notepad hosts 4、然后…

DataFunSummit:2023年現代數據棧技術峰會-核心PPT資料下載

一、峰會簡介 現代數據棧&#xff08;Modern Data Stack&#xff09;是一種集合了多種技術和工具的軟件基礎設施&#xff0c;旨在更好地管理和處理數據&#xff0c;并為企業提供數據驅動的洞察和決策。包含以下幾個組件&#xff1a;數據采集、數據處理、數據存儲、數據查詢和分…

區塊鏈技術與應用 【全國職業院校技能大賽國賽題目解析】第四套區塊鏈應用后端開發

第四套區塊鏈應用后端開發 環境 : ubuntu20 fisco : 2.8.0 springboot 2.1.1 fisco-java-sdk: 2.7.2 maven 3.8.8 前言 這套后端樣題,只涉及調用fisco的系統接口,不涉及此食品溯源項目的業務接口,所以我就直接生成一個springboot項目進行完成此題目。 請提前準備好一…

Docker的項目資源參考

Docker的項目資源包括以下內容&#xff1a; Docker官方網站&#xff1a;https://www.docker.com/ Docker Hub&#xff1a;https://hub.docker.com/ Docker文檔&#xff1a;https://docs.docker.com/ Docker GitHub倉庫&#xff1a;https://github.com/docker Docker官方博客…

Unity中Shader的Standard材質解析(二)

文章目錄 前言一、我們對 Standard 的 PBR 的 GI 進行解析1、我們先創建一個PBR的.cginc文件&#xff0c;用于整理用到的函數2、然后在Standard的Shader中引用該cginc文件 二、依次整理函數到該cginc文件中我們來看一下PBR中GI的鏡面反射做了些什么 二、最終代碼.cginc代碼&…

OpenGL 繪制旋轉球(Qt)

文章目錄 一、簡介二、實現代碼三、實現效果一、簡介 這里其實就是指三個互相垂直的三個圓形,正好之前已經完成了圓形平面的繪制,那么這里就需要對之前的圓形進行一些改造,使得它們可以以任意一種姿態在OpenGL中進行繪制(添加變換矩陣)。 這里同樣對其進行封裝,具體內容如…