自分用memo
やってること
STM32 Nucleo-F746ZGボードでPWM出力可能な全ピン32ヶ所からPWMを出す。
Version
cd ~/zephyrproject/zephyr
cat VERSION
VERSION_MAJOR = 2
VERSION_MINOR = 7
PATCHLEVEL = 99
VERSION_TWEAK = 0
EXTRAVERSION =
なので、Zephyr 2.7.99
Zephyr 3系だと動かない可能性高し
west --version
v0.12.0
python --version
Python 3.7.6
プロジェクトの作成
appを作っていく。お好きなエディタでいくつかのファイルを作成・記述していく。
最小構成のディレクトリ
最小構成は以下の通り
参考:
https://docs.zephyrproject.org/latest/application/index.html#overview
<home>/app
├── CMakeLists.txt
├── prj.conf
└── src
└── main.c
今回はappの名前をprj_f746
とした。
ボード定義はzephyrに最初から含まれているnucleo_f746zgのものを利用する。
ただし、今回作成するPWMのアプリケーションに必要なタイマーの記述が、元のボード定義に不足していたため、新たにapp.overlay
ファイルを追加する必要がある。
<home>/app
├── CMakeLists.txt
├── prj.conf
├── app.overlay
└── src
└── main.c
CMakeLists.txt
prj_f746ディレクトリ直下にCMakeLists.txt
を作成
引用: https://docs.zephyrproject.org/latest/application/index.html#creating-an-application
cmake_minimum_required(VERSION 3.20.0)
find_package(Zephyr)
project(prj_f746)
target_sources(app PRIVATE src/main.c)
prj.conf
prj_f746ディレクトリ直下にprj.conf
を作成
標準だとGPIOしか有効になっていないので、PWMなどのおしゃれな機能を使おうとしても動かない。なお動かなくてもビルドエラーは出ない(n敗)。
以下を記述する。
CONFIG_PWM=y
src/main.c
PWMを全部出してみた。
ただし、nucleoに乗ってる青色LED(LD2, PB7)は動作チェック用に点滅(1Hz)動作にしてある。
この点滅動作含めコードのほとんどはblinkyのサンプルから流用している。
zephyr/samples/basic/blinky at main · zephyrproject-rtos/zephyr · GitHub
#include <zephyr.h>
#include <device.h>
#include <devicetree.h>
#include <drivers/gpio.h>
#include <drivers/pwm.h>
#include <stdio.h>
#define SLEEP_TIME_MS 1000
#define LED2_NODE DT_ALIAS(led2)
#if DT_NODE_HAS_STATUS(LED2_NODE, okay)
#define LED2 DT_GPIO_LABEL(LED2_NODE, gpios)
#define PIN DT_GPIO_PIN(LED2_NODE, gpios)
#define FLAGS DT_GPIO_FLAGS(LED2_NODE, gpios)
#else
#error "Unsupported board: led0 devicetree alias is not defined"
#define LED2 ""
#define PIN 0
#define FLAGS 0
#endif
void main(void)
{
const struct device *pwm[15];
const struct device *gpio_b;
bool led_on = true;
int ret;
char labelname[20];
const char pwm_enbl[15][4] =
{
{0,0,0,0},
{1,1,1,1},
{1,1,1,1},
{1,1,1,1},
{1,1,1,1},
{1,1,1,1},
{0,0,0,0},
{0,0,0,0},
{1,1,1,1},
{1,1,0,0},
{1,0,0,0},
{1,0,0,0},
{1,1,0,0},
{1,0,0,0},
{1,0,0,0}
};
gpio_b = device_get_binding("GPIOB");
if (gpio_b == NULL) {
return;
}
for(int8_t i = 1; i <= 14; i++ )
{
if(i >= 1 && i <= 5 || i >= 8 && i <= 14)
sprintf(labelname, "PWM_%d", i);
pwm[i] = device_get_binding(labelname);
}
for(int8_t i = 1; i <= 14; i++ )
{
for(int8_t j = 1; j <= 4; j++ )
{
if(pwm_enbl[i][j-1] == 1)
pwm_pin_set_usec(pwm[i], j, 200, 100, PWM_POLARITY_NORMAL);
}
}
ret = gpio_pin_configure(gpio_b, 7, GPIO_OUTPUT_ACTIVE | FLAGS);
while (1) {
gpio_pin_set(gpio_b, 7, (int)led_on);
led_on = !led_on;
k_msleep(SLEEP_TIME_MS);
}
}
app.overlay
dtsファイルの内容を補足する。
拡張子は.overlayだが、書式はdtsそのもの。
ファイル名は「app」まで含めて決められているため変えてはいけない(変える場合がCMakeListに記載する必要がある)
https://docs.zephyrproject.org/latest/guides/dts/howtos.html#set-devicetree-overlays
https://docs.zephyrproject.org/latest/guides/dts/intro.html
元になったと思われるArm Linuxのoverlayファイル(.dtso)では、先頭に
/dts-v1/;
/plugin/;
を記述する必要があるっぽい(参考:デバイスツリー Overlay について調べてみた - Qiita)が、Zephyrではむしろあっちゃダメっぽかった。
&timers1 {
st,prescaler = <0>;
status = "okay";
pwm1: pwm {
status = "okay";
pinctrl-0 = <&tim1_ch1_pe9 &tim1_ch2_pe11 &tim1_ch3_pe13 &tim1_ch4_pe14>;
pinctrl-names = "default";
};
};
&timers2 {
st,prescaler = <0>;
status = "okay";
pwm2: pwm {
status = "okay";
pinctrl-0 = <&tim2_ch1_pa15 &tim2_ch2_pb3 &tim2_ch3_pb10 &tim2_ch4_pb11>;
pinctrl-names = "default";
};
};
&timers3 {
st,prescaler = <0>;
status = "okay";
pwm3: pwm {
status = "okay";
pinctrl-0 = <&tim3_ch1_pb4 &tim3_ch2_pb5 &tim3_ch3_pb0 &tim3_ch4_pb1>;
pinctrl-names = "default";
};
};
&timers4 {
st,prescaler = <0>;
status = "okay";
pwm4: pwm {
status = "okay";
pinctrl-0 = <&tim4_ch1_pb6 &tim4_ch2_pd13 &tim4_ch3_pb8 &tim4_ch4_pb9>;
pinctrl-names = "default";
};
};
&timers5 {
st,prescaler = <0>;
status = "okay";
pwm5: pwm {
status = "okay";
pinctrl-0 = <&tim5_ch1_pa0 &tim5_ch2_pa1 &tim5_ch3_pa2 &tim5_ch4_pa3>;
pinctrl-names = "default";
};
};
&timers8 {
st,prescaler = <0>;
status = "okay";
pwm8: pwm {
status = "okay";
pinctrl-0 = <&tim8_ch1_pc6 &tim8_ch2_pc7 &tim8_ch3_pc8 &tim8_ch4_pc9>;
pinctrl-names = "default";
};
};
&timers9 {
st,prescaler = <0>;
status = "okay";
pwm9: pwm {
status = "okay";
pinctrl-0 = <&tim9_ch1_pe5 &tim9_ch2_pe6>;
pinctrl-names = "default";
};
};
&timers10 {
st,prescaler = <0>;
status = "okay";
pwm10: pwm {
status = "okay";
pinctrl-0 = <&tim10_ch1_pf6>;
pinctrl-names = "default";
};
};
&timers11 {
st,prescaler = <0>;
status = "okay";
pwm11: pwm {
status = "okay";
pinctrl-0 = <&tim11_ch1_pf7>;
pinctrl-names = "default";
};
};
&timers12 {
st,prescaler = <0>;
status = "okay";
pwm12: pwm {
status = "okay";
pinctrl-0 = <&tim12_ch1_pb14 &tim12_ch2_pb15>;
pinctrl-names = "default";
};
};
&timers13 {
st,prescaler = <0>;
status = "okay";
pwm13: pwm {
status = "okay";
pinctrl-0 = <&tim13_ch1_pf8>;
pinctrl-names = "default";
};
};
&timers14 {
st,prescaler = <0>;
status = "okay";
pwm14: pwm {
status = "okay";
pinctrl-0 = <&tim14_ch1_pf9>;
pinctrl-names = "default";
};
};
ビルドコマンド
west build -b nucleo_f746zg
実行コマンド
Nucleoを接続して
west flash
で自動的に書き込み・実行される。
青色LEDが点滅しだし、PWMが出るポートからPWMが出始める。
続き?
www.shujima.work
その他調べてわかったことメモ
プロジェクトフォルダの構造
https://docs.zephyrproject.org/latest/application/index.html
Zephyrにアプリケーションを追加する - みつきんのメモ
- projectdir
- build
- src
- main.c
- CMakeLists.txt
- prj.conf
- README.rst
- sample.yaml
- boards
my_custom_board_defconfig
my_custom_board.dts
my_custom_board.yaml
board.cmake
board.h
CMakeLists.txt
doc/
dts_fixup.h
Kconfig.board
Kconfig.defconfig
pinmux.c
support/
Kconfig
prj.conf
or <boardname>_defconfig
ファイル
- 一覧
- C++を使いたい場合は
CONFIG_CPLUSPLUS=y
- 各APIなどで追記を要求される
- ボード固有はdefconfig内に定義
defconfig
https://docs.zephyrproject.org/latest/guides/build/kconfig/setting.html#setting-configuration-values
Device Tree
デバイスツリーについて調べてみた - Qiita
[Linux][kernel] Device Tree についてのまとめ - Qiita
デバイスツリーのディレクトリ構成
- zephyr/
- boards/
- arm/
- nucleo_f746zg
- nucleo_f746zg.dts
- nucleoボードのデバイスツリー。f7のdtsiをincludeしている。
- dts/
- arm/
- st
- f7
- stm32f7.dtsi
- stm32f746.dtsi
- stm32f745.dtsi
- i2c4
- spi6
- can2
- mac(ethernet)
用語
- デバイスツリー
- dts
- ninja
- west
- zephyr用ツール群。名前の由来は、"Zephyr"は英語で西風の意だから?
- Kconfig