[NXP マイコン初心者ガイド 11] へ | [NXP マイコン初心者ガイド 13] | ||
NXP マイコン初心者ガイド まとめサイト |
もくじ
- はじめに
- 1. Hello World サンプルプロジェクトの Debug Console の概要
- 2. Debug Console の初期化方法
- 3. 評価ボードにおける Debug Console のピンアサイン
- 4. Debug Console の Pin アサインを変更する方法
- 5. Pin 変更後の挙動確認
- 6. ADVANCED_ENABLE を有効にする
- 7. (おまけ) printf() と scanf() 機能テスト結果 とサンプルコード
- まとめ
はじめに
マイコン開発では printf() や scanf() などの標準入出力をシリアルターミナルとして実装することが多いですが、NXP から提供される SDK ではシリアルターミナルの実装に Debug Console 機能を使用しています。
この記事では、NXP が提供している Hello World サンプルプロジェクトで Debug Console がどのように実装されているかを解説し、FRDM-MCXN947 を参考に出力先の Pin を変更する方法をご紹介します。
対象デバイス、この記事で使用する評価ボードとバージョンは下記のとおりです
- MCX、LPC、Kinetis、i.MXRT ファミリー
- FRDM-MCXN947
- MCUXpresso SDK 2.16.000
SDK のインストール方法は下記コンテンツをご参照ください。
参考:[NXP マイコン初心者ガイド 1] MCUXpresso IDE でサンプルプロジェクトを作成する方法
ポイント:通常、NXP 純正評価ボード(EVK)を使用する場合、Debug 用 Port が決まっているため意識する必要はありませんが、カスタムボード向けポート(ピンアサイン)の変更が必要となる場合に参考になります。
1. Hello World サンプルプロジェクトの Debug Console の概要
表1 に Debug Console で使用するソフトウェア を一覧で掲載いたします。
図1 に Hello World サンプルプロジェクトの構造を掲載いたします。
LPUART を使用して Debug Console を実現していますが、fsl_debug_console.c や fsl_adapter_lpuart.c により抽象化されているため、ユーザーが直接 LPUART ドライバーを制御する必要がないことがわかります。
参考:MCUXpresso SDK API Reference Manual: Debug Console (nxp.com)
Hello World main コード | hello_world.c |
Application ソフトウェア |
Debug Console コード |
fsl_debug_console.c fsl_debug_console.h |
Debug Console の初期化 |
UART HAL コード |
fsl_adapter_lpuart.c fsl_adapter_uart.h |
UART に必要な処理が網羅的に実装されている HAL |
LPUART ドライバー |
fsl_lpuart.c fsl_lpuart.h |
LPUART を制御するために必要な処理が実装されているドライバー |
図1:Hello World サンプルプロジェクト
2. Debug Console の初期化方法
図2 に Hello World サンプルプロジェクトの Main 処理を掲載します。
先頭で Debug Console 用の Clock 設定を実行後、BOARD_InitDebugConsole() 関数を実行して初期化しています。
図2:Hello World サンプルプロジェクトの Main 処理
2-1. BOARD_InitDebugConsole() の中身
BOARD_InitDebugConsole() の中身をみていきましょう。<Project Dir>/board/board.c に記載があります。
DbgConsole_Init() の引数に、BOARD_DEBUG_UART_INSTANCE、BOARD_DEBUG_UART_BAUDRATE、BOARD_DEBUG_UART_TYPE、BOARD_DEBUG_UART_CLK_FREQ を渡しています。
図3:BOARD_InitDebugConsole の記述
この引数の中身は<Project Dir>/board/board.h に記載があり、下記のようになっています。
(引数に渡している定義を太文字にしています)
/*! @brief The UART to use for debug messages. */
#define BOARD_DEBUG_UART_TYPE kSerialPort_Uart
#define BOARD_DEBUG_UART_BASEADDR (uint32_t) LPUART4
#define BOARD_DEBUG_UART_INSTANCE 4U
#define BOARD_DEBUG_UART_CLK_FREQ 12000000U
#define BOARD_DEBUG_UART_CLK_ATTACH kFRO12M_to_FLEXCOMM4
#define BOARD_DEBUG_UART_RST kFC4_RST_SHIFT_RSTn
#define BOARD_DEBUG_UART_CLKSRC kCLOCK_FlexComm4
#define BOARD_UART_IRQ_HANDLER LP_FLEXCOMM4_IRQHandler
#define BOARD_UART_IRQ LP_FLEXCOMM4_IRQn
#define BOARD_DEBUG_UART_BAUDRATE 115200U
ポイント: Board 依存の設定を board.h と ソースコードを board.c で記載しているのが分かります。
2-2. DbgConsole_Init() の中身
続いて、DbgConsole_Init() の中身にを見てみましょう。<Project Dir>/utikities/fsl_debug_console.c に記載があります。
usrtConfig と s_debugConsole に設定を格納し、HAL_UartInit() を実行しています。
図4:DbgConsole_Init の記述
usrtConfig の構造体である hal_uart_config_t は <Project Dir>/component/uart/fsl_adapter_uart.h で定義されており、 UART HAL コード で使用する設定内容が用意されています。
typedef struct _hal_uart_config
{
uint32_t srcClock_Hz; /*!< Source clock */
uint32_t baudRate_Bps; /*!< Baud rate */
hal_uart_parity_mode_t parityMode; /*!< Parity mode, disabled (default), even, odd */
hal_uart_stop_bit_count_t stopBitCount; /*!< Number of stop bits, 1 stop bit (default) or 2 stop bits */
uint8_t enableRx; /*!< Enable RX */
uint8_t enableTx; /*!< Enable TX */
uint8_t enableRxRTS; /*!< Enable RX RTS */
uint8_t enableTxCTS; /*!< Enable TX CTS */
uint8_t instance; /*!< Instance (0 - UART0, 1 - UART1, ...), detail information please refer to the SOC corresponding RM.
Invalid instance value will cause initialization failure. */
#if (defined(HAL_UART_ADAPTER_FIFO) && (HAL_UART_ADAPTER_FIFO > 0u))
uint8_t txFifoWatermark;
uint8_t rxFifoWatermark;
#endif
} hal_uart_config_t;
s_debugConsole は fsl_debug_console.c で グローバル変数として定義されており、debug_console_state_t という構造体です。putChar と getChar を呼び出した時実行される関数ポインターを設定することができます。
DbgConsole_Init() では、HAL_UartSendBlocking と HAL_UartReceiveBlocking を設定しており、最終的にこの関数が実行されます。
/*! @brief State structure storing debug console. */
typedef struct DebugConsoleState
{
uint8_t uartHandleBuffer[HAL_UART_HANDLE_SIZE];
hal_uart_status_t (*putChar)(hal_uart_handle_t handle,const uint8_t *data,size_t length); /*!< put char function pointer */
hal_uart_status_t (*getChar)(hal_uart_handle_t handle,uint8_t *data,size_t length); /*!< get char function pointer */
serial_port_type_t serial_port_type; /*!< The initialized port of the debug console. */
} debug_console_state_t;
つまり、Debug Console の設定を変更したい場合、DbgConsole_Init () で設定している usrtConfig とs_debugConsole の各種値を変更することで実現できることが分かります。
ポイント:BOARD_DEBUG_UART_INSTANCE の設定は LPUART のペリフェラル番号で、LPUART4 (MCX の場合 Flexcomm 4) がデフォルト設定なので、これを変えれば別の Pin にもアサインできそうですね。
3. 評価ボードにおける Debug Console のピンアサイン
FRDM-MCXN947 は UART の TX RX が MCU-Link 用の CPU に接続されており、USB を PC と接続するだけで、Debug Console としてターミナルとマイコンを接続することが可能です。
サンプルプロジェクトを開いた後、図5 のように Pin Config Tool を起動すると Pin アサインを確認することができます。
サンプルでは、A1 と B1 に接続されています。使用しているペリフェラルは FlexComm4 です。
図5:Pin Config Tool の起動方法
図6:サンプルプロジェクトの Pin アサイン
ポイント:FlexComm は LPUART、LPSPI、LPI2C を実現できるマルチペリフェラルになっており、HAL_UartInit() で LPUART を使用する設定になっています。Pin によって FlexComm の番号が設定されており、使用する Pin によって FlexComm の番号も変わります。
4. Debug Console の Pin アサインを変更する方法
FRDM-MCXN947 は Arduino Header を有しており、今回は FlexComm9 を LPUART として設定します。
Arduino Header J3 の Pin 5, 7, 9, 11 番を使用すると LPUART の RXD TXD RTS CTS を使用することができます。今回は RXD TXD のみ使用します。
Arduino Header J3 Pin No |
MCX Pin No | LPUART 属性 |
5 | P2_3 (J3) | TXD |
7 | P2_2 (H3) | CTS |
9 | P2_5 (K1) | RTS |
11 | P2_4 (K3) | RXD |
Arduino Header J3 は図7のような回路図になります。
図7:Arduino Header J3 の回路図
Pin Config Tool での設定は 図8のようになります。
その後、 を実行し、Project に変更を反映させます。
図8:Pin Config Tool でのピンアサインの追加
続いて、<Project Dir>/board/board.h の define 定義を FlexComm9 (LPUART9) に変更します。
FlexComm4 (LPUART4) に関連する数字を 9 に変更します。下記のようになります。
#define BOARD_DEBUG_UART_TYPE kSerialPort_Uart
#define BOARD_DEBUG_UART_BASEADDR (uint32_t) LPUART9
#define BOARD_DEBUG_UART_INSTANCE 9U
#define BOARD_DEBUG_UART_CLK_FREQ 12000000U
#define BOARD_DEBUG_UART_CLK_ATTACH kFRO12M_to_FLEXCOMM9
#define BOARD_DEBUG_UART_RST kFC9_RST_SHIFT_RSTn
#define BOARD_DEBUG_UART_CLKSRC kCLOCK_FlexComm9
#define BOARD_UART_IRQ_HANDLER LP_FLEXCOMM9_IRQHandler
#define BOARD_UART_IRQ LP_FLEXCOMM9_IRQn
Project を Build してエラーが出なければ変更完成です。
5. Pin 変更後の挙動確認
GPIO にアサインした UART 信号を PC で確認する方法は下記のようにいくつかあります。
今回は3番の方法を使って、確認します。
- 別の評価ボードで UART を構築して、基板間で疎通テストを実施する
- FRDM-MCXN947 の別の UART Pin を用意してループバックで疎通テストを実施する
- UART to USB 変換製品を使用して PC の Teraterm で確認する
- ロジックアナライザーを使用して RX と TX Pin を監視する
図9 のように接続し、図10 のように、PC の Teraterm で Hello World の挙動を確認できます。
図9:UART to USB 変換コネクターの接続
図10:Hello World サンプルプロジェクトの挙動
6. ADVANCED_ENABLE を有効にする
Debug Console コード fsl_debug_console.c には Debug Console の初期化以外にも、printf()、scanf()、putchar()、getchar() の処理 が記載されています。printf() scanf() は PRINTF_ADVANCED_ENABLE の有効/無効で機能の調整ができるようになっています。
SCANF_ADVANCED_ENABLE と PRINTF_ADVANCED_ENABLE を有効にすることで下記機能を拡張することができます。
なお、浮動小数点を扱うには、PRINTF_FLOAT_ENABLE と SCANF_FLOAT_ENABLE を有効にすることで実現できます。
6.1 printf() の PRINTF_ADVANCED_ENABLE
printf() では、%[flags][width][.precision][length] を付けることで様々な機能を実現できます。
length は未サポートです。
①:flags
数値や文字列の表示方法を詳細に制御できます。
- -:左寄せ
- +:符号付き数値の際にプラス符号を表示
- スペース:符号付き数値のプラス符号をスペースに置換
- 0:ゼロ埋め
- #:特殊なフォーマット(例えば、%x で 0x 接頭辞、%o で 0 接頭辞を追加)
②:可変幅(width)
- 例えば、%8d で8文字幅に右寄せ
* を使用 すると、動的に引数から指定可能。
③:精度(.precision)
- 整数指定子 (d,i,o,u,x,X) の場合、最小桁数。
表示文字数が指定値より小さい場合空白で埋められます。大きい場合切り捨ては行われません - 指定子が f の場合小数点以下の桁数。
- 指定子が s の場合、出力文字数の最大数。
終了ヌル文字が検出されるまですべての文字が出力されます。
* を使用 すると、動的に引数から指定可能。
6.2 scanf() の SCANF_ADVANCED_ENABLE
scanf() では、%[*][width][length] を付けることで様々な機能を実現できます。
①:* のサポート
- データの引数への格納を無視します
②:可変幅(width)
- 読み取られる文字数の最大値
③:長さ修飾子(Length Modifiers)
異なるサイズの整数を正確にフォーマット可能になります。
-
%h:short 整数または符号なし short 整数として解釈
(整数指定子 i、d、o、u、x、および X にのみ適用) -
%hh:符号付き文字または符号なし文字として解釈
(整数指定子 i、d、o、u、x、および X にのみ適用) -
%l:数指定子 (i、d、o、u、x、および X) の場合は long 整数または符号なし long 整数として解釈
指定子 c および s の場合はワイド文字またはワイド文字列として解釈 - %ll:long long 型の整数をフォーマット
- %z:size_t 型の整数をフォーマット(システムによるサイズ依存)
7. (おまけ) printf() と scanf() 機能テスト結果 とサンプルコード
printf() は scanf() の機能を確認できるサンプルコードをご用意しました。記事の下部からダウンロードしてご利用ください。
下記4つの定義を有効にして実行することですべての機能を確認頂けます。
- SCANF_ADVANCED_ENABLE
- PRINTF_ADVANCED_ENABLE
- PRINTF_FLOAT_ENABLE
- SCANF_FLOAT_ENABLE
変更方法は Project Propertoes の Preprocessor で可能です。図11のように変更ください。
図11:Define の変更箇所
実行すると下記のようなログになります。scanf のテストは文字を入力ください。
hello world.
=== printf のテスト ===
整数(%d, %i): 12345, 12345
符号なし整数(%u): 12345
16進数(%x, %X): 3039, 3039
8進数(%o): 30071
浮動小数点数(%f): 3.141590
long int(%ld): 1234567890
long long int(%lld): 123456789012345
unsigned long long int(%llu): 12345678901234567890
文字列(%s): Hello, World!
文字(%c): A
幅指定(%10d): 12345
ゼロ埋め(%010d): 0000012345
左寄せ(%-10d): 12345
符号付(%+d): +12345
=== printf のテスト End ===
=== scanf のテスト ===
整数を入力してください: 入力された整数: 12345
符号なし整数を入力してください: 入力された符号なし整数: 12345
浮動小数点数を入力してください: 入力された浮動小数点数: 3.141590
文字列を入力してください: 入力された文字列: Hello,
文字を入力してください: 入力された文字: H
long long int を入力してください: 入力された long long int: 123456789012345
unsigned long long int を入力してください: 入力された unsigned long long int: 12345678901234567890
=== scanf のテスト End ===
まとめ
ログ出力としてよく使用する Debug Console の概要と活用方法についてご紹介しました。
初期設定では評価ボードのデバッグポートに出力するよう作らていますので、好きな Pin に設定できるようになることで、より柔軟な開発を進めることが可能になります。
その他にも、シェル機能を実装するサンプルプロジェクトも用意されており、Debug Console 機能をより高度に活用しております。別の機会に改めてご紹介しようと思います。
[NXP マイコン初心者ガイド 11] へ | [NXP マイコン初心者ガイド 13] | ||
NXP マイコン初心者ガイド まとめサイト |