前回はZephyr OS付属のサンプルプログラムをビルドしてSeeeduino XIAOに書き込んでみました。
いよいよ、独自のプロジェクトを作ってマイアプリを作っていきましょう!✊ まずは、定番のHello world!を表示するファームウェアを作ってみます。
ちなみに、Hello, world!を表示するサンプルはZephyr OSにも含まれているので、ほぼそれと同じ内容になります。
プロジェクトフォルダの作成
上記記事ではでZephyr OSを~/zephyrproject/
以下にインストールし、その中に含まれているサンプルプロジェクトをビルドしました。
独自のプロジェクトを作成するときは、この~/zephyrproject/
以外の場所に、自分用のプロジェクトフォルダを作ってアプリを管理するのがよいでしょう。
ここでは、~/myprojects/
以下にアプリを作成していきます。たくさんアプリを作ることを想定して、その中にhello-world
フォルダを作って、そこにhello-worldというプロジェクトを作ることにします。
$ mkdir -p ~/myprojects/hello-world $ cd ~/myprojects/hello-world/
この中に必要なファイルを配置していきます。
プロジェクトファイルの作成
前回の記事で取り上げた通り、Zephyr OSのプロジェクトには最低限、CMakeLists.txt、prj.conf、ファームウェアのソースファイルの3つが必要です。
├── CMakeLists.txt ├── prj.conf └── src └── main.c
こんな感じになるようにファイルを作っていきましょう。
CMakeLists.txt
最低限の中身のCMakeLists.txtは次のようになります。
cmake_minimum_required(VERSION 3.13.1) find_package(Zephyr) project(hello_world) target_sources(app PRIVATE src/main.c)
find_pachage(Zephyr)
でZephyr OSのビルドシステムを取り込み、app
というターゲットにアプリのソースファイルを指定します。
project()
はプロジェクト名の指定です。
prj.conf
このファイルには、使用するZephyr OSの機能、追加で読み込むドライバ、設定値の変更などを指定します。
前回のLEDチカチカのサンプルプログラムには、GPIOドライバを読み込む設定が入っていましたね。
実はUARTでの文字出力はZephyr OSのデフォルトで有効になっているので、今回は何も書かなくても良いです。 ファイルが無くてもOKですが、一応コメントだけ書いておきます。
# Nothing needed
src/main.c
Hello, world!を表示するソースファイルがこちらです。
#include <zephyr.h> #include <sys/printk.h> void main(void) { printk("Hello World!\n"); }
とても簡単ですね。printk()
はZephyr OSのシステムコンソールに文字を出力する関数で、標準Cライブラリのprintf()
と似た機能を持ちます。
引数も同じように使えます。ただし、浮動小数点のフォーマット%f
をサポートしていないなど、軽量化のための制約もあります。
printk()
を使うには、KconfigのCONFIG_PRINTK
をy
に設定する必要がありますが、デフォルトでy
になっています。
そのため、prj.conf
でCONFIG_PRINTK=y
と書く必要はありません。
以上でプロジェクトが完成しました。
システムコンソールとは?
ところで、printk()の文字はどこに出力されるのでしょうか?🤔
これはZephyr OSのシステムコンソールに出力されます。そのシステムコンソールはKconfigやボードのデバイスツリーで設定されています。
Zephyr OSのソースツリー中のSeeeduino XIAOのボード定義フォルダをのぞいてみると、デバイスツリーファイルに次のような記述があります(抜粋)。
chosen { zephyr,console = &sercom4; zephyr,shell-uart = &sercom4; zephyr,sram = &sram0; zephyr,flash = &flash0; zephyr,code-partition = &code_partition; };
ここで、コンソールとしてsercom4が選択されていることがわかります。
sercom4というのはSeeeduino XIAOに搭載されているマイコンSAMD21のペリフェラルで、UART機能を持っています。
Seeeduino XIAOでは、sercom4のピンがUART TX/RXピン(D6/D7ピン)に割り当てられています。
なのでデフォルトのままだと、このUART TX/RXピンがコンソールとして使われることになります。
アプリ側でオーバーライドして、他のポートをコンソールにしたり、USBシリアルをコンソールにしたりもできます。
最終的なデバイスツリーは、ビルド結果のbuild/zephyr/zephyr.dts
に出力されるので、ここで確認できます。
また、Kconfigで出力先を変えた場合は、build/zephyr/.config
を見ると、CONFIG_UART_CONSOLE_ON_DEV_NAME="SERCOM1"
などと出力先が設定されていることもあります。
ビルド&書き込み
いよいよこのプロジェクトをビルドしてみましょう。 プロジェクトフォルダに入り、
$ west build -b seeeduino_xiao (略) Memory region Used Size Region Size %age Used FLASH: 10572 B 232 KB 4.45% SRAM: 3816 B 32 KB 11.65% IDT_LIST: 0 GB 2 KB 0.00%
とすれば、ビルドできます。最後にメモリ使用量を表示してくれます。FLASHが10KB、RAMが4KBくらい使われているようです。 まだまだ余裕ですね。
ビルド成果物はbuild/
というフォルダができてそこに出てきます。
ファームウェアバイナリファイルはbuild/zephyr/zephyr.bin
で、これをSeeeduino XIAOに書き込めばOKです。
動かしてみよう
ファームウェアを書き込んだらいよいよ動かしてみましょう。
私は市販のUSBシリアル変換基板を用意して、Seeeduino XIAOのUARTポートにつないでみました。
Seeeduino XIAOピン | USBシリアルピン | 説明 |
---|---|---|
3V3 | 3V3 | 電源(3.3V) |
GND | GND | グランド (0V基準電圧) |
TX | RxD | UART (XIAO→PC) |
RX | TxD | UART (PC→XIAO) |
今回はSeeeduino XIAOは出力だけで入力は無いので、PC→XIAOのピンはつながなくても大丈夫です。 実際に接続すると、次のようになりました。
電源を入れると、パソコン上のTera Termに文字が出力されました!🥰
最初の行はZephyr OSが自動的に出力しているみたいです。
とても単純なプログラムですが、これで自分のプロジェクトが作れるようになりましたね。 次回はSeeeduino XIAOのUSBポートからUSBシリアル出力してみたいと思います。