1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

1. はじめに

これまでの記事では、Zephyr の入門的な記事を投稿してきました。
一方で直近の記事は、DeviceTree の記述方法について部分的に解説をしたものの、視野の狭い解説になっており理解しにくい内容だったと反省しております。

そこで、今回はいったん理屈を抜きにしてとりあえず動かして、答えを見てから理解しようという方針で記事を書いていこうと思います。

過去の Zephyr の記事は以下にまとめていますのでご参考にしていただけると幸いです。

2. ターゲット

最近触ったマイコンボードの中でちょっとお気に入りの Nucleo G431KB をベースに話を進めていきます。

せっかくなので Raspberry Pi Pico / Pico2 と比較してみました。

Nucleo G431KB RPi pico RPi pico2
アーキテクチャ Cortex M4F Cortex M0+ Cortex M33
CPU clock 170 MHz 133 MHz x 2 150 MHz x 2
FPU あり なし あり
RAM 32 KB 264 KB 520 KB
ROM 128 KB 2 MB 4 MB
Size (mm) 18.542 x 50.292 21.0 x 51.3 21.0 x 51.3
形状 Arduino nano 互換 独自(RPi pico系) 独自(RPi pico系)
デバッガ ST-Link 内蔵 別売り(約 2,000 円) 別売り(約 2,000 円)
値段 (2026年1月) 約 2,000 円 約 800 円 約 900 円

こうやって見ると、pico / pico2 の ROM / RAM が異次元ですね・・・
ですが、nucleo_g431kb には pico 系にはない以下の魅力があります。

  • Cortex M4 170MHz + FPU 搭載で演算能力としてなかなか
  • ST-Link が内蔵されているためこれ単体でデバッグ/書き込み可能
  • Arduino nano フォームファクター互換なので拡張ボードも利用可能

本記事の終盤にフォームファクター互換を活かすおまけも記載していますのであわせてご覧ください。

3. ディレクトリ構成と overlay の配置

まずは overlay の置き場所について触れておきます。明示的に指定しなければ、ビルド時に2箇所のみ自動的に検索して適用されます。

  1. boards ディレクトリ直下
  2. CMakeLists.txt と同じ場所

自作ソフトを apps として作成した場合、以下のような配置になります。

.
├── .venv/
├── .west/
├── apps/                           # 自作ソフトのディレクトリ(名前は何でもOK)
│   ├── boards/
│   │   └── nucleo_g431kb.overlay   # 1. ディレクトリを分けて管理する場合はこちら
│   ├── CMakeLists.txt              # west build で参照されるビルドの設定集
│   ├── nucleo_g431kb.overlay       # 2. CMakeLists.txt と同じ階層でも良い
│   └── prj.conf
├── bootloader/
├── modules/
└── zephyr/

一方で、以下のようにビルド時に明示的に指定することも可能です。

west build -b nucleo_g431kb -- -DDTC_OVERLAY_FILE=path/to/foo.overlay

なお、CMakeLists.txt をゼロから作るのがめんどくさい場合は、以下のように zephyr/samples/hello_world をコピペして編集するのがおすすめです。

cp -rf zephyr/samples/hello_world apps

4. nucleo_g431kb 向けの雛形

まずは、nucleo_g431kb で適用できる UART / I2C / SPI の選択肢をすべて挙げたものを出しておきます(Timer(PWM)は数が多いので割愛)。

設定内容は以下の通りです。

nucleo_g431kb.png

以下の内容をそのまま overlay として先述の配置に保存すれば利用できます。

nucleo_g431kb 向け overlay
/*
 * Copyright (c) 2026 Takayuki Goto <tkg.develop@gmail.com>
 *
 * SPDX-License-Identifier: Apache-2.0
 */

/ {
	chosen {
		zephyr,console = &usart1;
		zephyr,shell-uart = &usart1;
	};
};

&lpuart1 {
    status = "disabled";
    current-speed = <115200>;

    // lpuart1_tx_pa2
    // lpuart1_rx_pa3
    pinctrl-0 = <&lpuart1_tx_pa2 &lpuart1_rx_pa3>;
    pinctrl-names = "default";

    // LL_DMAMUX_REQ_LPUART1_TX, LL_DMAMUX_REQ_LPUART1_RX
//  dmas = <&dmamux1 0 35 STM32_DMA_PERIPH_TX>,
//         <&dmamux1 1 34 STM32_DMA_PERIPH_RX>;
//  dma-names = "tx", "rx";
//  fifo-enable;
};

&usart1 {
    status = "okay";
    current-speed = <115200>;

    // usart1_tx_pa9, usart1_tx_pb6
    // usart1_rx_pa10, usart1_rx_pb7
    pinctrl-0 = <&usart1_tx_pa9 &usart1_rx_pa10>;
    pinctrl-names = "default";

	// LL_DMAMUX_REQ_USART1_TX, LL_DMAMUX_REQ_USART1_RX
	dmas = <&dmamux1 2 25 STM32_DMA_PERIPH_TX>,
	       <&dmamux1 3 24 STM32_DMA_PERIPH_RX>;
	dma-names = "tx", "rx";
	fifo-enable;
};

&usart2 {
    status = "disabled";
    current-speed = <115200>;

    // usart2_tx_pa2, usart2_tx_pa14, usart2_tx_pb3
    // usart2_rx_pa3, usart2_rx_pa15, usart2_rx_pb4
    pinctrl-0 = < &usart2_tx_pa2 &usart2_rx_pa3 >;
    pinctrl-names = "default";

	// LL_DMAMUX_REQ_USART2_TX, LL_DMAMUX_REQ_USART2_RX
//  dmas = <&dmamux1 4 27 STM32_DMA_PERIPH_TX>,
//         <&dmamux1 5 26 STM32_DMA_PERIPH_RX>;
//  dma-names = "tx", "rx";
};

&dma1 {
	status = "okay";
};

&dmamux1 {
	status = "okay";
};

&i2c1 {
    status = "okay";
    clock-frequency = <I2C_BITRATE_STANDARD>;

    // i2c1_scl_pa13, i2c1_scl_pa15, i2c1_scl_pb8
    // i2c1_sda_pa14, i2c1_sda_pb7
    pinctrl-0 = < &i2c1_scl_pa15 &i2c1_sda_pb7 >;
    pinctrl-names = "default";
};

&i2c2 {
    status = "disabled";
    clock-frequency = <I2C_BITRATE_STANDARD>;

    // i2c2_scl_pa9
    // i2c2_sda_pa8, i2c2_sda_pf0
    pinctrl-0 = < &i2c2_scl_pa9 &i2c2_sda_pa8 >;
    pinctrl-names = "default";
};

&i2c3 {
    status = "disabled";
    clock-frequency = <I2C_BITRATE_STANDARD>;

    // i2c3_scl_pa8
    // i2c3_sda_pb5
    pinctrl-0 = < &i2c3_scl_pa8 &i2c3_sda_pb5 >;
    pinctrl-names = "default";
};

&spi1 {
    status = "disabled";
    clock-frequency = <8000000>;

    // spi1_sck_pa5, spi1_sck_pb3
    // spi1_miso_pa6, spi1_miso_pb4
    // spi1_mosi_pa7, spi1_mosi_pb5
    pinctrl-0 = <&spi1_sck_pa5 &spi1_miso_pa6 &spi1_mosi_pa7>;
    pinctrl-names = "default";
//  cs-gpios = <&gpiob 7 GPIO_ACTIVE_LOW>;
};

&spi2 {
    status = "disabled";
    clock-frequency = <8000000>;

    // spi2_sck_pf1
    // spi2_miso_pa10
    // spi2_mosi_pa11
    pinctrl-0 = <&spi2_sck_pf1 &spi2_miso_pa10 &spi2_mosi_pa11>;
    pinctrl-names = "default";
//  cs-gpios = <&gpioa 1 GPIO_ACTIVE_LOW>;
};

&spi3 {
    status = "okay";
    clock-frequency = <8000000>;

    // spi3_sck_pb3
    // spi3_miso_pb4
    // spi3_mosi_pb5
    pinctrl-0 = <&spi3_sck_pb3 &spi3_miso_pb4 &spi3_mosi_pb5>;
    pinctrl-names = "default";
    cs-gpios = <&gpiob 0 GPIO_ACTIVE_LOW>;

    sdhc0: sdhc@0 {
        compatible = "zephyr,sdhc-spi-slot";
        reg = <0>;
        status = "okay";
        mmc {
            compatible = "zephyr,sdmmc-disk";
            disk-name = "SD";
            status = "okay";
        };
        spi-max-frequency = <8000000>;
    };
};

&timers1 {
    status = "disabled";
    pwm1: pwm {
        status = "disabled";

        // tim1_ch1_pa8, tim1_ch1n_pa7, tim1_ch1n_pa11
        // tim1_ch2_pa9, tim1_ch2n_pa12, tim1_ch2n_pb0
        // tim1_ch3_pa10, tim1_ch3n_pf0
        // tim1_ch4_pa11,
        pinctrl-0 = <&tim1_ch1_pa8 &tim1_ch4_pa11>;
        pinctrl-names = "default";
    };
};

&timers2 {
    status = "disabled";
    pwm2: pwm {
        status = "disabled";

        // tim2_ch1_pa0, tim2_ch2_pa1, tim2_ch3_pa2, tim2_ch4_pa3
        // tim2_ch1_pa5, tim2_ch3_pa9, tim2_ch4_pa10, tim2_ch1_pa15
        // tim2_ch2_pb3
        pinctrl-0 = <&tim2_ch1_pa0>;
        pinctrl-names = "default";
    };
};

&timers3 {
    status = "disabled";
    pwm3: pwm {
        status = "disabled";

        // tim3_ch2_pa4, tim3_ch1_pa6, tim3_ch2_pa7, tim3_ch3_pb0
        // tim3_ch1_pb4, tim3_ch2_pb5, tim3_ch4_pb7
        pinctrl-0 = <&tim3_ch2_pa4>;
        pinctrl-names = "default";
    };
};

&timers4 {
    status = "disabled";
    pwm4: pwm {
        status = "disabled";

        // tim4_ch1_pa11, tim4_ch2_pa12, tim4_ch3_pa13, tim4_ch1_pb6
        // tim4_ch2_pb7, tim4_ch3_pb8
        pinctrl-0 = <&tim4_ch2_pa12>;
        pinctrl-names = "default";
    };
};

&timers8 {
    status = "disabled";
    pwm8: pwm {
        status = "disabled";

        // tim8_ch1n_pa7, tim8_ch2_pa14, tim8_ch1_pa15, tim8_ch2n_pb0
        // tim8_ch1n_pb3, tim8_ch2n_pb4, tim8_ch3n_pb5, tim8_ch1_pb6
        // tim8_ch2_pb8
        pinctrl-0 = <&tim8_ch2_pa14>;
        pinctrl-names = "default";
    };
};

&timers15 {
    status = "disabled";
    pwm15: pwm {
        status = "disabled";

        // tim15_ch1n_pa1, tim15_ch1_pa2, tim15_ch2_pa3
        pinctrl-0 = <&tim15_ch1n_pa1>;
        pinctrl-names = "default";
    };
};

&timers16 {
    status = "disabled";
    pwm16: pwm {
        status = "disabled";

        // tim16_ch1_pa6, tim16_ch1_pa12, tim16_ch1n_pa13, tim16_ch1_pb4
        // tim16_ch1n_pb6, tim16_ch1_pb8
        pinctrl-0 = <&tim16_ch1_pb8>;
        pinctrl-names = "default";
    };
};

&timers17 {
    status = "disabled";
    pwm17: pwm {
        status = "disabled";

        // tim17_ch1_pa7, tim17_ch1_pb5, tim17_ch1n_pb7
        pinctrl-0 = <&tim17_ch1_pa7>;
        pinctrl-names = "default";
    };
};
/*
&adc1 {
    status = "disabled";

    // adc1_in1_pa0, adc1_in2_pa1, adc1_in3_pa2
    // adc1_in4_pa3, adc1_in15_pb0, adc1_in10_pf0
    pinctrl-0 = <&adc1_in1_pa0>;
    #address-cells = <1>;
    #size-cells = <0>;
    st,adc-clock-source = "SYNC";
    st,adc-prescaler = <4>;
};

&adc2 {
    status = "disabled";

    // adc2_in1_pa0, adc2_in2_pa1, adc2_in17_pa4
    // adc2_in13_pa5, adc2_in3_pa6, adc2_in4_pa7
    // adc2_in10_pf1
//  pinctrl-0 = <&>;
};

&dac1 {
    status = "disabled";

    // dac1_out1_pa4, dac1_out2_pa5
//  pinctrl-0 = <&>;
};
*/

5. 使い方例

5.1. USART2 の有効化と出力先の変更

先述の内容は図の通り usart1 を有効にしており、USB経由(ST-Link)に繋がっている usart2 は無効にしています。
USB 経由でシリアル通信を行いたい場合は以下の2点を変更してください。

chosen でデフォルト出力先を usart1 から usart2 に変更
/ {
	chosen {
		zephyr,console = &usart2;
		zephyr,shell-uart = &usart2;
	};
};

usart2 の status = "disabled" を "okay" に変えて有効にする
&usart2 {
    status = "okay";
    current-speed = <115200>;

    // usart2_tx_pa2, usart2_tx_pa14, usart2_tx_pb3
    // usart2_rx_pa3, usart2_rx_pa15, usart2_rx_pb4
    pinctrl-0 = < &usart2_tx_pa2 &usart2_rx_pa3 >;
    pinctrl-names = "default";

5.2. Timer(PWM) を有効にする

timers1pwmstatus = "okay" にすると PA8PA11PWM 出力することができます。

timers1 の pwm1 の設定を有効にする
&timers1 {
    status = "okay";
    pwm1: pwm {
        status = "okay";

        // tim1_ch1_pa8, tim1_ch1n_pa7, tim1_ch1n_pa11
        // tim1_ch2_pa9, tim1_ch2n_pa12, tim1_ch2n_pb0
        // tim1_ch3_pa10, tim1_ch3n_pf0
        // tim1_ch4_pa11,
        pinctrl-0 = <&tim1_ch1_pa8 &tim1_ch4_pa11>;
        pinctrl-names = "default";
    };
};

対象のピンを変えたい場合は、pinctrl-0 = <&tim1_ch1_pa8 &tim1_ch4_pa11>; の右辺を変更します。変更可能なピンは、直前のコメントアウト内に羅列していますので、これらをコピペして設定してください。

例えば、PA11 のみを PWM 用に設定する場合は以下のようになります。

timers1 内の pinctrl-0 の右辺値を tim1_ch4_pa11 に変更
        pinctrl-0 = <&tim1_ch4_pa11>;

※ 他の機能で同じピンを使っていないか確認の上設定してください。
例えば tim1_ch2_pa9pa9usart1_tx_pa9 にも使われており、同時利用はできません。

※ 同様に、この pwm1 内の同一 ch の重複も回避してください。
例えば tim1_ch1n_pa7tim1_ch1n_pa11tim1 の中の同一 ch1 なので、これも同時利用はできません。

5.3. I2C3 を有効にする

同じ要領で I2C3 を有効にしたい場合は statusokay にするだけです。
※ 先述の PWMPA8 を設定している場合は重複するので注意。
(nucleo_g431kb だと、i2c3 に割り当てられるピンはそれぞれ1種類しかなく変更不可)

i2c3 の status = "disabled" を "okay" に変えて有効にする
&i2c3 {
    status = "okay";
    clock-frequency = <I2C_BITRATE_STANDARD>;

    // i2c3_scl_pa8
    // i2c3_sda_pb5
    pinctrl-0 = < &i2c3_scl_pa8 &i2c3_sda_pb5 >;
    pinctrl-names = "default";
};

5.4. DMA の有効化

ついでに DMA の設定を有効にしやすいようにこちらも記載しています。
デフォルトで usart1 に適用していますが、usart2 にも適用したい場合は dmas, dma-names, fifo-enable のコメントアウトを解除するだけです。

必須機能ではないですが、性能・機能を無駄なく活かせてコーディングも楽になるためオススメです。
活かし方は zephyr/samples/boards/st/uart/circular_dma を参考にしてください。

usart2 の設定
&usart2 {
    status = "okay";
    current-speed = <115200>;

    // usart2_tx_pa2, usart2_tx_pa14, usart2_tx_pb3
    // usart2_rx_pa3, usart2_rx_pa15, usart2_rx_pb4
    pinctrl-0 = < &usart2_tx_pa2 &usart2_rx_pa3 >;
    pinctrl-names = "default";

	// LL_DMAMUX_REQ_USART2_TX, LL_DMAMUX_REQ_USART2_RX
    dmas = <&dmamux1 4 27 STM32_DMA_PERIPH_TX>,
           <&dmamux1 5 26 STM32_DMA_PERIPH_RX>;
    dma-names = "tx", "rx";
    fifo-enable;
};

6. Arduino nano 互換を活かした応用

今回例示した overlayusart1 を有効にしているなど、少々変な設定だとは思いますが、これは今回使用している nucleo_g431kb が Arduino Nano のフォームファクター準拠なことに由来しています。

つまり、Arduino nano のピンアサインに近づけた設定というわけです。

その結果 Arduino nano 互換として様々な拡張ボードが利用できるようになり、私は下記のコネクタキャリアをセットで愛用しています。

これを使うと以下のメリットがあります。

  • メスのピンヘッダで簡易ブレッドボード化
  • USART1 は Grove コネクタから利用可能
  • I2C1 は Qwiic と Grove コネクタからアクセス可能
  • SD カードシールドも付属(動くけど要検証)
  • ADC1ADC2 も Grove コネクタからアクセス可能(ただし未所持で未確認)

いろんなセンサードライバの実装を行ったり、性能を確認・検証する場合に於いて、はんだ不要で付け替えたりできるため非常に重宝しています。

6.1. 利用できるコネクターの紹介

6.1.1. Grove コネクタ

Grove コネクタは Seeed Studio 提唱のコネクタで、幅広く採用されています。

6.1.2. Qwiic コネクタ

Qwiic コネクタは Sparkfun が提唱しているコネクタで、用途もほぼ Grove と同じですが更に小型化されています。

6.1.3. 相互変換ハブ

どちらか一方しか使えないわけではなく、以下のようなハブを使うと相互に変換でき、ポートも増やせるためこれも手元にあるとさらに便利です。

6.2. dts の設定や配線のチェック

これらを使って色々繋げた様子はこちら。

connect_sample.png

ドライバを書く前に、結線や overlay が正しいかチェックする際に i2c scan が便利です。
その機能を有効にするには、prj.conf で下記3つを有効にするだけです。

prj.conf で I2C SCAN を有効にする方法
CONFIG_I2C=y
CONFIG_SHELL=y
CONFIG_I2C_SHELL=y

実際に確認する方法は以下の流れです。DTS や 配線が正しければ以下のように該当するアドレスが表示されます。

Zephyr の shell を使ってI2Cデバイスをスキャン
uart:~$ *** Booting Zephyr OS build v4.3.0-3523-g588d22464d13 ***
Hello World! nucleo_g431kb/stm32g431xx

uart:~$ i2c scan                    <- 一旦 i2c scan と打つ
scan: wrong parameter count
scan - Scan I2C devices
       Usage: scan <device>
Subcommands:
  i2c@40005400                      <- バスのアドレス一覧が出てくる(有効なバスだけが表示)
uart:~$ i2c scan i2c@40005400       <- バスを指定して改めて実行
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:             -- -- -- -- -- -- -- -- -- -- -- -- 
10: 10 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- 28 29 -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: 40 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: 70 -- -- -- -- -- -- --

6.3. SDカードシールドを有効にする方法

一応、SDカードシールドが使えることは確認しています。ただし下記注意点があります。

  1. SD_SS(CS) はデフォルトでは D4(PB7) に割り当てられていますが、PB7I2C1 SCL になるため、Solder Jumper を短絡して D3(PB0) に変更が必要
  2. SDカードへアクセスする際の初期化時に、SPIのクロックが規定外で先に進めません。雑にコメントアウトで回避はできますが要検証
  3. ピン が重複する以外の理由があるのか I2C1(Grove/Qwiic) と併用できていません。代わりにI2C2, I2C3は利用可能ですが、その場合は USART1 との干渉に注意。 デフォルトで有効になっている D4(PB7) の Solder Jumper が繋がったままが原因でした。 D4(PB7) の Jumper をしっかり切断し、D3(PB0) を繋げることで SD カードへのアクセスと I2C1 の併用ができることを確認しています。

6.3.1. Solder Jumper の設定方法

コネクタキャリア側のジャンパーを切り替えることで、SDカード用の CS を D4(PB7)D3(PB0)D2(PA12) のどれかに割り当てることができます。デフォルトでは D4(PB7) になっていますが、これは i2c1_sda_pb7 と重複しているため、以下のジャンパーを結線して D3(PB0) に切り替えています(写真オレンジ枠が該当のジャンパー)。
なお、nucleo_g431kb の USBコネクタの向き(写真左上)は、コネクタキャリア側に USB という印字がされている方(写真右下部)と逆の位置になる点には注意。

connector_carrier_jumper.png

双方のピンアサインの画像も以下に貼り付けておきます。

6.3.2. SDカードを機能させるための SPI の初期化を通すための対応

ジャンパーの結線と overlay の有効化を行っただけでは以下のエラーで動作しません。

[00:00:00.001,000] <err> spi_stm32: Unsupported frequency 400000Hz, max 85000000Hz, min 664062Hz
[00:00:00.001,000] <err> sdhc_spi: Card SCLK init sequence failed

これは以下の初期化関数内で低速過ぎて弾かれるのですが、コメントアウトで回避はできています(要検証)。

zephyr/drivers/spi/spi_stm32.c
 922 static int spi_stm32_configure(const struct device *dev,
 923                    const struct spi_config *config,
 924                    bool write)
 925 {   
 926     const struct spi_stm32_config *cfg = dev->config;
 927     struct spi_stm32_data *data = dev->data;
                              :
                              :
 999     for (br = 0; br < ARRAY_SIZE(scaler); ++br) {
1000         uint32_t clk = clock >> (br + shift);
1001 
1002         if (clk <= config->frequency) {
1003             break;
1004         }
1005     }
1006 /*
1007     if (br >= ARRAY_SIZE(scaler)) {
1008         LOG_ERR("Unsupported frequency %uHz, max %uHz, min %uHz",
1009             config->frequency, clock >> shift,
1010             clock >> (ARRAY_SIZE(scaler) - 1 + shift));
1011         return -EINVAL;
1012     }
1013 */
1014     LL_SPI_Disable(spi);
1015     LL_SPI_SetBaudRatePrescaler(spi, scaler[br]);
1016 
1017 #if defined(SPI_CFG2_IOSWP)
1018     if (cfg->ioswp) {
1019         LL_SPI_EnableIOSwap(cfg->spi);
1020     }
1021 #endif

6.3.3. SD カードのフォーマット

下記手順でブートセクタ、パーティション等を構築することでアクセスできることを確認しています。

※ SD カードは /dev/sda として検出している前提です。作業環境に依存するため自分のPCやカードリーダーの作りを把握した上で進めてください。

$ sudo fdisk /dev/sda
Welcome to fdisk (util-linux 2.39.3).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.
MBR(Master Boot Record)形式に設定
Command (m for help): o
Created a new DOS (MBR) disklabel with disk identifier 0xb488ee27.
新しくパーティションを作成(primary, 以降デフォルト設定)
Command (m for help): n
Partition type
   p   primary (0 primary, 0 extended, 4 free)
   e   extended (container for logical partitions)
Select (default p): p
Partition number (1-4, default 1): 
First sector (2048-7744511, default 2048): 
Last sector, +/-sectors or +/-size{K,M,G,T,P} (2048-7744511, default 7744511): 

Created a new partition 1 of type 'Linux' and of size 3.7 GiB.
Partition #1 contains a vfat signature.

Do you want to remove the signature? [Y]es/[N]o: Y

The signature will be removed by a write command.
パーティションのフォーマットに FAT32 を指定
Command (m for help): t
Selected partition 1
Hex code or alias (type L to list all): b
Changed type of partition 'Linux' to 'W95 FAT32'.
パーティション情報を表示
Command (m for help): p
Disk /dev/sda: 3.69 GiB, 3965190144 bytes, 7744512 sectors
Disk model: SD/MMC          
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0xb488ee27

Device     Boot Start     End Sectors  Size Id Type
/dev/sda1        2048 7744511 7742464  3.7G  b W95 FAT32

Filesystem/RAID signature on partition 1 will be wiped.
問題ないことを確認して設定内容を書き込む
Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.

パーティション構成を作成したあと、パーティション自体を vfat でフォーマットします。

$ sudo mkfs.vfat -v /dev/sda1 
mkfs.fat 4.2 (2021-01-31)
Auto-selecting FAT32 for large filesystem
/dev/sda1 has 122 heads and 62 sectors per track,
hidden sectors 0x0800;
logical sector size is 512,
using 0xf8 media descriptor, with 7742436 sectors;
drive number 0x80;
filesystem has 2 32-bit FATs and 8 sectors per cluster.
FAT size is 7552 sectors, and provides 965912 clusters.
There are 32 reserved sectors.
Volume ID is 9eae7be7, no volume label.

6.3.4. 実際にSDカードを読み書きしてみる

SDカードへのアクセスに関しては、samples/subsys/fs/fs_sample/ としてサンプルがありますので、これに nucleo_g431kb.overlay を適用してビルド・ファーム書き込みを行います。

ディレクトリツリーを表示
$ tree zephyr/samples/subsys/fs/fs_sample/
zephyr/samples/subsys/fs/fs_sample/
├── CMakeLists.txt
├── Kconfig
├── README.rst
├── boards
│   ├── apollo4p_evb.conf
│                      :
│   ├── nucleo_g431kb.overlay             <- ここに nucleo_g431kb.overlay を配置
│                      :
│   └── stm32h747i_disco_stm32h747xx_m7.conf
├── prj.conf
├── prj_ext.conf
├── sample.yaml
└── src
    └── main.c
fs_sample のビルドと書き込み
west build -p -b nucleo_g431kb zephyr/samples/subsys/fs/fs_sample/
west flash --runner openocd
fs_sample のログ出力
$ cu -s 115200 -l /dev/ttyUSB1 
Connected.
*** Booting Zephyr OS build v4.3.0-3523-g588d22464d13 ***
[00:00:00.034,000] <inf> sd: Maximum SD clock is under 25MHz, using clock of 8000000Hz
[00:00:00.034,000] <inf> main: Block count 7744512
Sector size 512
Memory Size(MB) 3781
[00:00:00.068,000] <inf> sd: Maximum SD clock is under 25MHz, using clock of 8000000Hz
Disk mounted.
[00:00:00.108,000] <inf> sd: Maximum SD clock is under 25MHz, using clock of 8000000Hz

Listing dir /SD: ...
[FILE] SOME.DAT (size = 0)
[DIR ] SOME

PC で SDカードの中身を確認すると書き込まれていることが確認できます。

image.png

7. まとめ

今回、記事を書いている間に、あれもこれもとネタが出てきてカロリー高くなってしまったので、一旦ここで記事を分割しておきます。

少なくともこの記事に沿って手を動かすことで、Nucleo G431KB / STM32G431KBT6 向けの設定はある程度自由に変更できるようになるかと思います。

次回は、この overlay を踏み込んで解説することで、他のボード向けの overlay も自分で書ける応用編を考えています。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?