MicroBlaze로 AXI GPIO 외부 핀 인터럽트 구현

개요



MicroBlaze에서 외부 핀 입력으로부터의 인터럽트를 구현하고 AXI GPIO의 인터럽트와 AXI 인터럽트 컨트롤러의 사용법을 배웁니다.
인터럽트 처리는 앞으로 쓰려고 하고 있는 AXI Quad SPI나 AXI IIC등을 사용한 SPI나 I2C 통신을 하기 위해서 필요합니다.

환경


  • Vivado 2018.3

  • Block Design 만들기



    MicroBlaze 추가



    미리 Clocking Wizard로 100MHz의 시스템 클럭을 쉽게 해둔 상태에서 MicroBlaze를 추가합니다.

    Run Block Automation을 실행하여 아래 그림과 같이 설정합니다. Interrupt Controller의 검사는 필수입니다.

    Run Connection Automation을 실행한 후의 배선입니다. AXI Interrupt Controller에 연결된 Concat에 인터럽트 신호를 입력합니다.


    AXI GPIO 추가



    AXI GPIO를 추가하고 Run Connection Automation을 사용하여 배선합니다.
    GPIO 버스는 버튼 스위치가 연결됩니다.
    인터럽트를 활성화하고 ip2intc_irpt 핀을 AXI 인터럽트 컨트롤러에 연결합니다.


    UART 추가



    디버그 메시지 등을 표시하기 위해 UART를 추가합니다.
    이 부분은 보드에 따라 설정이 다르다고 생각하므로 설명은 생략합니다.


    인터럽트 입력 수 수정



    이번에는 GPIO Interrupt만 사용하므로 AXI Interrupt Controller에 연결된 Concat의 입력을 하나로 수정합시다.
    비어있는 핀이 있으면 SDK에서 프로젝트를 생성 할 때 오류가 발생하기 때문에주의하십시오.


    Bitstream 생성 및 SDK 프로젝트 만들기



    Block Design의 작성이 끝나면, 핀 배치의 설정등을 실시해 Generate Bitstream를 실시해 주세요.
    또한 Export Hardware를 실행한 다음 Xilinx SDK를 시작하십시오.

    SDK에서는 Hello World 템플릿 프로젝트를 생성합니다.

    샘플 코드


    #include <stdio.h>
    #include "platform.h"
    #include "xil_printf.h"
    #include "xintc.h"
    #include "xgpio.h"
    
    XGpio Gpio;
    XIntc Intc;
    
    // GPIO Interrupt Handler
    void GpioHandler(void *CallbackRef)
    {
        XGpio *GpioPtr = (XGpio *)CallbackRef;
        xil_printf("Gpio Interrupt!\r\n");
        // Clear the Interrupt
        XGpio_InterruptClear(GpioPtr, 1);
    }
    
    int main()
    {
        int Status;
    
        init_platform();
    
        // XGpioの初期化
        Status = XGpio_Initialize(&Gpio, XPAR_GPIO_0_DEVICE_ID);
        if(Status != XST_SUCCESS) return XST_FAILURE;
        // Buttonピンを入力に設定
        XGpio_SetDataDirection(&Gpio, 1, 1);
    
        // XIntcの初期化
        Status = XIntc_Initialize(&Intc, XPAR_INTC_0_DEVICE_ID);
        if(Status != XST_SUCCESS) return XST_FAILURE;
    
        // XGpioの割り込みで呼び出される関数を指定
        Status = XIntc_Connect(&Intc, XPAR_INTC_0_GPIO_0_VEC_ID,
                    (XInterruptHandler)GpioHandler,
                    (void *)&Gpio);
        if(Status != XST_SUCCESS) return XST_FAILURE;
    
        //XIntcをhardware interrupts onlyで開始
        Status = XIntc_Start(&Intc, XIN_REAL_MODE);
        if(Status != XST_SUCCESS) return XST_FAILURE;
    
        // XGpioの割り込みを有効化
        XIntc_Enable(&Intc, XPAR_INTC_0_GPIO_0_VEC_ID);
    
        // MicroBlazeの割り込み設定を初期化
        Xil_ExceptionInit();
        // MicroBlazeにXIntcからの割り込みを登録
        Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
                    (Xil_ExceptionHandler)XIntc_InterruptHandler,
                    &Intc);
        // MicroBlazeの割り込みを有効化
        Xil_ExceptionEnable();
    
        // GPIO Channel 1の割り込みを有効化
        XGpio_InterruptEnable(&Gpio, 1);
        // GPIOのグローバル割り込みを有効化
        XGpio_InterruptGlobalEnable(&Gpio);
    
        while(1);
    
        cleanup_platform();
        return 0;
    }
    

    실행 결과



    버튼 스위치를 누르면 인터럽트 핸들러 함수가 호출되었습니다.


    참고



    AXI GPIO 사용법은 여기를 참고하십시오.
    자일링스 AXI GPIO 사용법

    좋은 웹페이지 즐겨찾기