目次
この記事の内容
Zynq でタイマー割り込みのテストプログラムの main 関数の内容のメモ。
このテストプログラムはFPGA設計大全第2版の第5章に載っています。RGB LED の色を一定時間ごとに変化させるプログラムです。
- タイマー割り込み
- 割り込みコントローラのドライバ初期化
- 割り込み処理関数の登録
- 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);
タイマーの動作をスタート。
関連記事・参考文献
関連記事
当ブログ内の関連記事
- タイマー割り込み
- 割り込みコントローラのドライバ初期化
- 割り込み処理関数の登録
- 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 については、割り込みハンドラの記事の最後 をご覧ください。
コメントを残す