• Zynq-7000 FreeRTOS(二)中断:PL中断请求


      总结Zynq-7000的PL发送给PS一个中断请求,为FreeRTOS中断做准备。

      UG585的P225显示了系统的中断框图,如下图所示。

    图:ZYNQ器件的中断框图

      UG585的P227画出来中断控制器的框图,如下图所示。PL PS 部分的中断经过 ICD 控制器分发器后同时进入 CPU1 CPU0

    图:中断控制器示意图

      UG585的P57,PL PS 部分一共有 20 个中断可以使用。 其中 4 个是快速中断。 如下表所示。

    表:PL的中断信号 

     

      ZYNQ的每一个CPU还有16个软件中断,Software Generated Interrupts (SGI) ,UG585的P229显示了SGI,如下图所示。

    表:ZYNQ的软件中断SGI

      文档在P229,描述了CPU私有端口中断CPU Private Peripheral Interrupts (PPI) 和共享中断Shared Peripheral Interrupts (SPI) ,这些中断都是固定死的, 不能修改。 PPI中有 2 PL 到 每个CPU 的快速中断 nFIQ ,ID号为28和31(nIRQ)。共享中断就是 PL 的中断可以发送给 PS 处理。  这里不再贴图。
      PS的设置如下图。

      Block Design如下图。

      黑金AX7010 开发板的 PL 部分板载了 4 个用户按键(KEY1~KEY4), 按键的信号连接到 ZYNQ的 BANK34 和 BANK35 的 IO 上。 按键都为低电平有效, 没有按下时,信号为高;按键按下时,信号为低。 4 个用户按键的原理图如下图所示。

    图:黑金开发板按键原理图

     代码:

    #include <stdio.h>
    #include "xscugic.h"
    #include "xil_exception.h"
    
    #define INT_CFG0_OFFSET 0x00000C00
    
    // Parameter definitions
    #define SW1_INT_ID              61
    #define SW2_INT_ID              62
    
    #define INTC_DEVICE_ID          XPAR_PS7_SCUGIC_0_DEVICE_ID
    #define INT_TYPE_RISING_EDGE    0x03
    #define INT_TYPE_HIGHLEVEL      0x01
    #define INT_TYPE_MASK           0x03
    
    static XScuGic INTCInst;
    
    static void SW_intr_Handler(void *param);
    static int IntcInitFunction(u16 DeviceId);
    
    static void SW_intr_Handler(void *param)
    {
        int sw_id = (int)param;
        printf("SW%d int
    
    ", sw_id);
    }
    
    void IntcTypeSetup(XScuGic *InstancePtr, int intId, int intType)
    {
        int mask;
    
        intType &= INT_TYPE_MASK;
        mask = XScuGic_DistReadReg(InstancePtr, INT_CFG0_OFFSET + (intId/16)*4);
        mask &= ~(INT_TYPE_MASK << (intId%16)*2);
        mask |= intType << ((intId%16)*2);
        XScuGic_DistWriteReg(InstancePtr, INT_CFG0_OFFSET + (intId/16)*4, mask);
    }
    
    int IntcInitFunction(u16 DeviceId)
    {
        XScuGic_Config *IntcConfig;
        int status;
    
        // Interrupt controller initialisation
        IntcConfig = XScuGic_LookupConfig(DeviceId);
        status = XScuGic_CfgInitialize(&INTCInst, IntcConfig, IntcConfig->CpuBaseAddress);
        if(status != XST_SUCCESS) return XST_FAILURE;
    
        // Call to interrupt setup
        Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
                                     (Xil_ExceptionHandler)XScuGic_InterruptHandler,
                                     &INTCInst);
        Xil_ExceptionEnable();
    
        // Connect SW1~SW3 interrupt to handler
        status = XScuGic_Connect(&INTCInst,
                                 SW1_INT_ID,
                                 (Xil_ExceptionHandler)SW_intr_Handler,
                                 (void *)1);
        if(status != XST_SUCCESS) return XST_FAILURE;
    
        status = XScuGic_Connect(&INTCInst,
                                 SW2_INT_ID,
                                 (Xil_ExceptionHandler)SW_intr_Handler,
                                 (void *)2);
        if(status != XST_SUCCESS) return XST_FAILURE;
    
    
    
        // Set interrupt type of SW1~SW3 to rising edge
        IntcTypeSetup(&INTCInst, SW1_INT_ID, INT_TYPE_RISING_EDGE);
        IntcTypeSetup(&INTCInst, SW2_INT_ID, INT_TYPE_RISING_EDGE);
    
    
        // Enable SW1~SW3 interrupts in the controller
        XScuGic_Enable(&INTCInst, SW1_INT_ID);
        XScuGic_Enable(&INTCInst, SW2_INT_ID);
    
    
        return XST_SUCCESS;
    }
    
    int main(void)
    {
        print("PL int test
    
    ");
        IntcInitFunction(INTC_DEVICE_ID);
        while(1);
        return 0;
    }
  • 相关阅读:
    边界值分析
    等价类划分
    手工检测SQL注入(安全性测试)
    Web安全性测试
    Jmeter使用流程及简单分析监控
    使用可视化工具redisclient连接redis
    Java ThreadLocal的使用
    jvm中的新生代Eden和survivor区
    策略模式和工厂模式的区别
    java将一数组乱序排列
  • 原文地址:https://www.cnblogs.com/yiwenbo/p/10730845.html
Copyright © 2020-2023  润新知