0


【ZYNQ 开发】AMP双arm交互 - 软中断(2)

1. 实验目的:

这篇主要讲解上一篇未讲解的软中断实现过程。在上节课的搭建的代码框架基础上,我们今天实现两个arm核之间使用软中断来实现一些交互的操作。

2. 实验原理:

2.1 什么是软中断?和硬中断有什么区别?

软中断和硬中断都是计算机系统中用于处理异步事件的机制,但它们有一些区别。

1. 软中断(Software Interrupt):
- 来源: 软中断是由软件(如操作系统或应用程序)产生的中断请求,通常是为了执行特定的系统调用或触发特殊事件。
- 触发时机: 软中断是通过软件调用指令(例如系统调用指令)来触发的,通常是为了请求某种服务或执行某个操作。
- 处理机制: 软中断的处理方式与硬中断类似,会导致处理器跳转到预定义的软中断处理程序,执行相应的任务。
- 异步性: 软中断也是异步的,因为它们的触发是由软件主动发起的,不受处理器当前执行任务的控制。

总的来说,硬中断是由硬件设备触发,而软中断是由软件发起的。两者都用于处理异步事件,但触发和处理的机制略有不同。在操作系统中,软中断常常用于系统调用、异常处理等,而硬中断用于处理硬件设备的异步事件。

2. 硬中断(Hardware Interrupt):
- 来源:硬中断是由硬件设备(如外部设备、定时器等)发送给处理器的信号,表示发生了一个事件需要处理。
- 触发时机:硬中断是通过硬件信号触发的,即硬件设备向处理器发送中断请求。
- 处理机制:处理器在收到硬中断信号后,会中断当前执行的任务,跳转到中断服务程序(Interrupt Service Routine,ISR)来处理中断事件。ISR是一段预先定义的代码,用于响应和处理特定中断。
- 异步性: 硬中断是异步的,因为它们是由硬件设备触发的,处理器无法预测中断的发生时机。

2.2 软中断的实现流程

首先我们通过查询手册UG585发现我们的软中断ID有16个,我们可以任意选择其中两个来使用,我们在这使用0x0D和0x0E

之后就要进入中断注册的流程
函数功能****函数名称()
初始化异常处理

**Xil_ExceptionInit(); **

初始化中断控制器

XScuGic_LookupConfig();

XScuGic_CfgInitialize();

注册异常处理回调函数到CPU

Xil_ExceptionRegisterHandler();

连接软中断中断信号并注册软中断回调函数

XScuGic_Connect();

使能中断控制器中的软中断中断

XScuGic_Enable();

使能异常处理

Xil_ExceptionEnableMask();

2.3 CPU0的软中断实现

首先展示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");
}

2.4 CPU1的软中断实现

#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");
}

最后结果如下:

3. 实验结论:

到这就完成了软中断的过程了,我们需要注意的是中断的初始化流程。之后会讲解硬中断的过程

标签: arm开发

本文转载自: https://blog.csdn.net/Gatsby2023/article/details/135753401
版权归原作者 Gatsby2023 所有, 如有侵权,请联系我们删除。

“【ZYNQ 开发】AMP双arm交互 - 软中断(2)”的评论:

还没有评论