Zephyr×Rustのインテグレーションにチャレンジ!⑨~UART Driver 準備編~

はじめに

ZephyrとRustのインテグレーションに挑戦しています。

前回は、RustでDriverの初期化関数を書いて、動作させることに成功しました。

tomo-wait-for-it-yuki.hatenablog.com

今回から、もう少しちゃんとデバイスDriverを作っていきます。 まずは、QEMUのUARTをターゲットにします。QEMUのUARTデバイスガバガバで、初期化を行わなくてもデータ送受信ができるので、敷居が低いです。

下準備

専用のdevice tree bindingを準備

既存のstellaris UART Driverの実装を修正しない方法でやりたいため、Rustで書くDriver用に、device treeのbindingを作成します。

|> zephyr/dts/bindings/serial

cp ti,stellaris-uart.yaml rust,simple-uart.yaml

ベースとなるstellarisのbindingをコピーして、compatibleを変更するだけです。

---
title: TI Stellaris UART Driver Bindings Written in Rust
version: 0.1

description: >
    This binding gives a base representation of the TI Stellaris UART

inherits:
    !include uart.yaml

properties:
    compatible:
-      constraint: "ti,stellaris-uart"
+      constraint: "rust,simple-uart"

device tree修正

&uart0 {
+   compatible = "rust,simple-uart";
    status = "ok";
    current-speed = <115200>;
};

ちなみに、uart0には、UART_0というラベルがついています。

|> zephyr/dts/arm/ti/lm3s6965.dtsi

                uart0: uart@4000c000 {
                        compatible = "ti,stellaris-uart";
                        reg = <0x4000c000 0x4c>;
                        interrupts = <5 3>;
                        status = "disabled";
                        label = "UART_0";
                };

kernel config修正

uart0を間借りするので、本来のuart0をconfigで無効化します。 これをしないと、device treeで必要なマクロが生成されていない状態で、stellaris Driverのインスタンスを作ろうとするため、コンパイルエラーになります。

|> prj.conf

CONFIG_UART_STELLARIS_PORT_0=n

一度動作確認

ビルドができて、実行はできない、ことを確認します。

$ mkdir build && cd $_
$ cmake -GNinja -DBOARD=qemu_cortex_m3 ..
$ ninja run
[0/1] To exit from QEMU enter: 'CTRL+a, x'[QEMU] CPU: cortex-m3
qemu-system-arm: warning: nic stellaris_enet.0 has no peer
qemu: fatal: Lockup: can't escalate 3 to HardFault (current priority -1)

QEMUでHardFaultが発生しました。 UART Driverで必要とされるAPIを実装していないので、一旦、これでOKです。