💨

CH32V003J4M6マイコンで、ch32v00x-halを利用してみた

2024/01/15に公開

CH32V003J4M6マイコンでRustでLチカをしてみた のサンプルでは、メモリを直に操作していました。

今回は、 CH32V00X 向けの HAL である ch32v00x-hal を利用してみました。

Cargo.toml の変更

[dependencies]
ch32v-rt = "0.0.3"
ch32v00x-hal = { version = "0.1.0", git = "https://github.com/ch32-rs/ch32v00x-hal.git", default-features = false, features = ["ch32v003j4m6"] }

前回は、riscv-rt というクレートを指定していましたが、ch32v-rt に変更しました。
https://github.com/ch32-rs/ch32v-rt を見ると、こいつはもうお役ご免で、
qingke-rt を使うよう書いてあります。後日こちらも試してみようと思います。

ch32v00x-hal の方は、まだ crate.io には無いので、リポジトリにあるのもの(a0a0500)を直接利用しています。
デフォルトの features でも動くと思いますが、より正確なものを指定しました。

ビルドまわりの変更

build.rs や memory.x まわりを ch32v00x-hal 側でやってくれるので、ファイル自体を削除し、以下の設定を追加しました。

.cargo/config.toml
[target.riscv32ec-unknown-none-elf]
rustflags = [
  "-C", "link-arg=-Tlink.x",
]

また、前回は、

$ cargo +custom-rv32ec build

とビルドをしていましたが、プロジェクト以下で

$ rustup override set custom-rv32ec

を実行することで

$ cargo build

で済むようになりました。
(理由はわかっていません)

書き込みの改善

前回は minichlink というツールを利用していましたが、ch32-rs が提供している wlink に変更しました。

$ cargo install --git https://github.com/ch32-rs/wlink
.cargo/toml
[target.riscv32ec-unknown-none-elf]
runner = "wlink -v flash"

これにより、IDE 上から直接書き込み&実行ができるようになりました。

ソースコードの変更

src/main.rs
#![no_std]
#![no_main]

use ch32v_rt::entry;
use ch32v00x_hal::prelude::*;
use ch32v00x_hal::pac::Peripherals;
use panic_halt as _;

#[entry]
fn main() -> ! {
    let pac = Peripherals::take().unwrap();

    let mut rcc = pac.RCC.constrain();
    let _clocks = rcc.config.freeze();

    let gpioc = pac.GPIOC.split(&mut rcc);
    let mut led = gpioc.pc1.into_push_pull_output();
    loop {
        led.toggle();

        for _ in 0..1_000_000 {
            core::hint::black_box(()); // Do nothing, but keep the loop
        }
    }
}

待つ部分は、ch32v00x-hal のサンプルでは

unsafe {
    qingke::riscv::asm::delay(10000000);
}

となっていて、こちらの方が綺麗で扱いやすい形のような気がします。

おわりに

今回は HAL を利用して、よりよいソースコードに改善しました。
ビルドや実行まわりも改善をして、効率よく開発が進められる準備が整いました。

https://github.com/task-jp/ch32v003j4m6-led/tree/ch32v00x_hal

Discussion