ECLIC中斷流程及實際應用 —— RISC-V中斷機制(二)

在長期的嵌入式開發實踐中,對中斷機制的理解始終停留在表面層次,特別當開發者長期局限于純軟件抽象層面時,對中斷機制的理解極易陷入"知其然而不知其所以然"的困境,這種認知的局限更為明顯;隨著工作需要不斷深入底層技術,對硬件機制的了解逐漸加深,并積累了大量的學習筆記。借此機會,我將這些零散的知識進行系統化梳理,既是對自身知識的復盤,也希望能為相關領域的開發者提供些許幫助和參考。關于RISC-V中斷機制的分析,本文將從硬件實現原理和軟件應用以下兩個方面來展開介紹:

RISC-V CLINT、PLIC及芯來ECLIC中斷機制分析 —— RISC-V中斷機制(一)
ECLIC中斷流程及實際應用 —— RISC-V中斷機制(二)

背景

中斷(Interrupt)機制,即處理器內核在順序執行程序指令流的過程中突然被別的請求打斷而中止執行當前的程序,轉而去處理別的事情,待其處理完了別的事情,然后重新回到之前程序中斷的點繼續執行之前的程序指令流。
中斷相關的基本知識要點:

  • 打斷處理器執行的“別的請求”便稱之為中斷請求(Interrupt Request),“別的請求”的來源便稱之為中斷源(Interrupt Source),中斷源通常來自于內核外部(稱之為外部中斷源),也可以來自于內核內部(成為內部中斷源)。
  • 處理器轉而去處理的“別的事情”便稱之為中斷服務程序(Interrupt Service Routine,ISR)
  • 中斷處理是一種正常的機制,而非一種錯誤情形。處理器收到中斷請求之后,需要保存當前程序的現場,簡稱為“保存現場”。等到處理完中斷服務程序后,處理器需要恢復之前的現場,從而繼續執行之前被打斷的程序,簡稱為“恢復現場”。
  • 可能存在多個中斷源同時向處理器發起請求的情形,需要對這些中斷源進行仲裁,從而選擇哪個中斷源被優先處理。此種情況稱為“中斷仲裁”,同時可以給不同的中斷分配級別和優先級以便于仲裁,因此中斷存在著“中斷級別”和“中斷優先級”的概念。

芯來N級別處理器內核實現了一個“改進型內核中斷控制器(Enhanced Core Local Interrupt Controller,ECLIC)”,可用于多個中斷源的管理。N級別處理器內核中的所有類型(除了調試中斷之外)的中斷都由ECLIC統一進行管理。

1 寄存器

有詳細介紹說過ECLIC相關的寄存器,下面介紹中斷處理流程使用的CSR寄存器:用來保存控制信息。

1.1 硬件自動填寫的寄存器

  • mepc(Machine Exception Program Counter)
    保存發生異常或中斷時的PC值。
    如果中斷處理需要恢復到異常指令后一條指令進行執行,就需要正確判斷將 pc 寄存器加上多少字節。

  • mcause(Machine Cause Register)
    記錄中斷是否是硬件中斷,以及具體的中斷原因,如:

    • Interrupt Bit(最高位):1 表示中斷,0 表示異常。
    • Exception Code(低 31 位):具體原因編碼(如 0x0B 表示外部中斷)。

異常編碼表:
在這里插入圖片描述

  • mtval(Machine Trap Value Register)
    存儲與異常相關的附加信息(如非法地址、非法指令編碼)。

    • 非法地址異常:mtval 記錄訪問的非法地址。
    • 非法指令異常:mtval 存儲非法指令的二進制編碼。
    • 對于中斷(非異常),mtval 通常無意義,可能保留為 0

1.2 指示硬件處理中斷的寄存器

  • mtvec(Machine Trap Vector Base Address Register)
    設置機器模式(M-mode)下中斷和異常的入口地址基址。存儲了一個基址 BASE 和模式 MODE:
    • MODE 為 0 表示 直接模式,即遇到中斷便跳轉至 同一入口地址(mtvec.BASE)。
    • MODE 為 1 表示 向量模式,中斷跳轉到 mtvec.BASE + 4 * cause,異常仍使用統一入口。

以上是官方中斷入口,芯來的eclic是基于clic,這里是有改動的,正常情況下mtvec是作為異常處理入口的,中斷入口是由mtvt2定義。芯來mtvec定義如下:

在這里插入圖片描述

  • mstatus(Machine Status Register)
    控制全局中斷使能及特權模式切換;如:

    • MIE(Machine Interrupt Enable):全局中斷開關。若為 0,所有中斷被屏蔽。
    • MPP(Machine Previous Privilege):記錄中斷前的特權模式(如 M/S/U-mode),用于 mret 返回。
      在這里插入圖片描述
  • mie(Machine Interrupt Enable Register)
    用來控制具體類型中斷的使能,如:

    • MEIE(Machine External Interrupt Enable):外部中斷(如 PLIC/ECLIC 中斷)使能。
    • MTIE(Machine Timer Interrupt Enable):定時器中斷使能。
    • MSIE(Machine Software Interrupt Enable):軟件中斷使能。
      在這里插入圖片描述
  • mip(Machine Interrupt Pending Register)
    和 mie 相對應,標記中斷的掛起狀態(Pending Bits)

    • MEIP(Machine External Interrupt Pending):外部中斷掛起位。
    • MTIP(Machine Timer Interrupt Pending):定時器中斷掛起位。
    • MSIP(Machine Software Interrupt Pending):軟件中斷掛起位。
  • mtvt
    寄存器保存中斷向量表的基址(在CLIC模式下),基址至少對齊64字節邊界

  • mtvt2
    用于指示所有ECLIC中斷共享的公共基處理程序的入口地址
    在這里插入圖片描述

  • mscratch
    寄存器的用處會在實現線程時起到作用,在中斷處理開始時,將當前線程的上下文指針保存到 mscratch,再從 mscratch 加載中斷棧指針;感興趣可以自行學習下。

  • msubm
    芯來自定義的CSR msubm寄存器保存當前機器子模式和當前陷阱之前的機器子模式

在這里插入圖片描述

  • jalmnxti
    芯來自定義的CSR jalmnxti,用來減少中斷延遲并加速中斷尾部鏈接。
    jalmnxti包括mnxti(Next Interrupt Handler Address and Interrupt-Enable CSR)的所有功能,此外還包括啟用中斷、處理下一個中斷、跳轉到下一個中斷入口地址以及跳轉到中斷處理程序。(感興趣可以自行繼續深入學習下)

實際通過修改jalmnxti和ra的地址的值,在中斷嵌套和咬尾時,可以節省保存上下文(CSR和通用寄存器)的開銷,

1.4 臨時寄存器

  • pushmepc
  • pushmsubm
  • pushmcause

芯來自定義了通過CSR指令csrrwi將msubm、mepc、mcause的值存儲在以SP為基址的內存空間中,該指令將CSR寄存器的值存儲在SP+1*4地址中。

2 ECLIC中斷處理流程

2.1 整體流程(主要以非向量中斷為例)

當一個hart發生中斷時,整個中斷流程需要軟硬協作完成,下圖是eclic中斷處理,包括:進入以及推出全部流程流程

在這里插入圖片描述

  1. 硬件接收到中斷信號,硬件自動更新CSR寄存器

    • 更新內核退出中斷時的返回地址,存儲在mepc(1、該地址就是中斷打斷的PC值(在中斷結束之后,回到被停止執行的程序點), 2、mepc軟件可以顯示修改)
      • ①、mcause.EXCCODE存放中斷ID,以便軟件查詢;②、如果當前中斷搶占了低優先級中斷,mcause.MPIL將更新為minstatus.MIL的值,處理中斷后,將使用mcause.MPIL的值來恢復mintcause.MIL的值;③、如果是向量模式中斷,mcause.minhv的值將更新為1,在完成從中斷向量表中取出存儲的目標地址,然后再跳轉到目標地址中去后,mcause.minhv域的值清除為0
      • ①、mstatus.MPIE更新為mstatus.MIE的值,mstatus.MIE置0(屏蔽所有中斷);②、處理器的當前特權模式(Privilege Mode)切換到機器模式(Machine Mode)mstatus.MPP從特權模式將切換到機器模式;
      • ①、msubm.PTYP域的值被更新為中斷發生前的Machine Sub-Mode(msubm.TYP域的值)②、msubm.TYP域的值則被更新為“中斷處理模式”(反映當前的模式已經是“中斷處理模式”)
  2. 跳轉到共享中斷入口地址,保存中斷上下文(非向量中斷)(寄存器clicintattr[i]的shv域決定中斷是向量中斷還是非向量中斷)

    • 跳入到mtvt2.CMMON-CODE-ENTRY(mtvt2.MTVT2EN = 1);
    • 將一些通用寄存器(ra/tp/t0-t6/a0-a7)(保存中斷上下文)保存到堆棧中;
    • 將CSR mepc、mcause、msubm保存到堆棧中,確保后續的搶占中斷可以被正確處理;
      • 如果被配置成為向量處理模式,則該中斷被處理器內核響應后,處理器直接跳入該中斷的向量入口(Vector Table Entry)存儲的目標地址(ISR地址)
      • 如果被配置成為非向量處理模式,則該中斷被處理器內核響應后,處理器直接跳入所有中斷共享的入口地址
  3. 執行Nuclei自定義指令“csrrw ra,CSR_JALMNXTI,ra”,如果沒有待處理的中斷,則該指令將被視為空操作;否則進入下面步驟

    • 直接跳入該中斷的向量入口(Vector Table Entry)存儲的目標地址,即該中斷源的中斷服務程序**(Interrupt Service Routine,ISR)**中去
    • 硬件置位全局中斷使能位mstatus.MIE,此時可以接受新中斷,以形成中斷嵌套。
    • 把當前PC(csrrw ra,CSR_JALMNXTI,ra)寫入返回地址ra寄存器,達到JAL(Jump and Link)的效果,即:在執行完中斷handle之后,將再次執行該指令“csrrw ra,CSR_JALMNXTI,ra”,進而重新判斷是否有還未處理的中斷(pending),進而形成中斷咬尾
  4. 從中斷服務函數中返回后,軟件來恢復中斷上下文

    • mstatus.MIE置0,屏蔽所有中斷,確保操作的原子性
    • 從堆棧中恢復中斷前CSR寄存器(msubm、mepc、mcause)以及通用寄存器(ra/tp/t0-t6/a0-a7/sp)的值
  5. 軟件執行mret退出中斷處理程序,硬件將自動更新CSR寄存器

    • ①、mcause.MPIL的值恢復minstatus.MIL的值,minstatus.MIL的值會被恢復到中斷前的原始值;②、使用mcause.MPIE的值恢復minstatus.MIE的值,minstatus.MIE的值會被恢復到觸發中斷前的值;③、mcause.MPP特權模式從中斷模式退出,恢復為中斷前的模式,(同樣也會更新mstatus.MPIE和mcause.MPP的值,見最后NOTE)。
    • 硬件將處理器Machine Sub-Mode的值恢復為msubm.PTYP域的值
    • 跳轉到mepc定義的PC,繼續執行之前被中止的程序流。

NOTE:
mstatus.MPIE域和mstatus.MPP域的值與mcause.MPIE域和mcause.MPP域的值是鏡像關系,即,在正常情況下,mstatus.MPIE域的值與mcause.MPIE域的值總是完全一樣,mstatus.MPP域的值與mcause.MPP域的值總是完全一樣。

2.2 向量中斷與非向量中斷

ECLIC的每個中斷源均可以設置成向量或者非向量處理(通過寄存器clicintattr[i]的shv域),向量處理模式和非向量處理模式二者有較大的差別

2.1章節主要是以非向量中斷為例介紹的中斷處理流程,這里把前面的一些和向量中斷不同的點再總結下,方便和向量中斷做對比

2.2.1 非向量中斷處理模式

在這里插入圖片描述
1、非向量處理模式,則該中斷被處理器內核響應后,處理器會直接跳入到所有非向量中斷共享的入口地址,該入口地址可以通過軟件進行設置

  • 如果配置CSR寄存器mtvt2的最低位為0(上電復位默認值),則所有非向量中斷共享的入口地址由CSR寄存器mtvec的值(忽略最低2位的值)指定。由于mtvec寄存器的值也指定異常的入口地址,因此,意味著在這種情況下,異常和所有非向量中斷共享入口地址

  • 如果配置CSR寄存器mtvt2的最低位為1芯來SDK的bootloader里配置為1了,將異常和非向量中斷入口分開,不用判斷是中斷還是異常了,提升效率),則所有非向量中斷共享的入口地址由CSR寄存器mtvt2的值(忽略最低2位的值)指定。

2、如2.1章節步驟二描述,進入所有非向量中斷共享的入口地址之后,處理器會開始執行一段共有的軟件代碼

  • 首先保存CSR寄存器mepc、mcause、msubm入堆棧。保存這幾個CSR寄存器是為了保證后續的中斷嵌套能夠功能正確,因為新的中斷響應會重新覆蓋mepc、mcause、msubm的值,因此需要將它們先保存入堆棧
  • 保存若干通用寄存器(處理器的上下文)入堆棧
  • 然后執行一條特殊的指令“csrrw ra, CSR_JALMNXTI, ra”。如果沒有中斷在等待(Pending),則該指令相當于是個Nop指令不做任何操作;如果有中斷在等待(Pending),執行該指令后處理器會
    • 直接跳入該中斷的向量入口(Vector Table Entry)存儲的目標地址,即該中斷源的中斷服務程序(Interrupt Service Routine,ISR)中去。
    • 在跳入中斷服務程序的同時,硬件也會同時打開中斷的全局使能,即,設置mstatus寄存器的MIE域為1。打開中斷全局使能后,新的中斷便可以被響應,從而達到中斷嵌套的效果。
    • 在跳入中斷服務程序的同時,“csrrw ra, CSR_JALMNXTI, ra”指令還會達到JAL(Jump and Link)的效果,硬件同時更新Link寄存器的值為該指令的PC自身作為函數調用的返回地址。因此,從中斷服務程序函數返回后會回到該“csrrw ra, CSR_JALMNXTI, ra”指令重新執行,重新判斷是否還有中斷在等待(Pending),從而達到中斷咬尾的效果。
    • 在中斷服務程序的結尾處同樣需要添加對應的恢復上下文出棧操作。并且在CSR寄存器mepc、mcause、msubm出堆棧之前,需要將中斷全局使能再次關閉,以保證mepc、mcause、msubm恢復操作的原子性(不被新的中斷所打斷)。

2.2.2 向量中斷的處理

在這里插入圖片描述
1、如果被配置成為向量處理模式,則該中斷被處理器內核響應后,處理器會**直接跳入該中斷的向量入口(Vector Table Entry)**存儲的目標地址,即該中斷源的中斷服務程序(Interrupt Service Routine,ISR)

2、向量處理模式具有如下特點:

  • 向量處理模式時處理器會直接跳到中斷服務程序,并沒有進行上下文的保存,因此,中斷響應延遲非常之短,從中斷源拉高到處理器開始執行中斷服務程序中的第一條指令,基本上只需要硬件進行查表和跳轉的時間開銷,理想情況下約6個時鐘周期。

  • 對于向量處理模式的中斷服務程序函數,一定要使用特殊的__attribute__((interrupt))來修飾中斷服務程序函數。

  • 向量處理模式時,由于在跳入中斷服務程序之前,處理器并沒有進行上下文的保存,因此,理論上中斷服務程序函數本身不能夠進行子函數的調用。

  • 如果不小心調用了其他子函數,只要使用了__attribute__((interrupt))來修飾中斷復位函數,編譯器就會自動插入一段代碼進行上下文的保存。(實際使用中不推薦調用子函數)

  • 處理器在響應向量中斷后,mstatus寄存器中的MIE域將會被硬件自動更新成為0(中斷被全局關閉,從而無法響應新的中斷)。因此向量處理模式默認是不支持中斷嵌套的,為了達到向量處理模式且又能夠中斷嵌套的效果,可以在中斷服務例程里依次加入以下操作來實現中斷嵌套效果。

    • 保存CSR寄存器mepc、mcause、msubm入堆棧。
    • 重新打開中斷的全局使能(mstatus.MIE置1)
    • 執行中斷程序內容
    • 關閉中斷全局使能,恢復上下文出棧操作

3、對于向量處理模式的中斷而言,由于在跳入中斷服務程序之前,處理器并沒有進行上下文的保存,因此進行“中斷咬尾”的意義不大,因此,向量處理模式的中斷,沒有“中斷咬尾”處理能力。(除非在向量中斷復位函數里進行中斷上下文以及返回地址的處理,但這樣不如一開始就注冊為非向量中斷)

2.2.3 二者區別

這里就簡單總結對比下:

對比項向量中斷(Vectored Interrupt)非向量中斷(Non-Vectored Interrupt)
入口地址每個中斷有獨立的入口地址(由向量表定義)。所有中斷共享統一入口地址。
開銷低(硬件自動跳轉IRQ,無需軟件處理中斷上下文)。高(需要從統一入口進入,需要軟件處理中斷上下文)。
中斷嵌套支持(需要在中斷服務例程中手動處理上下文來支持)支持
中斷咬尾不支持支持
IRQ定義void __INTERRUPT isr_uart() { ... }void isr_uart() { ... }
應用場景需要快速響應的高優先級外設低優先級或非實時外設

NOTE:
非向量模式的中斷處理函數,中斷函數前面一定不要加__INTERRUPT 這個關鍵字描述,否則編譯器會用mret 指令,導致中斷提前返回了中斷前的代碼,而不是返回到common_entry 這里
而向量中斷需要使用__attribute__((interrupt))來修飾,讓編譯器來處理該服務例程

2.3 中斷搶占和中斷咬尾

實際上通過前面的前面的介紹,對于中斷搶占和中斷咬尾,基本上已經能了解個七七八八了,這里再簡單總結下,并舉例說明下。

2.3.1 基本概念

1、中斷嵌套
處理器內核正在處理某個中斷的過程中,可能有一個級別更高的新中斷請求到來,處理器可以中止當前的中斷服務程序,轉而開始響應新的中斷,并執行其“中斷服務程序”,如此便形成了中斷嵌套(即前一個中斷還沒響應完,又開始響應新的中斷),并且嵌套的層次可以有很多層。

2、中斷咬尾
處理器內核正在處理某個中斷的過程中,可能有新中斷請求到來,但是**“新中斷的級別”低于或者等于“當前正在處理的中斷級別”**,因此,新中斷不能夠打斷當前正在處理的中斷(因此不會形成嵌套)

2.3.2 中斷嵌套處理流程

1、非向量中斷
假設中斷源30、31、32這三個中斷源先后到來,且“中斷源32的級別” > “中斷源31的級別”> “中斷源30的級別”,那么后來的中斷便會打斷之前正在處理的中斷形成中斷嵌套
在這里插入圖片描述
2、向量中斷
假設中斷源30、31、32這三個中斷源先后到來,且“中斷源32的級別” > “中斷源31的級別”> “中斷源30的級別”,那么后來的中斷便會打斷之前正在處理的中斷形成中斷嵌套。
在這里插入圖片描述
向量中斷不同點是,1、中斷入口不一致(中斷的服務函數地址),2、中斷服務函數里軟件實現中斷上下文處理

2.3.3 中斷咬尾處理流程

假設中斷源30、29、28這三個中斷源先后到來,且“中斷源30的級別” >= “中斷源29的級別”>= “中斷源28的級別”,那么后來的中斷不會打斷之前正在處理的中斷(不會形成中斷嵌套),但是會被置于等待(Pending)狀態。當中斷源30完成處理后,將會直接開始中斷源29的中斷處理,省掉中間的“恢復上下文”和“保存上下文”過程。

在這里插入圖片描述

2.3.4 總結

非向量中斷總是能夠支持中斷嵌套和中斷咬尾的;
向量中斷則是可以通過在中斷服務程序中通過軟件處理來支持中斷嵌套,但不支持中斷咬尾。
另外,并未給出向量中斷和非向量中斷相互嵌套的例子,不過大家可以自行分析下。

3 實際應用

這里結合芯來開源SDK中demo_eclic代碼及qemu(RISC-V匯編學習(四)—— RISCV QEMU平臺搭建(基于芯來平臺))來演示下,向量中斷與非向量中斷以及中斷的嵌套。

中斷注冊入口初始化共享中斷入口流程代碼,自行參考芯來開源sdk中的驅動及BootLoader學習(參考下面源碼鏈接)。

3.1、源碼分析

芯來提供了一個軟件中斷和timer中斷的示例,源碼點擊鏈接即可查看:
Gitee: https://gitee.com/Nuclei-Software/nuclei-sdk/blob/master/application/baremetal/demo_eclic/demo_eclic.c
Github: https://github.com/Nuclei-Software/nuclei-sdk/blob/master/application/baremetal/demo_eclic/demo_eclic.c.

源碼執行結果,展示部分打印

-------------------
[IN TIMER INTERRUPT]timer interrupt hit 0 times
[IN TIMER INTERRUPT]trigger software interrupt
[IN TIMER INTERRUPT]software interrupt will run when timer interrupt finished
[IN TIMER INTERRUPT]timer interrupt end
[IN SOFTWARE INTERRUPT]software interrupt hit 0 times
[IN SOFTWARE INTERRUPT]software interrupt end
-------------------
[IN TIMER INTERRUPT]timer interrupt hit 1 times
[IN TIMER INTERRUPT]trigger software interrupt
[IN TIMER INTERRUPT]software interrupt will run when timer interrupt finished
[IN TIMER INTERRUPT]timer interrupt end
[IN SOFTWARE INTERRUPT]software interrupt hit 1 times
[IN SOFTWARE INTERRUPT]software interrupt end

分析

  • 程序中分別注冊了:
    • 1、timer中斷:高優先級、非向量中斷
    • 2、軟件中斷:低優先級、向量中斷
timer_intlevel = HIGHER_INTLEVEL;
swirq_intlevel = LOWER_INTLEVEL;// initialize timer
setup_timer();
// initialize software interrupt as vector interrupt
returnCode = ECLIC_Register_IRQ(SysTimerSW_IRQn, ECLIC_VECTOR_INTERRUPT,ECLIC_LEVEL_TRIGGER, swirq_intlevel, 0, eclic_msip_handler);
// inital timer interrupt as non-vector interrupt
returnCode = ECLIC_Register_IRQ(SysTimer_IRQn, ECLIC_NON_VECTOR_INTERRUPT,ECLIC_LEVEL_TRIGGER, timer_intlevel, 0, eclic_mtip_handler);
  • 實現:
    通過設置core內部的MTIMERCMP寄存器,來觸發timer中斷,之后在timer中斷服務例程里配置MSIP來觸發軟件中斷

根據打印可以發現程序這里實現了中斷咬尾效果,即:
1、低優先級中斷無法打斷高優先級中斷
2、每次都會先觸發非向量中斷(timer中斷),然后再觸發向量中斷(soft中斷)
3、在高優先級的非向量中斷退出后再次執行"csrrw ra, CSR_JALMNXTI, ra",此時還有低優先級的中斷在pending中,就會繼續執行低優先級的軟件中斷,從而形成中斷咬尾

另外,這里把軟件中斷配置成非向量中斷(記得去掉IRQ的__INTERRUPT修飾)效果也是一樣的,
但是把timer中斷換成向量中斷(不支持中斷咬尾)是不行的。(第一個觸發的中斷是非向量中斷可以實現中斷咬尾)

3.2 中斷嵌套實現

我們在芯來提供的demo_eclic基礎上來做些修改:

只需要打開#define SWIRQ_INTLEVEL_HIGHER 1,就會從新定義優先級: soft中斷>timer中斷

執行代碼,部分打印如下:

-------------------
[IN TIMER INTERRUPT]timer interrupt hit 0 times
[IN TIMER INTERRUPT]trigger software interrupt
[IN TIMER INTERRUPT]software interrupt will run during timer interrupt
[IN SOFTWARE INTERRUPT]software interrupt hit 0 times
[IN SOFTWARE INTERRUPT]software interrupt end
[IN TIMER INTERRUPT]timer interrupt end
-------------------
[IN TIMER INTERRUPT]timer interrupt hit 1 times
[IN TIMER INTERRUPT]trigger software interrupt
[IN TIMER INTERRUPT]software interrupt will run during timer interrupt
[IN SOFTWARE INTERRUPT]software interrupt hit 1 times
[IN SOFTWARE INTERRUPT]software interrupt end
[IN TIMER INTERRUPT]timer interrupt end

可以看到在低優先級timer中斷執行時,將被高優先級soft中斷打斷,從而形成中斷嵌套。

這里把軟件中斷配置成非向量中斷(記得去掉IRQ的__INTERRUPT修飾)效果也是一樣的,
后者把timer中斷換成向量中斷也是可行的(1、IRQ加上的__INTERRUPT修飾 2、IRQ里開始加上SAVE_IRQ_CSR_CONTEXT();,結束加上RESTORE_IRQ_CSR_CONTEXT();)。

以上就是芯來eclic中斷相關的內容,如有紕漏,還請各位看官大佬予以指出

參考:
芯來科技N級別指令集架構

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

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

相關文章

計算機網絡-LDP標簽發布與管理

前面學習了LDP建立鄰居,建立會話,今天來學習在MPLS中的標簽發布與管理。 在MPLS網絡中,下游LSR決定標簽和FEC的綁定關系,并將這種綁定關系發布給上游LSR。LDP通過發送標簽請求和標簽映射消息,在LDP對等體之間通告FEC和…

Go語言運算符詳解

文章目錄 1. 算術運算符2. 關系運算符3. 邏輯運算符4. 位運算符5. 賦值運算符6. 其他運算符運算符優先級注意事項 Go語言提供了與其他語言類似的運算符,包括算術運算符、關系運算符、邏輯運算符、位運算符、賦值運算符等。這些運算符即可滿足基本的運算需求。 1. 算…

Selenium模擬人類行為,操作網頁的方法(全)

看到有朋友評論問,用selenium怎么模仿人類行為,去操作網頁的頁面呢? 我想了想,這確實是一個很大的點,不應該是一段代碼能解決的, 就像是,如果讓程序模擬人類的行為。例如模擬人類買菜,做飯&am…

RabbitMQ的工作隊列模式和路由模式有什么區別?

RabbitMQ 的工作隊列模式(Work Queues)和路由模式(Routing)是兩種不同的消息傳遞模式,主要區別在于消息的分發邏輯和使用場景。以下是它們的核心差異: 1. 工作隊列模式(Work Queues&#xff09…

牛客練習賽138(首篇萬字題解???)

賽時成績如下: 1. 小s的簽到題 小s拿到了一個比賽榜單,他要用最快的速度找到簽到題,但是小s腦子還是有點暈,請你幫幫小s,助力他找到簽到題。 比賽榜單是一個 2 行 n 列的表格: 第一行是 n 個大寫字母&#…

linux0.11內核源碼修仙傳第十六章——獲取硬盤信息及根目錄掛載

🚀 前言 書接第十四章:linux0.11內核源碼修仙傳第十四章——進程調度之fork函數,在這一節博客中已經通過fork進程創建了一個新的進程1,并且可以被調度,接下來接著主線繼續走下去。希望各位給個三連,拜托啦&…

mobile自動化測試-appium webdriverio

WebdriverIO是一款支持mobile app和mobile web自動化測試框架,與appium集成,完成對mobile應用測試。支持ios 和android兩種平臺,且功能豐富,是mobile app自動化測試首選框架。且官方還提供了mobile 應用測試example代碼&#xff0…

Kubernetes排錯(十):常見網絡故障排查

通用排查思路 Kubernetes 集群內不同服務之間的網絡通信出現異常,表現為請求超時、連接失敗或響應緩慢,導致服務間依賴關系中斷,依賴服務的功能不可用或性能下降,甚至可能波及整個微服務架構,引發連鎖反應&#xff0c…

PyTorch 張量與自動微分操作

筆記 1 張量索引操作 import torch ? # 下標從左到右從0開始(0->第一個值), 從右到左從-1開始 # data[行下標, 列下標] # data[0軸下標, 1軸下標, 2軸下標] ? def dm01():# 創建張量torch.manual_seed(0)data torch.randint(low0, high10, size(4, 5))print(data->,…

接口的基礎定義與屬性約束

在 TypeScript 中,接口(Interface)是一個非常強大且常用的特性。接口定義了對象的結構,包括對象的屬性和方法,可以為對象提供類型檢查和約束。通過接口,我們可以清晰地描述一個對象應該具備哪些屬性和方法。…

高效全能PDF工具,支持OCR識別

軟件介紹 PDF XChange Editor是一款功能強大的PDF編輯工具,支持多種操作功能,不僅可編輯PDF內容與圖片,還具備OCR識別表單信息的能力,滿足多種場景下的需求。 軟件特點 這款PDF編輯器完全免費,用戶下載后直接…

OpenCV 中用于背景分割的一個類cv::bgsegm::BackgroundSubtractorGMG

操作系統:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 編程語言:C11 算法描述 cv::bgsegm::BackgroundSubtractorGMG 是 OpenCV 中用于背景分割的一個類,它實現了基于貝葉斯推理的背景建模算法(Bayesi…

MongoDB知識框架

簡介:MongoDB 是一個基于分布式文件存儲的數據庫,屬于 NoSQL 數據庫產品,以下是其知識框架總結: 一、數據模型 文檔:MongoDB 中的數據以 BSON(二進制形式的 JSON)格式存儲在集合中,…

WEBSTORM前端 —— 第2章:CSS —— 第8節:網頁制作2(小兔鮮兒)

目錄 1.項目目錄 2.SEO 三大標簽 3.Favicon 圖標 4.版心 5.快捷導航(shortcut) 6.頭部(header) 7.底部(footer) 8.banner 9.banner – 圓點 10.新鮮好物(goods) 11.熱門品牌(brand) 12.生鮮(fresh) 13.最新專題(topic) 1.項目目錄 【xtx-pc】 ima…

1、RocketMQ 核心架構拆解

1. 為什么要使用消息隊列? 消息隊列(MQ)是分布式系統中不可或缺的中間件,主要解決系統間的解耦、異步和削峰填谷問題。 解耦:生產者和消費者通過消息隊列通信,彼此無需直接依賴,極大提升系統靈…

[Linux網絡_71] NAT技術 | 正反代理 | 網絡協議總結 | 五種IO模型

目錄 1.NAT技術 NAPT 2.NAT和代理服務器 3.網線通信各層協議總結 補充說明 4.五種 IO 模型 1.什么是IO?什么是高效的IO? 2.有那些IO的方式?這么多的方式,有那些是高效的? 異步 IO 🎣 關鍵缺陷類比…

Unity基礎學習(八)時間相關內容Time

眾所周知,每一個游戲都會有自己的時間。這個時間可以是內部,從游戲開始的時間,也可以是外部真實的物理時間,時間相關內容 主要用于游戲中 參與位移計時 時間暫停等。那么我們今天就來看看Unity中和時間相關的內容。 Unity時間功能…

Java游戲服務器開發流水賬(1)游戲服務器的架構淺析

新項目立項停滯,頭大。近期讀老項目代碼看到Java,筆記記錄一下。 為什么要做服務器的架構 游戲服務器架構設計具有多方面的重要意義,它直接關系到游戲的性能、可擴展性、穩定性以及用戶體驗等關鍵因素 確保游戲的流暢運行 優化數據處理&a…

計算機視覺與深度學習 | 基于Transformer的低照度圖像增強技術

基于Transformer的低照度圖像增強技術通過結合Transformer的全局建模能力和傳統圖像增強理論(如Retinex),在保留顏色信息、抑制噪聲和平衡亮度方面展現出顯著優勢。以下是其核心原理、關鍵公式及典型代碼實現: 一、原理分析 1. 全局依賴建模與局部特征融合 Transformer的核…

Linux 文件目錄管理常用命令

pwd 顯示當前絕對路徑 cd 切換目錄 指令備注cd -回退cd …返回上一層cd ~切換到用戶主目錄 ls 列出目錄的內容 指令備注ls -a顯示當前目錄中的所有文件和目錄,包括隱藏文件ls -l以長格式顯示當前目錄中的文件和目錄ls -hl以人類可讀的方式顯示當前目錄中的文…