Rust製組込みOSのTockを触ってみる②
はじめに
諸事情によりまとまった時間を取るのが難しいので、入門系やります。
今回は、Rust製のRTOSであるTockを触ってみます。 githubのTock organizationはこちらです。
前回はC言語で書かれたサンプルアプリケーションを動かしたので、今回はRustで書かれたサンプルアプリケーションを動かしてみます。
libtock-rs
Rustでアプリケーションを書くためのライブラリレポジトリは、libtock-rsです。 examplesは、nRF52-DKでなら動作するようです。 nRF52840-DKとは別物ですが、まぁ動くでしょう。やってみましょう。
rustup target add thumbv7em-none-eabi git clone https://github.com/tock/libtock-rs.git cd libtock-rs ./run_example.sh blink
無事書き込めて、動いています。
+ elf_file_name=target/tab/blink/cortex-m4.elf + tab_file_name=target/tab/blink.tab + tockloader_flags='--jlink --arch cortex-m4 --board nrf52dk --jtag-device nrf52 --app-address 0x20000' + hail_defined= + '[' -n '' ']' + mkdir -p target/tab/blink + cp target/thumbv7em-none-eabi/release/examples/blink target/tab/blink/cortex-m4.elf + elf2tab -n blink -o target/tab/blink.tab target/tab/blink/cortex-m4.elf --stack 2048 --app-heap 1024 --kernel-heap 1024 --protected-region-size=64 + '[' 1 -ge 2 ']' + tockloader uninstall --jlink --arch cortex-m4 --board nrf52dk --jtag-device nrf52 --app-address 0x20000 Preparing to uninstall apps... Using known arch and jtag-device for known board nrf52dk No apps are installed on the board + true + tockloader install --jlink --arch cortex-m4 --board nrf52dk --jtag-device nrf52 --app-address 0x20000 target/tab/blink.tab Installing apps on the board... Using known arch and jtag-device for known board nrf52dk Finished in 1.961 seconds
なにやら色々やっていますね。 事前にアプリケーションがインストールされていると、アンインストールするみたいです。
examplesチラ見
BLEのサンプルがあって気になります。
|> exmaples/ble_scanning.rs
#![no_std] use libtock::ble_parser; use libtock::led; use libtock::simple_ble; use libtock::simple_ble::BleCallback; use libtock::simple_ble::BleDriver; use libtock::syscalls; use serde::Deserialize; #[derive(Deserialize)] struct LedCommand { pub nr: u8, pub st: bool, } // Prevents the compiler from dropping the subscription too early. #[allow(unreachable_code)] fn main() { let mut shared_buffer = BleDriver::create_scan_buffer(); let mut my_buffer = BleDriver::create_scan_buffer(); let shared_memory = BleDriver::share_memory(&mut shared_buffer).unwrap(); let mut callback = BleCallback::new(|_: usize, _: usize| { shared_memory.read_bytes(&mut my_buffer[..]); ble_parser::find(&my_buffer, simple_ble::gap_data::SERVICE_DATA as u8) .and_then(|service_data| ble_parser::extract_for_service([91, 79], service_data)) .and_then(|payload| corepack::from_bytes::<LedCommand>(&payload).ok()) .and_then(|msg| led::get(msg.nr as isize).map(|led| led.set_state(msg.st))); }); let _subscription = BleDriver::start(&mut callback).unwrap(); loop { syscalls::yieldk(); } }
あー、serdeビルドしているの、なぜだろうと思ってましたが、ここで使っていたのですね…。 割とビルド時間長いのは、気になりますね。
BLE Advertising driverもkernel側に実装されています。
libtock-rsにBleAdvertisingDriver
の実装がありますが、基本はシステムコールを呼ぶだけで、実態はkernel側のようですね。
おもむろにDRIVER_NUMBER
が使用されていますが、これはkernel側のシステムコールで定義されています。
|> libtock-rs/src/simple_ble.rs
const DRIVER_NUMBER: usize = 0x30000; pub const MAX_PAYLOAD_SIZE: usize = 9; pub const BUFFER_SIZE_ADVERTISE: usize = 39; pub const BUFFER_SIZE_SCAN: usize = 39; mod ble_commands { pub const START_ADVERTISING: usize = 0; pub const ALLOW_ADVERTISMENT_BUFFER: usize = 0; pub const BLE_PASSIVE_SCAN_SUB: usize = 0; pub const ALLOW_SCAN_BUFFER: usize = 1; pub const PASSIVE_SCAN: usize = 5; }
|> tock/doc/syscalls/README.md
Radio
1.0 | Driver Number | Driver | Description |
---|---|---|---|
0x30000 | BLE | Bluetooth Low Energy | |
0x30001 | 802.15.4 | IEEE 802.15.4 | |
0x30002 | UDP | UDP / 6LoWPAN Interface |
なるほどね〜。