赞
踩
这篇主要讲解上一篇未讲解的软中断实现过程。在上节课的搭建的代码框架基础上,我们今天实现两个arm核之间使用软中断来实现一些交互的操作。
软中断和硬中断都是计算机系统中用于处理异步事件的机制,但它们有一些区别。
1. 软中断(Software Interrupt):
- 来源: 软中断是由软件(如操作系统或应用程序)产生的中断请求,通常是为了执行特定的系统调用或触发特殊事件。
- 触发时机: 软中断是通过软件调用指令(例如系统调用指令)来触发的,通常是为了请求某种服务或执行某个操作。
- 处理机制: 软中断的处理方式与硬中断类似,会导致处理器跳转到预定义的软中断处理程序,执行相应的任务。
- 异步性: 软中断也是异步的,因为它们的触发是由软件主动发起的,不受处理器当前执行任务的控制。
总的来说,硬中断是由硬件设备触发,而软中断是由软件发起的。两者都用于处理异步事件,但触发和处理的机制略有不同。在操作系统中,软中断常常用于系统调用、异常处理等,而硬中断用于处理硬件设备的异步事件。
2. 硬中断(Hardware Interrupt):
- 来源:硬中断是由硬件设备(如外部设备、定时器等)发送给处理器的信号,表示发生了一个事件需要处理。
- 触发时机:硬中断是通过硬件信号触发的,即硬件设备向处理器发送中断请求。
- 处理机制:处理器在收到硬中断信号后,会中断当前执行的任务,跳转到中断服务程序(Interrupt Service Routine,ISR)来处理中断事件。ISR是一段预先定义的代码,用于响应和处理特定中断。
- 异步性: 硬中断是异步的,因为它们是由硬件设备触发的,处理器无法预测中断的发生时机。
首先我们通过查询手册UG585发现我们的软中断ID有16个,我们可以任意选择其中两个来使用,我们在这使用0x0D和0x0E。
之后就要进入中断注册的流程
函数功能 | 函数名称() |
初始化异常处理
|
Xil_ExceptionInit();
|
初始化中断控制器
|
XScuGic_LookupConfig();
XScuGic_CfgInitialize();
|
注册异常处理回调函数到CPU
|
Xil_ExceptionRegisterHandler();
|
连接软中断中断信号并注册软中断回调函数
|
XScuGic_Connect();
|
使能中断控制器中的软中断中断
|
XScuGic_Enable();
|
使能异常处理
|
Xil_ExceptionEnableMask();
|
--- | --- |
首先展示CPU0的相关中断的回调函数和异常的回调函数
- #include <stdio.h>
- #include "xil_printf.h"
- #include "xscugic.h"
- #include "xparameters.h"
- #define COMM_VAL (*(volatile unsigned long*)(0xFFFF0000))
- #define CPU0_SW_INTR 0x0d
- #define CPU1_SW_INTR 0x0E
- #define GIC_ID XPAR_PS7_SCUGIC_0_DEVICE_ID
-
-
- //initial software interrupt 0x0d
- int initSwIntr();
- //
- void cpu0IntrHandler(void * CallBackRef);
- static XScuGic ScuGic;
- static XScuGic_Config * ScuGicCfgPtr;
- int main()
- {
- COMM_VAL = 0;
- //disable onchip memory cache xapp1079
- Xil_SetTlbAttributes(0xFFFF0000,0x14de2);
- int status;
- status = initSwIntr();
- if(status != XST_SUCCESS){
- return status;
- }
- while(1){
- printf("Hello world cpu0!\n\r");
- //accept CPU1 interrupt
- XScuGic_SoftwareIntr(&ScuGic,CPU1_SW_INTR,XSCUGIC_SPI_CPU1_MASK);
- COMM_VAL =1;
- while(COMM_VAL == 1){
- }
- }
- return 0;
- }
-
- //initial software interrept
- int initSwIntr(){
- int status;
- Xil_ExceptionInit();
-
- ScuGicCfgPtr = XScuGic_LookupConfig(GIC_ID);
- status = XScuGic_CfgInitialize(&ScuGic,ScuGicCfgPtr,ScuGicCfgPtr->CpuBaseAddress);
- if(status != XST_SUCCESS){
- return status;
- }
- Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,(Xil_ExceptionHandler)XScuGic_InterruptHandler,&ScuGic);
- status = XScuGic_Connect(&ScuGic,CPU0_SW_INTR,(Xil_ExceptionHandler)cpu0IntrHandler,&ScuGic);
- if(status != XST_SUCCESS){
- return status;
- }
- XScuGic_Enable(&ScuGic,CPU0_SW_INTR);
- Xil_ExceptionEnable();
- return XST_SUCCESS;
- }
-
- void cpu0IntrHandler(void * CallBackRef){
- printf("cpu1 interrupt cpu0 !\n\r");
- }
- #include <stdio.h>
- #include "xil_printf.h"
- #include "xscugic.h"
- #include "xparameters.h"
- #define COMM_VAL (*(volatile unsigned long*)(0xFFFF0000))
- #define CPU0_SW_INTR 0x0d
- #define CPU1_SW_INTR 0x0E
- #define GIC_ID XPAR_PS7_SCUGIC_0_DEVICE_ID
- //initial software interrupt 0x0d
- int initSwIntr();
- void cpu1IntrHandler(void * CallBackRef);
- static XScuGic ScuGic;
- static XScuGic_Config * ScuGicCfgPtr;
- int main()
- {
- COMM_VAL =0;
- //disable onchip memory cache xapp1079
- Xil_SetTlbAttributes(0xFFFF0000,0x14de2);
- int status;
- status = initSwIntr();
- if(status != XST_SUCCESS){
- return status;
- }
- while(1){
- printf("Hello world cpu1!\n\r");
- //accept CPU0 interrupt
- XScuGic_SoftwareIntr(&ScuGic,CPU0_SW_INTR,XSCUGIC_SPI_CPU0_MASK);
- COMM_VAL =0;
- while(COMM_VAL == 0){
- }
- }
- return 0;
- }
-
- //initial software interrept
- int initSwIntr(){
- int status;
- Xil_ExceptionInit();
- ScuGicCfgPtr = XScuGic_LookupConfig(GIC_ID);
- status = XScuGic_CfgInitialize(&ScuGic,ScuGicCfgPtr,ScuGicCfgPtr->CpuBaseAddress);
- if(status != XST_SUCCESS){
- return status;
- }
- Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,(Xil_ExceptionHandler)XScuGic_InterruptHandler,&ScuGic);
- status = XScuGic_Connect(&ScuGic,CPU1_SW_INTR,(Xil_ExceptionHandler)cpu1IntrHandler,&ScuGic);
- if(status != XST_SUCCESS){
- return status;
- }
- XScuGic_Enable(&ScuGic,CPU1_SW_INTR);
- Xil_ExceptionEnable();
- return XST_SUCCESS;
- }
- void cpu1IntrHandler(void * CallBackRef){
- printf("cpu0 interrupt cpu1 !\n\r");
- }
最后结果如下:
到这就完成了软中断的过程了,我们需要注意的是中断的初始化流程。之后会讲解硬中断的过程
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。