1.概述
2.中斷向量表初始化
3.詳細(xì)分析一下irq_entry
4.關(guān)于gd32vf103中斷編程模型的理解
1.概述在處理riscv處理器中斷的時(shí)候,需要弄清楚兩個(gè)概念:
1.向量中斷
2.非向量中斷
對(duì)于向量中斷,其中斷發(fā)生后,pc指針會(huì)根據(jù)中斷的類型跳轉(zhuǎn)到基地址+中斷號(hào)*4的地址處去執(zhí)行中斷處理程序,做過stm32的,應(yīng)該比較清楚向量中斷的大概樣子。當(dāng)然,riscv也是支持這種向量中斷,這樣每個(gè)地址處會(huì)安排一個(gè)特定的中斷處理函數(shù),當(dāng)中斷發(fā)生后,跳轉(zhuǎn)到特定的函數(shù)去執(zhí)行即可。
對(duì)于非向量中斷,則表示中斷發(fā)生后只有一個(gè)入口,需要在這一個(gè)中斷中去判斷具體中斷號(hào),這種行為可以在常見的mips處理器、sparc處理器中看到。
既然riscv支持這兩種中斷處理方式,正好gd32vf103的庫函數(shù)也實(shí)現(xiàn)了這兩種機(jī)制,那么就徹底的分析一下實(shí)現(xiàn)的策略。
2.中斷向量表初始化任何代碼在最初的匯編級(jí)別的初始化時(shí),都會(huì)指定向量的基地址。當(dāng)然riscv也不例外。
對(duì)于向量中斷來說
/*
* Intialize ECLIC vector interrupt
* base address mtvt to vector_base
*/
la t0, vector_base
csrw CSR_MTVT, t0
這里的理解就向mtvt寄存器中存放vector_base,該處存放向量地址入口,每個(gè)向量中斷發(fā)生,則根據(jù)偏移執(zhí)行對(duì)應(yīng)的函數(shù)。
.globl vector_base
.type vector_base, @object
vector_base:
#if defined(DOWNLOAD_MODE) && (DOWNLOAD_MODE != DOWNLOAD_MODE_FLASH)
j _start /* 0: Reserved, Jump to _start when reset for ILM/FlashXIP mode.*/
.align LOG_REGBYTES /* Need to align 4 byte for RV32, 8 Byte for RV64 */
#else
DECLARE_INT_HANDLER default_intexc_handler /* 0: Reserved, default handler for Flash download mode */
#endif
DECLARE_INT_HANDLER default_intexc_handler /* 1: Reserved */
DECLARE_INT_HANDLER default_intexc_handler /* 2: Reserved */
DECLARE_INT_HANDLER eclic_msip_handler /* 3: Machine software interrupt */
DECLARE_INT_HANDLER default_intexc_handler /* 4: Reserved */
DECLARE_INT_HANDLER default_intexc_handler /* 5: Reserved */
。
。
。
對(duì)于向量函數(shù)的處理,不用過多介紹。
下面非向量中斷的入口
/*
* 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_entry
csrw CSR_MTVT2, t0
csrs CSR_MTVT2, 0x1
其中irq_entry表示了非向量的處理過程。csrs CSR_MTVT2, 0x1該指令的解析如下:
mtvt2[0] = 1 mtvt2[0]為0時(shí),中斷入口使用mtvec寄存器,mtvt2[0]為1時(shí),中斷入口為mtvt2[31:2]。
3.詳細(xì)分析一下irq_entry分析非向量中斷的行為,可以更好的理解riscv的中斷底層的處理機(jī)制。
.global irq_entry
/* This label will be set to MTVT2 register */
irq_entry:
/* Save the caller saving registers (context) */
SAVE_CONTEXT
/* Save the necessary CSR registers */
SAVE_CSR_CONTEXT
/* This special CSR read/write operation, which is actually
* claim the CLIC to find its pending highest ID, if the ID
* is not 0, then automatically enable the mstatus.MIE, and
* jump to its vector-entry-label, and update the link register
*/
csrrw ra, CSR_JALMNXTI, ra
/* Critical section with interrupts disabled */
DISABLE_MIE
/* Restore the necessary CSR registers */
RESTORE_CSR_CONTEXT
/* Restore the caller saving registers (context) */
RESTORE_CONTEXT
/* Return to regular code */
mret
從中斷處理的原理上來講,中斷處理分三部分:
1.保存當(dāng)前現(xiàn)場(chǎng)
2.進(jìn)入中斷處理函數(shù)
3.恢復(fù)現(xiàn)場(chǎng)
其中SAVE_CONTEXT確實(shí)是保存上下文現(xiàn)場(chǎng)的方式。
.macro SAVE_CONTEXT
csrrw sp, CSR_MSCRATCHCSWL, sp
/* Allocate stack space for context saving */
#ifndef __riscv_32e
addi sp, sp, -20*REGBYTES
#else
addi sp, sp, -14*REGBYTES
#endif /* __riscv_32e */
STORE 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)
#ifndef __riscv_32e
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)
#endif /* __riscv_32e */
.endm
按照riscv的數(shù)據(jù)模型,又分為I數(shù)據(jù)模型和E數(shù)據(jù)模型,這部分在riscv的MISA寄存器中有描述。簡(jiǎn)而言之,E數(shù)據(jù)模型會(huì)比I數(shù)據(jù)模型少一半的寄存器,E數(shù)據(jù)模型是專門針對(duì)嵌入式應(yīng)用場(chǎng)景的,更少的寄存器意味著更快速的壓棧和出棧,實(shí)時(shí)性相應(yīng)會(huì)更加優(yōu)秀。
I數(shù)據(jù)模型一共有32個(gè)寄存器,而E數(shù)據(jù)模型是16個(gè)寄存器。
所以在進(jìn)行中斷入棧的時(shí)候,E數(shù)據(jù)模型會(huì)壓入10個(gè)寄存器。
caller代表中斷上層函數(shù)可以使用的寄存器,所以
x1,x5,x6,x7,x10,x11,x12,x13,x14,x15
這10個(gè)寄存器會(huì)保存,上述程序多保存了x4。
下面理解一下中斷的處理,通過csrrw ra, CSR_JALMNXTI, ra該指令進(jìn)行分析。
不難發(fā)現(xiàn),這個(gè)是個(gè)芯來自定義擴(kuò)展指令,CSR_JALMNXTI寄存器通過gdb解析可以看到如下的數(shù)據(jù)
其中0x7ed則是該寄存器的地址。
那么一條指令是如何實(shí)現(xiàn)中斷的處理的呢?
實(shí)際上該指令首先會(huì)判斷當(dāng)前eclic中是否有掛起未處理的中斷,如果沒有,那這條指令向下執(zhí)行,并不會(huì)處理任何事情,一旦存在,那么會(huì)跳轉(zhuǎn)到eclic的中斷向量的入口,這里便是關(guān)鍵的地方了。
另外需要注意的是,默認(rèn)進(jìn)入中斷時(shí),保存現(xiàn)場(chǎng)時(shí),此處是關(guān)閉中斷的,當(dāng)執(zhí)行這條語句,中斷便會(huì)開啟,然后判斷是否還有中斷未響應(yīng),這樣可以達(dá)到中斷咬尾的效果。
并且當(dāng)中斷處理函數(shù)執(zhí)行完成后,又會(huì)回到該指令執(zhí)行一次,判斷是否還需要處理中斷。這一切的行為都是由硬件完成,大大提高中斷處理的效率。
現(xiàn)場(chǎng)恢復(fù)則是中斷處理的逆過程,這里不贅述。
4.關(guān)于gd32vf103中斷編程模型的理解對(duì)于cortex-m3等處理器來說,riscv的底層模型似乎更加復(fù)雜一些,但是實(shí)際上弄清楚riscv中斷處理模型,eclic中斷處理機(jī)制,以及向量中斷,非向量中斷和一條中斷處理指令csrrw ra, CSR_JALMNXTI, ra后,也不會(huì)覺得十分的難以理解。
玩gd32vf103,其riscv底層匯編級(jí)別的中斷處理一般都不會(huì)太多需要修改的,理解就可以。需要使用好的是eclic配置,還有相關(guān)的gpio的中斷引腳的配置即可。將中斷線、eclic配置完成,具體中斷處理函數(shù)中實(shí)現(xiàn)自己的業(yè)務(wù)邏輯即可,不需要有許多學(xué)習(xí)成本。
原文標(biāo)題:從riscv底層原理分析gd32vf103的中斷行為
文章出處:【微信公眾號(hào):嵌入式IoT】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
責(zé)任編輯:haq
-
嵌入式
+關(guān)注
關(guān)注
5174文章
19967瀏覽量
324248 -
RISC-V
+關(guān)注
關(guān)注
47文章
2694瀏覽量
50805 -
GD32VF103
+關(guān)注
關(guān)注
0文章
6瀏覽量
1008
原文標(biāo)題:從riscv底層原理分析gd32vf103的中斷行為
文章出處:【微信號(hào):Embeded_IoT,微信公眾號(hào):嵌入式IoT】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
GD32F103RCT6 rt_kprintf無法打印怎么解決?
GD32F103RCT6移植qboot,燒錄之后系統(tǒng)卡死怎么解決?
協(xié)議分析儀能監(jiān)測(cè)哪些異常行為?
Cortex-M MCU應(yīng)用程序移植到RV32 MCU中的問題解析

AS32X601驅(qū)動(dòng)系列教程 PLIC_中斷應(yīng)用詳解

GD32VF103硬件開發(fā)指南

GD32E103和GD32C103硬件開發(fā)指南

程序中斷的100種寫法
谷歌在印尼因壟斷行為被罰1200萬美元
GD32F103xx數(shù)據(jù)表

GD32A103xx數(shù)據(jù)表

GD32VF103數(shù)據(jù)表

GD32E103xx數(shù)據(jù)表

GD32C103xx數(shù)據(jù)表

評(píng)論