『RT-Thread デバイス ドライバー開発ガイド』 - 基本的な UART デバイス ドライバー開発

RT スレッド デバイス ドライバーの開発 - 第 2 章 UART デバイス ドライバーの開発 

UART の概要

UART (Universal Asynchronous Receiver/Transmitter、Universal Asynchronous Receiver Transmitter) は、シリアル ポートとも呼ばれます。UART は非同期シリアル通信プロトコルの一種で、送信データの各文字を 1 文字ずつ送信することで機能します。UART は、アプリケーション開発中に最も頻繁に使用されるデータ バスです。組み込み設計では、UART は、組み込みデバイスと外部モジュール (Wi-Fi、Bluetooth モジュールなど) 間の通信、組み込みデバイスと PC モニター間の通信、または 2 つの組み込みデバイス間の通信など、ホストと補助デバイス間の通信によく使用されます。デバイス間の通信。

UART シリアル ポートはキャラクタ デバイスの一種で、2 本の伝送ラインでデータを送信し、もう一方 (RX) でデータを受信するという双方向通信を実現できる限り、そのハードウェア接続は比較的簡単です。

UART シリアル通信には、ボー レート、スタート ビット、データ ビット、ストップ ビット、パリティ チェック ビットなどの重要なパラメータがあります。UART シリアル通信を使用する 2 つのポートでは、これらのパラメータが一致する必要があり、一致しないと通信が正常に行われません。

d908a32ec0e293f6e22463f262efa289.jpeg

データフォーマットには、スタートビット、データビット、パリティビット、ストップビットが含まれます。

スタートビット:データ送信の開始を示し、レベル論理は「0」です。

データ ビット: データ ビットは通常 8 ビット データ (1 バイト) ですが、送信データのビット数を示す 5 ビット、6 ビット、7 ビットなどの他のサイズにすることもできます。

パリティビット:受信側が受信したデータをチェックし、2進数中の「1」の数が偶数(偶数チェック)か奇数(奇数チェック)かをチェックし、データ送信の正しさをチェックするために使用されます。 、このビットは使用時に必要ない場合があります。

ストップビット:データのフレームの終わりを示し、レベル論理は「1」です。

ボーレート:シリアル通信の速度で、単位時間当たりに送信されるバイナリコードの実効数で表され、単位はビット/秒です。一般的なボー レート値は 4800、9600、14400、38400、115200 などです。値が大きいほど、データ送信が速くなります。ボー レート 115200 は、1 秒あたり 115200 ビットのデータが送信されることを意味します。

UART v2.0バージョンのUARTフレームワークとドライバーの説明

UART階層

583af499acdd207355504339c46d837a.jpeg

1) I/O デバイス管理層は、rt_device_read/write などの標準インターフェイスをアプリケーション層に提供し、アプリケーション層はこれらの標準インターフェイスを通じて UART デバイスにアクセスできます。

2) UART デバイス ドライバー フレームワークのソース コード ファイルは Serial_v2.c で、RT-Thread ソース コードのコンポーネント\ドライバー\シリアル フォルダーにあります。抽象化された UART デバイス ドライバー フレームワークはプラットフォームとは関係がなく、共通のソフトウェア層です。UART デバイス ドライバー フレームワークは次の機能を提供します。

① 上位の I/O デバイス管理層に接続し、アプリケーション層が I/O デバイス管理層が提供する統合インターフェースを呼び出して UART を操作できるようにします。

②UART デバイスドライバフレームワークは、UART デバイスドライバ層に UART デバイス操作メソッドインタフェース struct rt_uart_ops (configure、control、putc、getc、transmit など) を提供しており、ドライバ開発者はこれらのインタフェースを実装する必要があります。

③デバイス登録管理インターフェース rt_hw_serial_register と割り込み処理インターフェース rt_hw_serial_isr を提供します。

7f774e229a81f9112ef462238feb1e8f.jpeg

3) UART デバイス ドライバーのソース コード ファイルは drv_usartv2.c で、特定の bsp ディレクトリに配置されます。v2 は、シリアル ポート v2 バージョンのデバイス ドライバー フレームワークに接続されていることを意味します。UART デバイス ドライバーの実装はプラットフォームに依存し、特定の MCU UART コントローラーを操作します。UART デバイス ドライバーは、UART ハードウェアにアクセスして制御する機能を提供するために、UART デバイスの操作メソッド struct rt_uart_ops を実装する必要があります。この層は、rt_hw_serial_register 関数を呼び出して UART デバイスをオペレーティング システムに登録する役割も果たします。最後に、割り込み処理インターフェイス rt_hw_serial_isr を呼び出して、UART デバイス ドライバー フレームワーク層にデータを処理するように通知する必要があります。

d39c80c1b4d8fecaf85e353b9b4e0d5a.jpeg

4) 最下層は、MCU が外部モジュールと通信できるように、UART 通信モジュール、RS-232 チップまたは RS-485 チップ回路モジュールなどの MCU に接続された UART モジュールです。

UART デバイス ドライバー開発の主なタスクは、シリアル デバイス操作メソッド インターフェイス struct rt_uart_ops を実装し、シリアル デバイスを登録することです。

コード、シリアル ポートの初期化を確認します。

int rt_hw_usart_init(void)
{
    rt_size_t obj_num = sizeof(uart_obj) / sizeof(struct stm32_uart);
    struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
    rt_err_t result = 0;
    stm32_uart_get_dma_config();
    for (int i = 0; i < obj_num; i++)
    {
        uart_obj[i].config = &uart_config[i];
        uart_obj[i].serial.ops    = &stm32_uart_ops;
        uart_obj[i].serial.config = config;
        /* register UART device */
        result = rt_hw_serial_register(&uart_obj[i].serial, uart_obj[i].config->name,
                                       RT_DEVICE_FLAG_RDWR
                                       | RT_DEVICE_FLAG_INT_RX
                                       | RT_DEVICE_FLAG_INT_TX
                                       | uart_obj[i].uart_dma_flag
                                       , NULL);
        RT_ASSERT(result == RT_EOK);
    }
    return result;
}

UART デバイスを作成しますUART デバイスの場合、ドライバーの開発時に struct rt_serial_device 構造体から新しいシリアル デバイス モデルを派生し、独自のデバイス タイプに従ってプライベート データ フィールドを定義する必要があります。特に、同様のデバイスが複数ある場合 (シリアル ポート 1 とシリアル ポート 2 など)、デバイス インターフェイスは同じインターフェイスのセットを共有でき、唯一の違いはそれぞれのデータ フィールド (レジスタ ベース アドレスなど) です。

たとえば、STM32 の UART デバイス モデルは struct rt_serial_device から派生し、STM32 シリアル ポート ハンドル、シリアル ポート構成情報、DMA 構造情報など、STM32UART の固有のデータ構造が追加されます。

/* stm32 uart dirver class */
struct stm32_uart
{
    UART_HandleTypeDef handle;
    struct stm32_uart_config *config;
#ifdef RT_SERIAL_USING_DMA
    struct
    {
        DMA_HandleTypeDef handle;
        rt_size_t last_index;
    } dma_rx;
    struct
    {
        DMA_HandleTypeDef handle;
    } dma_tx;
#endif
    rt_uint16_t uart_dma_flag;
    **struct rt_serial_device serial;**
};

UARTデバイスの動作メソッドを実装する

struct rt_uart_ops
{
    rt_err_t (*configure)(struct rt_serial_device       *serial,
                          struct serial_configure       *cfg);
    rt_err_t (*control)(struct rt_serial_device         *serial,
                                            int          cmd,
                                            void        *arg);
    int (*putc)(struct rt_serial_device *serial, char c);
    int (*getc)(struct rt_serial_device *serial);
    rt_size_t (*transmit)(struct rt_serial_device       *serial,
                                 rt_uint8_t             *buf,
                                 rt_size_t               size,
                                 rt_uint32_t             tx_flag);
};

eb46a1451f7b12bf634c325b444f21e9.png

42b6e195746d9c639fec9149624995af.png

これらの操作メソッドにより、シリアル ポートの基本操作が完了します。たとえば、configure メソッドはシリアル ポート (ボー レートなど) の構成に使用され、control メソッドはシリアル ポートの制御に使用され、putc メソッドは使用されます。シリアル ポートから文字データを送信するために使用され、getc メソッドはシリアル ポート データから文字を取得するために使用され、transmit メソッドはデータ送信、主にマルチバイト データ送信に使用されます。引き続き、これらの操作方法の実装方法を説明していきます。

UARTデバイスを登録する

UART デバイスの操作メソッドを実装した後、デバイスをオペレーティング システムに登録する必要がありますが、UART デバイスを登録するためのインターフェイスは rt_err_t rt_hw_serial_register(struct rt_serial_device Serial, const char name, rt_uint32_t flag, void *data) です。

UARTデバイス割り込み処理

fefd224d206445283fc7ec1cf569b7ed.jpeg5918e53735cb44fb64b2e94745565ced.jpeg

DMAモードを追加

UART デバイスの DMA モードを追加するには、まず各 UART の DMA を設定し、次に DMA の初期化と割り込み処理を実行し、最後に DMA 送信を完了する必要があります。以下は DMA 構成コードです。

ドライバー構成

RT-Thread は、SCons を使用してプロジェクトをビルドし、Kconfig メカニズムに基づく menuconfig ツールを使用してプロジェクトを構成します。したがって、ドライバーを実装するだけでなく、ドライバーに関連する構成オプションも実装する必要があります。1 つは Kconfig 構成で、構成された構成ファイルは menuconfig ツール内の対応する構成インターフェイスを形成します。もう 1 つは SConscript 構成です。設定後、対応するドライバー ファイルがプロジェクトに追加されます。次の章のドライバー関連の構成オプションはこれに似ており、特別な構成がない場合は詳細に説明しません。

1. Kconfigの設定

bsp/stm32/stm32f407-atk-explorer/board/Kconfig ファイルを参照して、シリアル ポート ドライバーの関連オプションを次のように構成します。

menuconfig BSP_USING_UART
        bool "Enable UART"
        default y
        select RT_USING_SERIAL
        if BSP_USING_UART
            config BSP_USING_UART0
                bool "Enable UART0"
                default y
            config BSP_UART0_RX_USING_DMA
                bool "Enable UART0 RX DMA"
                depends on BSP_USING_UART0
                select RT_SERIAL_USING_DMA
                default n
            config BSP_USING_UART1
                bool "Enable UART1"
                default n
            config BSP_UART1_RX_USING_DMA
                bool "Enable UART1 RX DMA"
                depends on BSP_USING_UART1
                select RT_SERIAL_USING_DMA
                default n
            config BSP_USING_UART2
                bool "Enable UART2"
                default n
            config BSP_UART2_RX_USING_DMA
                bool "Enable UART2 RX DMA"
                depends on BSP_USING_UART2
                select RT_SERIAL_USING_DMA
                default n
            config BSP_USING_UART3
                bool "Enable UART3"
                default n
            config BSP_UART3_RX_USING_DMA
                bool "Enable UART3 RX DMA"
                depends on BSP_USING_UART3
                select RT_SERIAL_USING_DMA
                default n
            config BSP_USING_UART4
                bool "Enable UART4"
                default n
            config BSP_UART4_RX_USING_DMA
                bool "Enable UART4 RX DMA"
                depends on BSP_USING_UART4
                select RT_SERIAL_USING_DMA
                default n
            config BSP_USING_UART5
                bool "Enable UART5"
                default n
            config BSP_UART5_RX_USING_DMA
                bool "Enable UART5 RX DMA"
                depends on BSP_USING_UART5
                select RT_SERIAL_USING_DMA
                default n
            config BSP_USING_UART6
                bool "Enable UART6"
                default n
            config BSP_UART6_RX_USING_DMA
                bool "Enable UART6 RX DMA"
                depends on BSP_USING_UART6
                select RT_SERIAL_USING_DMA
                default n
            config BSP_USING_UART7
                bool "Enable UART7"
                default n
            config BSP_UART7_RX_USING_DMA
                bool "Enable UART7 RX DMA"
                depends on BSP_USING_UART7
                select RT_SERIAL_USING_DMA
                default n
        endif

コード スニペット内の関連マクロの説明は次のとおりです。

BSP_USING_UART: シリアル ポート ドライバー コードに対応するマクロ定義。このマクロは、シリアル ポート ドライバー関連のコードをプロジェクトに追加するかどうかを制御します。

RT_USING_SERIAL: シリアル ポート ドライバー フレームワーク コードに対応するマクロ定義。このマクロは、シリアル ポート ドライバー フレームワークの関連コードをプロジェクトに追加するかどうかを制御します。

BSP_USING_UART1: シリアル デバイス 1 に対応するマクロ定義。このマクロは、シリアル デバイス 1 をシステムに登録するかどうかを制御します。

BSP_UART1_RX_USING_DMA: シリアル デバイス 1 は DMA を使用してデータを受信します。

2.SConscript の設定

HAL_Drivers/SConscriptファイルにシリアルポートドライバの判定オプションを追加するコードは以下のとおりです。これは Python コードの一部であり、マクロ BSP_USING_UART が定義されている場合、drv_uart.c がプロジェクトのソース ファイルに追加されることを意味します。

if GetDepend(['RT_USING_SERIAL']):
    src += ['drv_usart.c']

デバイスを登録すると、UART デバイスは I/O デバイス マネージャーにキャラクター デバイスとして存在します。システムが起動して実行を開始した後、端末で list_device コマンドを使用して、登録されたデバイスに UART デバイスが含まれていることを確認し、UART デバイス ドライバー フレームワークによって提供される統合 API を使用して UART デバイスを操作できます。

まとめ

RT-Thread では、UART ペリフェラルが UART デバイスとして抽象化され、UART デバイス ドライバー フレームワークが UART デバイスの一般的な操作方法とドライバー フレームワークのアイデアと組み合わせて設計され、開発者により便利なデバイス制御方法を提供します。同時に、これにより、UART デバイスに基づいて記述されたアプリケーション コードの互換性と汎用性が高まります。また、開発者は以下の 2 点に注意する必要があります。

1) 操作メソッドの名前はカスタマイズできますが、実際の意味から逸脱することはなく、コードの仕様に従う必要があります。すべての操作メソッド/関数は内部関数であるため、関数の実装時に static で変更する必要があります。この注意事項はすべてのドライバーに適用されるため、次の章では繰り返し説明しません。

2) 割り込みに入るときと割り込みから出るときは、以下に示すように割り込み入り口関数と割り込み出口関数を呼び出す必要があります。この注意事項はすべてのドライバーに適用されるため、次の章では繰り返し説明しません。

eb6294ecf5d343053953e9d431532c1c.png

建築家のリー・ケンさん、本のプレゼントに感謝します!

個人の公開番号に注目することを歓迎します: 埋め込まれた学習と実践

おすすめ

転載: blog.csdn.net/weixin_46158019/article/details/131298195