Nios® II デバッグ手法シリーズ
このシリーズでは Nios® II プロセッサーのデバッグに役に立つ便利機能について紹介します。
JTAG UART を使ったコンソール出力
デバッグの際、stdout や stderr に JTAG UART モジュールを割り当て※1、printf() などを使って値や状態を出力し処理の流れや周辺回路の状態などを検証する方法は、簡単に扱えるため比較的よく使われます。しかし、JTAG UART を使った場合、コンソール※2が停止すると全ての処理が停止してしまいます。
- ※1 JTAG UART を実装すると BSP はデフォルトで stdin / stdout / stderr に JTAG UART を割り当てます。
- ※2 Nios® II Software Build Tools (SBT) for Exlipse の Debug Perspective における Nios® II Console ウィンドウや、Nios® II Command Shell における nios2-terminal など。
これは、標準ドライバーの場合、コンソールへの送受信処理は割り込み※3で実装されていますが、JTAG UART モジュールの FIFO およびドライバーのサイクリック・バッファーに空きが無くなると、出力関数(printf() など)の中で空き待ちのループに入ってしまうためです。
- ※3 Reduced device driver を使用している場合、割り込みでは無く関数の中に送受信処理が実装されていますので、タイムアウト制御はできません。また、JTAG UART モジュールの FIFO が Full になった段階で空き待ちのループに入ります。
JTAG UART ドライバーのタイムアウト制御
標準ドライバーを使用する場合、併せて Interval Timer モジュールを実装し、それを sys_clk_timer に割り当てる事で、コンソールが停止しても一定時間後に出力関数のブロックを解き、処理を再開させる事が出来ます。ただし、タイムアウトした場合には JTAG UART ドライバーの処理は切り離されますので、再度コンソールに接続してもバッファー内に残っているデータが送信される事はありますが、再び、出力関数が正常に動作する事にはなりません。
[ BSP Editor ]
タイムアウト時間の変更
タイムアウト時間はデフォルトで 10 秒となっています。タイムアウト時間を変更するには ioctl()(実装はaltera_avalon_jtag_uart_ioctl()) を使って設定可能です。
#include "sys/ioctl.h"
int main()
{
int timeout = 2;
ioctl(STDOUT_FILENO, TIOCSTIMEOUT, &timeout);
タイムアウトの値は秒で設定しますので、上記の場合 2 秒後にタイムアウトする設定をしています。なお、タイムアウト値に 1 以下の値を設定した場合、タイムアウトは無効となりますのでご注意ください。
おまけ
上記の回避策に printf をすべてコメントアウトすることも可能ですが、処理時間が変わってしまうことに考慮が必要です。また、printf をすべてコメントアウトするのは面倒なため、予め専用のデバッグログとして実装しておくと一括でコメントアウトできますので必要に応じて活用ください。
#define DEBUG_MODE (1) /* 0:Disable log print / 1:Enable log print */
#if DEBUG_MODE
#define dprintf(...) {printf("%s(%3d): ", __func__, __LINE__); printf(__VA_ARGS__);}
//#define dprintf(...) {printf(__VA_ARGS__);}
#else
#define dprintf(...)
#endif
int main()
{
dprintf("Hello \n");
return 0;
}
おすすめページ
弊社では Nios® II に関する各種情報とまとめた「Nios® II まとめページ」をご用意しております。本記事以外にも有用な情報が満載ですのでこちらも併せてご確認ください。