[X]关闭

[米联客-XILINX-H3_CZ08_7100] FPGA_SDK入门篇连载-17 PL中断实验

文档创建者:FPGA课程
浏览次数:128
最后更新:2024-09-27
文档课程分类-AMD-ZYNQ
AMD-ZYNQ: ZYNQ-SOC » 1_SDK应用方案(仅旗舰型号) » 1-SDK基础入门方案
本帖最后由 FPGA课程 于 2024-9-27 16:24 编辑

​ 软件版本:VIVADO2021.1
操作系统:WIN10 64bit
硬件平台:适用 XILINX A7/K7/Z7/ZU/KU 系列 FPGA
实验平台:米联客-MLK-H3-CZ08-7100开发板
板卡获取平台:https://milianke.tmall.com/
登录“米联客”FPGA社区 http://www.uisrc.com 视频课程、答疑解惑!


1概述
PL到PS的中断是ARM和FPGA交互中非常重要的一项功能。PS的中断控制器及时响应PL的中断,以通知CPU及时处理。本文通过按键输入,模拟中断信号的参数,通过简单的实验掌握PL到PS中断使用。然后在后续很多demo中,我们都会遇到PL到PS中断使用。虽然本文只用到了PL中断,但是在本文的第二下节,我们会对ZYNQ的中断资源做一个简要介绍。
本文实验目的:
1:熟悉ZYNQ的中断资源,并且重点掌握PL-PS的中断资源
2:搭建由FPGA按键输入模拟PL中断产生的的SOC工程
3:通过VITIS-SDK编写PL中断测试验证程序
2系统框图
e05dac91b9de46b4823d1ec20344b318.jpg
3PL中断资源简介
共有16个PL到PS中断通过Shared Peripheral Interrupts接入到CPU.
ee3a6e7a07de49b1b047e682a702ca23.jpg
PL-PS的中断资源分2组,第1组的中断号为68~61;第2组的中断号为15~8
16d4fa6f92234bc1a978ce0e2d79949b.jpg
4硬件电路分析
d657a26e05294a85b1391d54d3f7da8b.jpg
配套工程的FPGA PIN脚定义路径为soc_prj/uisrc/04_pin/ fpga_pin.xdc。
5搭建SOC系统工程
详细的搭建过程这里不再重复,对于初学读者如果还不清楚如何创建SOC工程的,请学习“01Vitis Soc开发入门”这篇文章。
5.1SOC系统工程
8e0463635ba84137acc372c01a1ea726.jpg
50953e44b6f24277891ef1be6e2cba47.jpg
5.2编译并导出平台文件
以下步骤简写,有不清楚的看第一篇文章。
1:单击Block文件à右键àGenerate the Output ProductsàGlobalàGenerate。
2:单击Block文件à右键à Create a HDL wrapper(生成HDL顶层文件)àLet vivado manager wrapper and auto-update(自动更新)。
3:添加配套工程路径下uisrc/04_pin/fpga_pin.xdc约束文件
4:生成Bit文件。
5:导出到硬件: FileàExport HardwareàInclude bitstream
6:导出完成后,对应工程路径的soc_hw路径下有硬件平台文件:system_wrapper.xsa的文件。根据硬件平台文件system_wrapper.xsa来创建需要Platform平台。
84659445503f4d3584b4fc4204fecef6.jpg
6搭建Vitis-sdk工程
创建soc_base sdk platform和APP工程的过程不再重复,如果不清楚请参考本章节第一个demo。
6.1创建SDK Platform工程
ae2322cf6b19440cbe680fbc7fa9714c.jpg
右击soc_base编译,编译的时间可能会有点长
6.2创建APP工程
fcc48ffcd3104b88bc582ecfb71c102e.jpg
7程序分析
在前面实验中,我们已经使用过PS的中断,比如GPIO中断、定时器中断、看门狗中断、I2C中断等等。其中关于sys_intr.c中的函数都做了详细介绍。所以本文开始不再介绍sys_intr.c中的函数。
7.1pl_intr_test.c测试主程序
  1. #include "sys_intr.h"
  2. #include "pl_intr.h"

  3. XScuGic Intc; //GIC

  4. void init_intr_sys(void)
  5. {
  6.         Init_Intr_System(&Intc);
  7.         pl_intr_init(&Intc);
  8.         Setup_Intr_Exception(&Intc);
  9. }

  10. int main(void)
  11. {
  12.         init_intr_sys();
  13.         while(1);
  14.     return 0;
  15. }
复制代码

7.2 pl_intr.c程序
  1. #include "pl_intr.h"
  2. //按键SW1中断回调
  3. void SW1_intr_Handler(void *param)
  4. {
  5.     int sw_id = (int)param;
  6.     printf("SW1=%d int\n\r", sw_id);
  7. }
  8. //按键SW2中断回调
  9. void SW2_intr_Handler(void *param)
  10. {
  11.     int sw_id = (int)param;
  12.     printf("SW2=%d int\n\r", sw_id);
  13. }

  14. //这个函数中,设置中断触发模式
  15. static void pl_intr_setup(XScuGic *InstancePtr, int intId, int intType)
  16. {
  17.     int mask;
  18.     intType &= PL_INT_TYPE_MASK;
  19.     mask = XScuGic_DistReadReg(InstancePtr, INT_CFG0_OFFSET + (intId/16)*4);
  20.     mask &= ~(PL_INT_TYPE_MASK << (intId%16)*2);
  21.     mask |= intType << ((intId%16)*2);
  22.     XScuGic_DistWriteReg(InstancePtr, INT_CFG0_OFFSET + (intId/16)*4, mask);
  23. }
  24. //PL 中断函数初始化
  25. int pl_intr_init(XScuGic * InstancePtr)
  26. {
  27.         int status;

  28.     // Connect SW1~SW2 interrupt to handler
  29.     status = XScuGic_Connect(InstancePtr,SW1_INT_ID,(Xil_ExceptionHandler)SW1_intr_Handler,(void *)1);

  30.     if(status != XST_SUCCESS) return XST_FAILURE;

  31.     status = XScuGic_Connect(InstancePtr,SW2_INT_ID,(Xil_ExceptionHandler)SW2_intr_Handler,(void *)2);

  32.     if(status != XST_SUCCESS) return XST_FAILURE;

  33.     // Set interrupt type of SW1~SW2 to rising edge
  34.     pl_intr_setup(InstancePtr, SW1_INT_ID, PL_INT_TYPE_RISING_EDGE);
  35.     pl_intr_setup(InstancePtr, SW2_INT_ID, PL_INT_TYPE_RISING_EDGE);

  36.     // Enable SW1~SW2 interrupts in the controller
  37.     XScuGic_Enable(InstancePtr, SW1_INT_ID);
  38.     XScuGic_Enable(InstancePtr, SW2_INT_ID);

  39.     return XST_SUCCESS;
  40. }
复制代码

1:pl_intr_init(XScuGic * InstancePtr)函数
这个函数中,我们设置了2个中断回调函数SW1_intr_Handler和SW2_intr_Handler,并且分别关联到GIC中断号61和62.
XScuGic_Connect(InstancePtr,SW1_INT_ID,(Xil_ExceptionHandler)SW1_intr_Handler,(void *)1)
XScuGic_Connect(InstancePtr,SW2_INT_ID,(Xil_ExceptionHandler)SW2_intr_Handler,(void *)2)
877339a99b0940ed8b347b28f3bfd626.jpg
读者可以看前面Setup_Intr_Exception函数中关于
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,(Xil_ExceptionHandler)XScuGic_InterruptHandler,(void *)IntcInstancePtr)函数的说明。
当有中断发生的时候,61和62相关的中断函数会被回调。
2:pl_intr_setup(XScuGic *InstancePtr, int intId, int intType)函数
这个函数中,设置中断触发模式。
我们这里的PL中断号是61 和62,我们以61计算。
中断配置寄存器的偏移地址为ICDICFR0=0x00001C00
中断配置寄存器每16个中断一组,(61/16)*4=12=0x0C
所以写入的寄存器的偏移地址是ICDICFR7=0x00001C0C
下图是ZYNQ的寄存器说明,我们对MPSOC的配置可以推到出来。
比如对于ZYNQ的61号中断,配置ICDICFR3寄存器的31:30可以设置触发模式是高电平触发,上升沿触发
40a3b2330cbd4bbbb6dc8f0aa71ad290.jpg
8方案演示
8.1硬件准备
本实验需要用到 JTAG 下载器、USB 转串口外设,另外需要把核心板上的 2P 模式开关设置到 JTAG 模式,即 ON ON(注意新版本的 MLK_H3_CZ08-7100-MZ7100FC),支持 JTAG 模式,对于老版本的核心板,JTAG 调试的时候 一定要拔掉 TF 卡,并且设置模式开关为 OFF OFF)
dc81afef6b4945a5b99b2fe5fdc43194.jpg
按下如上箭头所指的按键。
8.2实验结果
按下配套开发板上的PL 输入按键,输出结果如下:
df355e3602f244059cc8776b9175ef8b.jpg


您需要登录后才可以回帖 登录 | 立即注册

本版积分规则