Zynq 割り込み main 関数 – タイマー割り込み理解メモ (4)

アイキャッチ

この記事の内容

Zynq でタイマー割り込みのテストプログラムの main 関数の内容のメモ。

このテストプログラムはFPGA設計大全第2版の第5章に載っています。RGB LED の色を一定時間ごとに変化させるプログラムです。

  1. タイマー割り込み
  2. 割り込みコントローラのドライバ初期化
  3. 割り込み処理関数の登録
  4. main 関数・プリプロセッサ・インスタンス変数宣言 ← この記事の内容

プリプロセッサ・インスタンス変数宣言

ファイルの先頭部分

#include "xparameters.h"
#include "xgpio.h"
#include "xscutimer.h"
#include "xscugic.h"
#include "xil_exception.h"
#include "xil_printf.h"

#define TIMER_LOAD_VALUE 325000000 /* PYNQ-Z1ボード CPU周波数650MHz の1/2 */
#define LED_CHANNEL 1              /* ch1: LED, ch2: BTN */

/* 各周辺回路のインスタンス変数 */
XGpio Gpio;
XScuTimer TimerInstance;
XScuGic IntcInstance;
  • 必要なヘッダファイルの読み込み
  • パラメータ設定
  • ペリフェラルのインスタンス変数宣言 (グローバル変数として)

main 関数

main 関数

int main()
{
    int Status;
    XScuTimer_Config *ConfigPtr;
    xil_printf("Timer Interrupt Test.\n\n");

    /* GPIOの初期化 */
    Status = XGpio_Initialize(&Gpio, XPAR_GPIO_0_DEVICE_ID);
    if (Status != XST_SUCCESS)
        return XST_FAILURE;
    XGpio_SetDataDirection(&Gpio, LED_CHANNEL, 0);
    XGpio_DiscreteWrite(&Gpio, LED_CHANNEL, led_rgb(0));

    /* タイマーのドライバ初期化 */
    ConfigPtr = XScuTimer_LookupConfig(XPAR_XSCUTIMER_0_DEVICE_ID);
    Status = XScuTimer_CfgInitialize(&TimerInstance, ConfigPtr, ConfigPtr->BaseAddr);
    if (Status != XST_SUCCESS)
        return XST_FAILURE;

    /* 割り込み関連初期化と割り込み処理関数の登録 */
    Status = ScuGicInt_Init();
    if (Status != XST_SUCCESS)
        return XST_FAILURE;
    Status = ScuGicInt_Reg(XPAR_SCUTIMER_INTR, &TimerInstance, TimerCounterHandler);
    if (Status != XST_SUCCESS)
        return XST_FAILURE;

    /* タイマー初期設定と開始 */
    XScuTimer_EnableAutoReload(&TimerInstance);
    XScuTimer_LoadTimer(&TimerInstance, TIMER_LOAD_VALUE);
    XScuTimer_EnableInterrupt(&TimerInstance);
    XScuTimer_Start(&TimerInstance);

    while (1);
    return 0;
}

以下、内容メモ。


XScuTimer_Config *ConfigPtr;

タイマーの「コンフィグレーション」を宣言。

GPIO の初期化

Status = XGpio_Initialize(&Gpio, XPAR_GPIO_0_DEVICE_ID);

if (Status != XST_SUCCESS)
    return XST_FAILURE;

GPIO を初期化する。

XGpio_Initialize の第1引数は、GPIO のインスタンス、第2引数はデバイス ID (ハードウェア的に決まっている)

初期化に失敗したらこの時点で処理を終了する。


XGpio_SetDataDirection(&Gpio, LED_CHANNEL, 0);

GPIO の入出力方向を出力に設定する。

引数1つ目は GPIO のインスタンス、2つ目はチャンネル (1 か 2) 、3つ目は方向 (0 が出力、1 が入力)。


XGpio_DiscreteWrite(&Gpio, LED_CHANNEL, led_rgb(0));

XGpio_DiscreteWrite で GPIO に任意の値 (出力値) をライトする。引数3つ目が出力したい値。

ここでは初期化のためにLEDを消灯。led_rgb 関数は省略。

タイマーのドライバ初期化

初期化の流れは、割り込みコントローラのときと同じ。

ConfigPtr = XScuTimer_LookupConfig(XPAR_XSCUTIMER_0_DEVICE_ID);

タイマーのコンフィグレーションを調べる。

正常終了するとコンフィグレーションのポインタが返り、異常終了時は NULL が返る。

XPAR_XSCUTIMER_0_DEVICE_ID は xparameters.h で定義されている。


Status = XScuTimer_CfgInitialize(&TimerInstance, ConfigPtr, ConfigPtr->BaseAddr);

タイマーを初期化する。

引数は 割り込みコントローラの CfgInitialize と同様。

割り込み関連初期化と割り込み処理関数の登録

Status = ScuGicInt_Init();

割り込みコントローラのドライバ初期化 を実行。


Status = ScuGicInt_Reg(XPAR_SCUTIMER_INTR, &TimerInstance, TimerCounterHandler);

割り込み処理関数登録 を実行。

タイマー割り込み発生時に実行する関数として、別記事で作成した タイマー割り込み関数 を第3引数で指定している。

タイマー初期設定と開始

XScuTimer_EnableAutoReload(&TimerInstance);

タイマーの自動リロードを有効化。


XScuTimer_LoadTimer(&TimerInstance, TIMER_LOAD_VALUE);

タイムアウト値の設定 (第2引数の値がタイマーカウンタに設定される)。


XScuTimer_EnableInterrupt(&TimerInstance);

タイマー割り込みを有効化。


XScuTimer_Start(&TimerInstance);

タイマーの動作をスタート。

関連記事・参考文献

関連記事

当ブログ内の関連記事

  1. タイマー割り込み
  2. 割り込みコントローラのドライバ初期化
  3. 割り込み処理関数の登録
  4. main 関数・プリプロセッサ・インスタンス変数宣言 ← この記事の内容

参考文献

  • Xilinx Vitis Drivers API Documentation “gpio_v4_8” (Vitis 内から参照可能)
    (PS7_GPIO ではなく、AXI_GPIO のほうです)
  • Xilinx Vitis Drivers API Documentation “scutimer_v2_3” (Vitis内から参照可能)
  • FPGAプログラム大全 Xilinx編 第2版

使用したボード PYNQ-Z1 については、割り込みハンドラの記事の最後 をご覧ください。

スポンサーリンク