Zephyr×Rustのインテグレーションにチャレンジ!⑪~UART Driver 受信編~
はじめに
ZephyrとRustのインテグレーションに挑戦しています。
RustでデバイスDriverを作っていきます。
まずは、QEMUのUARTをターゲットにします。
QEMUのUARTデバイスはガバガバで、初期化を行わなくてもデータ送受信ができるので、敷居が低いです。
UART受信
基本は、以前の記事でUART Driverの受信処理を作ったときと同じです。
tomo-wait-for-it-yuki.hatenablog.com
動作確認も、ZephyrのShellが動くかどうか、を見ていきましょう。
実装
まず、APIのpoll_in
を埋めます。
static UART_API: uart_driver_api = uart_driver_api { poll_out: Some(rust_poll_out), - poll_in: None, + poll_in: Some(rust_poll_in), err_check: None, configure: None, config_get: None, };
poll_in
を実装します。あとでどちゃくそリファクタリングしましょう。
(と言ってもCからのコールバックなので、それほどきれいにできないかもしれませんが)
// Flag register const FR: u32 = 0x18; const UARTFR_RXFE: u32 = 0x00000010; unsafe extern "C" fn rust_poll_in(_dev: *mut device, p_char: *mut cty::c_uchar) -> cty::c_int { let flags = *((zephyr::UART_0_BASE_ADDRESS + FR) as *const u32); if (flags & UARTFR_RXFE) != 0 { return -1; // don't have RX data. } *p_char = *(zephyr::UART_0_BASE_ADDRESS as *mut u32) as cty::c_uchar; return 0; }
Rustの実装はこれだけです!
動作確認
ZephyrのShellをinterrupt drivenを無効化した上で、有効化します。
$ ninja run 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 ***** Booting Zephyr OS 1.13.99 ***** Hello from Rust! uart:~$ clear help history resize shell uart:~$ help Please press the <Tab> button to see all available commands. You can also use the <Tab> button to prompt or auto-complete all commands or its subcommands. You can try to call commands with <-h> or <--help> parameter for more information.
Rustで書いたZephyrのDriverが動いています!感動!