当前位置:   article > 正文

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

zynq xil_settlbattributes

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的相关中断的回调函数和异常的回调函数

  1. #include <stdio.h>
  2. #include "xil_printf.h"
  3. #include "xscugic.h"
  4. #include "xparameters.h"
  5. #define COMM_VAL (*(volatile unsigned long*)(0xFFFF0000))
  6. #define CPU0_SW_INTR 0x0d
  7. #define CPU1_SW_INTR 0x0E
  8. #define GIC_ID XPAR_PS7_SCUGIC_0_DEVICE_ID
  9. //initial software interrupt 0x0d
  10. int initSwIntr();
  11. //
  12. void cpu0IntrHandler(void * CallBackRef);
  13. static XScuGic ScuGic;
  14. static XScuGic_Config * ScuGicCfgPtr;
  15. int main()
  16. {
  17. COMM_VAL = 0;
  18. //disable onchip memory cache xapp1079
  19. Xil_SetTlbAttributes(0xFFFF0000,0x14de2);
  20. int status;
  21. status = initSwIntr();
  22. if(status != XST_SUCCESS){
  23. return status;
  24. }
  25. while(1){
  26. printf("Hello world cpu0!\n\r");
  27. //accept CPU1 interrupt
  28. XScuGic_SoftwareIntr(&ScuGic,CPU1_SW_INTR,XSCUGIC_SPI_CPU1_MASK);
  29. COMM_VAL =1;
  30. while(COMM_VAL == 1){
  31. }
  32. }
  33. return 0;
  34. }
  35. //initial software interrept
  36. int initSwIntr(){
  37. int status;
  38. Xil_ExceptionInit();
  39. ScuGicCfgPtr = XScuGic_LookupConfig(GIC_ID);
  40. status = XScuGic_CfgInitialize(&ScuGic,ScuGicCfgPtr,ScuGicCfgPtr->CpuBaseAddress);
  41. if(status != XST_SUCCESS){
  42. return status;
  43. }
  44. Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,(Xil_ExceptionHandler)XScuGic_InterruptHandler,&ScuGic);
  45. status = XScuGic_Connect(&ScuGic,CPU0_SW_INTR,(Xil_ExceptionHandler)cpu0IntrHandler,&ScuGic);
  46. if(status != XST_SUCCESS){
  47. return status;
  48. }
  49. XScuGic_Enable(&ScuGic,CPU0_SW_INTR);
  50. Xil_ExceptionEnable();
  51. return XST_SUCCESS;
  52. }
  53. void cpu0IntrHandler(void * CallBackRef){
  54. printf("cpu1 interrupt cpu0 !\n\r");
  55. }

2.4 CPU1的软中断实现

  1. #include <stdio.h>
  2. #include "xil_printf.h"
  3. #include "xscugic.h"
  4. #include "xparameters.h"
  5. #define COMM_VAL (*(volatile unsigned long*)(0xFFFF0000))
  6. #define CPU0_SW_INTR 0x0d
  7. #define CPU1_SW_INTR 0x0E
  8. #define GIC_ID XPAR_PS7_SCUGIC_0_DEVICE_ID
  9. //initial software interrupt 0x0d
  10. int initSwIntr();
  11. void cpu1IntrHandler(void * CallBackRef);
  12. static XScuGic ScuGic;
  13. static XScuGic_Config * ScuGicCfgPtr;
  14. int main()
  15. {
  16. COMM_VAL =0;
  17. //disable onchip memory cache xapp1079
  18. Xil_SetTlbAttributes(0xFFFF0000,0x14de2);
  19. int status;
  20. status = initSwIntr();
  21. if(status != XST_SUCCESS){
  22. return status;
  23. }
  24. while(1){
  25. printf("Hello world cpu1!\n\r");
  26. //accept CPU0 interrupt
  27. XScuGic_SoftwareIntr(&ScuGic,CPU0_SW_INTR,XSCUGIC_SPI_CPU0_MASK);
  28. COMM_VAL =0;
  29. while(COMM_VAL == 0){
  30. }
  31. }
  32. return 0;
  33. }
  34. //initial software interrept
  35. int initSwIntr(){
  36. int status;
  37. Xil_ExceptionInit();
  38. ScuGicCfgPtr = XScuGic_LookupConfig(GIC_ID);
  39. status = XScuGic_CfgInitialize(&ScuGic,ScuGicCfgPtr,ScuGicCfgPtr->CpuBaseAddress);
  40. if(status != XST_SUCCESS){
  41. return status;
  42. }
  43. Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,(Xil_ExceptionHandler)XScuGic_InterruptHandler,&ScuGic);
  44. status = XScuGic_Connect(&ScuGic,CPU1_SW_INTR,(Xil_ExceptionHandler)cpu1IntrHandler,&ScuGic);
  45. if(status != XST_SUCCESS){
  46. return status;
  47. }
  48. XScuGic_Enable(&ScuGic,CPU1_SW_INTR);
  49. Xil_ExceptionEnable();
  50. return XST_SUCCESS;
  51. }
  52. void cpu1IntrHandler(void * CallBackRef){
  53. printf("cpu0 interrupt cpu1 !\n\r");
  54. }

最后结果如下:

3. 实验结论:

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/274058
推荐阅读
相关标签
  

闽ICP备14008679号