Zephyr Board 配置指南¶
1 概述¶
Zephyr 使用一个名为 Board 的概念将各个板级硬件区分开,于是我们可以使用不同的 “board” 来编译不同的 App 工程;这种特性为实际项目提供了某种灵活性:如果 App 代码架构规划合理,将有办法使其很容易在不同 board 甚至 SoC 之间进行移植,缩短后续的开发周期。
Zephyr 默认的 board 存放目录为zephyr\boards
,而对于 PAN1080 来说,其支持的所有 boards 所在目录为zephyr\boards\arm
。目前 SDK 中支持 4 种 PAN108x EVB Board,及 1 种 PAN108x Mesh Dongle Board:
pan108xxa1_evb
:子板主控型号为PAN108X-XA1
(512KiB Flash Size、32 Pin)pan108xxa3_evb
:子板主控型号为PAN108X-XA3
(512KiB Flash Size、48 Pin)pan108xxb1_evb
/pan108xxb1_mesh_dongle
:子板主控型号为PAN108X-XB1
(1MiB Flash Size、32 Pin)pan108xxb5_evb
:子板主控型号为PAN108X-XB5
(1MiB Flash Size、64 Pin)
2 PAN1080 Evaluation Board¶
下面以 pan108xxb5_evb
board 为例,介绍相关文件含义。
pan108xxb5_evb
目录树结构如下:
<home>/01_SDK/zephyr/boards/arm/pan108xxb5_evb
├─board.cmake
├─Kconfig.board
├─Kconfig.defconfig
├─pan108xxb5_evb.dts
├─pan108xxb5_evb.yaml
└─pan108xxb5_evb_defconfig
其中:
board.cmake
:板级 CMake 配置;Kconfig.board
:板级 Kconfig 定义;Kconfig.defconfig
:板级 Kconfig 默认值,配置后在 Menuconfig 中可修改;pan108xxb5_evb.dts
:板级 Devicetree 定义;pan108xxb5_evb.yaml
:板级测试相关信息(用于 zephyr 自动化单元测试系统);pan108xxb5_evb_defconfig
:板级 Kconfig 默认值,配置后在 Menuconfig 中不可修改;
2.1 board.cmake¶
board.cmake
文件用于描述当前板级的 cmake 信息,目前主要是配置了 Jlink 相关参数,供 JLink 烧录和调试的时候调用:
# SPDX-License-Identifier: Apache-2.0
board_runner_args(jlink "--device=PAN1080XB" "--speed=2000")
include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake)
include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake)
注:此文件非必要请不要修改,唯一可考虑修改的参数为
"--speed=2000"
,可以根据实际情况修改 JLink 通信速率。
2.2 Kconfig.board¶
Kconfig.board
文件用于描述当前板级的 Kconfig 定义,目前主要定义了当前 EVB 板的名称为BOARD_PAN108XXB5_EVB
,并通过一系列select
关键字,使能了 PAN1080 HAL 层的各个底层 Driver:
# PAN108X-XB5-EVB MCU configuration
# Copyright (c) 2020-2022 Shanghai Panchip Microelectronics Co.,Ltd.
# SPDX-License-Identifier: Apache-2.0
config BOARD_PAN108XXB5_EVB
bool "PAN108X-XB5 Evaluation Board"
depends on SOC_PAN1080XB5
select USE_PANPLAT_ACC
select USE_PANPLAT_ADC
select USE_PANPLAT_CLKTRIM
select USE_PANPLAT_DMAC
select USE_PANPLAT_FMC
select USE_PANPLAT_GPIO
select USE_PANPLAT_I2C
select USE_PANPLAT_I2S
select USE_PANPLAT_KSCAN
select USE_PANPLAT_LOWPOWER
select USE_PANPLAT_PWM
select USE_PANPLAT_PRF
select USE_PANPLAT_QDEC
select USE_PANPLAT_SPI
select USE_PANPLAT_TIMER
select USE_PANPLAT_UART
select USE_PANPLAT_USB
select USE_PANPLAT_WDT
select USE_PANPLAT_WWDT
select USE_PANPLAT_EFUSE
注:此文件非必要请不要修改,但如果希望新增一些板级 Kconfig 定义,则直接在文件结尾新增定义即可。
2.3 Kconfig.defconfig¶
Kconfig.defconfig
文件用于描述当前板级的默认值,并且此处配置的默认值是非强制的;换句话说,即使在此处配置了默认值,后续仍然可以在 Menuconfig 中或者 App 工程目录的prj.conf
文件中进行强制修改:
# PAN108X-XB5-EVB MCU configuration
# Copyright (c) 2020-2022 Shanghai Panchip Microelectronics Co.,Ltd.
# SPDX-License-Identifier: Apache-2.0
if BOARD_PAN108XXB5_EVB
config BOARD
default "pan108xxb5_evb"
# BT_CTLR depends on BT. When BT is enabled we should default to also
# enabling the controller.
config BT_CTLR
default y if BT
# Use Panchip BLE Link Layer instead of Zephyr's
choice BT_LL_CHOICE
default BT_LL_PANCHIP if BT_CTLR
endchoice
if BT_LL_PANCHIP
config BT_HCI_TX_STACK_SIZE
default 2048
endif # BT_LL_PANCHIP
# Change default Logging configurations
if LOG
config LOG_BUFFER_SIZE
default 5120
config LOG_STRDUP_BUF_COUNT
default 8
config LOG_DEFAULT_LEVEL
default 3
endif # LOG
if USB_DEVICE_STACK
config USB_DEVICE_VID
default 0x2FE4
config USB_DEVICE_PID
default 0x0001
config USB_DEVICE_MANUFACTURER
default "Panchip"
config USB_DEVICE_REMOTE_WAKEUP
default n
endif # USB_DEVICE_STACK
# Increase ztest_thread_stack[] from default 1024 to 2048, since
# the default size is not enough, such as when test fcb_raw cases.
config ZTEST_STACKSIZE
default 2048
depends on ZTEST
endif # BOARD_PAN108XXB5_EVB
注:此文件可以根据实际需要进行修改。
2.4 pan108xxb5_evb.dts¶
pan108xxb5_evb.dts
文件用于描述当前板级的 Devicetree 定义:
/*
* Copyright (c) 2020-2022 Shanghai Panchip Microelectronics Co.,Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*/
/dts-v1/;
#include <mem.h>
#include <panchip/pan1080/pan1080xb5.dtsi>
/ {
model = "Panchip PAN108X-XB5 Evaluation Board";
compatible = "panchip,pan108xxb5-evb", "panchip,pan1080xb5";
chosen {
zephyr,console = &uart0;
zephyr,shell-uart = &uart0;
zephyr,bt-mon-uart = &uart0;
zephyr,bt-c2h-uart = &uart0;
zephyr,sram = &sram0;
zephyr,flash = &flash0;
zephyr,code-partition = &slot0_partition;
};
soc {
pin-controller@40030000 {
/* port, pin, pinmux_name, pinmux_sel [, flag1, ... ] */
DT_PAN_PINS(p0, 1, uart0_rx, PAN1080_PIN_FUNC_P01_UART0_RX, input-enable);
DT_PAN_PINS(p0, 7, uart1_rx, PAN1080_PIN_FUNC_P07_UART1_RX, input-enable);
DT_PAN_PINS(p0, 4, qdec_x0, PAN1080_PIN_FUNC_P04_QDEC_X0, bias-pull-up, input-enable);
DT_PAN_PINS(p0, 5, qdec_x1, PAN1080_PIN_FUNC_P05_QDEC_X1, bias-pull-up, input-enable);
DT_PAN_PINS(p3, 1, spi0_miso, PAN1080_PIN_FUNC_P31_SPI0_MISO, input-enable);
};
};
leds {
compatible = "gpio-leds";
led_blue: led_b {
gpios = <&p1 6 GPIO_ACTIVE_HIGH>;
label = "LED_BLUE";
};
};
pwmleds {
compatible = "pwm-leds";
pwm_led_red: pwm_led_r {
pwms = <&pwm0 4 PWM_POLARITY_NORMAL>;
label = "RGB_LED_RED";
};
pwm_led_green: pwm_led_g {
pwms = <&pwm0 5 PWM_POLARITY_NORMAL>;
label = "RGB_LED_GREEN";
};
pwm_led_blue: pwm_led_b {
pwms = <&pwm0 6 PWM_POLARITY_NORMAL>;
label = "RGB_LED_BLUE";
};
};
buttons {
compatible = "gpio-keys";
key1: k1 {
label = "KEY_1";
gpios = <&p0 4 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
};
key2: k2 {
label = "KEY_2";
gpios = <&p0 5 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
};
};
aliases {
led0 = &led_blue;
sw0 = &key1;
pwm-led0 = &pwm_led_red;
pwm-led1 = &pwm_led_green;
pwm-led2 = &pwm_led_blue;
pwm-0 = &pwm0;
kscan0 = &kscan;
};
};
&clk_xth {
clock-frequency = <DT_FREQ_M(32)>;
/* Enable the 32 MHz high speed crystal oscillator */
status = "okay";
};
&clk_xtl {
clock-frequency = <32768>;
/* Enable the 32 KHz low speed crystal oscillator */
status = "okay";
};
&dpll {
/* f(dpll_output) = f(dpll_input) / clock_div * clock_mult */
clocks = <&clk_xth>;
clock-div = <2>; /* Fixed to 2 */
clock-mult = <4>; /* Can be 3 (48MHz) or 4 (64MHz) */
status = "okay";
};
&rcc {
clock-names = "clk_system", "clk_slow";
clocks = <&dpll &clk_xtl>;
clock-frequency-system = <DT_FREQ_M(64)>;
clock-frequency-slow = <32768>;
ahb-prescaler = <1>;
apb1-prescaler = <1>;
apb2-prescaler = <1>;
};
&dma0 {
status = "okay";
};
&acc {
status = "okay";
};
&p0 {
status = "okay";
};
&p1 {
status = "okay";
};
&p2 {
status = "okay";
};
&p3 {
status = "okay";
};
&p4 {
status = "okay";
};
&p5 {
status = "okay";
};
&uart0 {
current-speed = <921600>;
pinctrl-0 = <&p0_0_uart0_tx &p0_1_uart0_rx>;
status = "okay";
};
&uart1 {
current-speed = <115200>;
pinctrl-0 = <&p0_6_uart1_tx &p0_7_uart1_rx>;
status = "okay";
};
&timer0 {
freq = <16000000>;
status = "okay";
};
&timer1 {
freq = <8000000>;
status = "okay";
};
&timer2 {
freq = <16000000>;
status = "okay";
};
&pwm0 {
pinctrl-0 = <&p1_0_pwm0_ch4 &p1_1_pwm0_ch5 &p1_6_pwm0_ch6>;
status = "okay";
};
&adc {
#io-channel-cells = <1>;
status = "okay";
};
&qdec {
event-threshold = <100>;
polarity = "polarity-low";
resolution = "cnt-resolution-1x";
filter-threshold = "filter-threshold-3";
pinctrl-0 = <&p0_4_qdec_x0 &p0_5_qdec_x1>;
status = "okay";
};
&spi0 {
pinctrl-0 = <&p3_0_spi0_mosi &p3_1_spi0_miso &p0_2_spi0_cs &p0_3_spi0_clk>;
#address-cells = <1>;
#size-cells = <0>;
status = "okay";
};
zephyr_udc0: &usbd {
compatible = "panchip,pan-usbd";
status = "okay";
};
&wdt {
status = "okay";
};
&flash0 {
partitions {
compatible = "fixed-partitions";
#address-cells = <1>;
#size-cells = <1>;
boot_partition: partition@0 {
label = "mcuboot";
reg = <0x00000000 0x00010000>;
read-only;
};
slot0_partition: partition@10000 {
label = "image-0";
reg = <0x00010000 0x00060000>;
};
slot1_partition: partition@70000 {
label = "image-1";
reg = <0x00070000 0x00060000>;
};
scratch_partition: partition@D0000 {
label = "image-scratch";
reg = <0x000D0000 0x00020000>;
};
storage_partition: partition@f0000 {
label = "storage";
reg = < 0xf0000 0xF000 >;
};
};
};
注:此文件请谨慎修改,因为修改后可能会导致某些例程执行条件发生变化。如果某个 App 确实需要修改 dts 文件,则可以优先考虑通过 DTS Overlay 的方式进行修改,相关说明请参考 Zephyr配置系统指南 文档中的介绍。
2.5 pan108xxb5_evb.yaml¶
pan108xxb5_evb.yaml
文件用于描述当前板级的测试环境相关信息,供 zephyr 自动化单元测试系统解析,以了解当前的板级硬件资源情况:
identifier: pan108xxb5_evb
name: PAN108X-XB5 Evaluation Board
type: mcu
arch: arm
toolchain:
- zephyr
- gnuarmemb
- xtools
ram: 64
flash: 1020
supported:
- adc
- counter
- dma
- flash
- gpio
- i2c
- kscan
- pinmux
- pwm
- qdec
- serial
- spi
- usb
- watchdog
注:仅供 Zephyr 自动化单元测试系统使用,一般实际项目中可以不用关心此文件。
2.6 pan108xxb5_evb_defconfig¶
pan108xxb5_evb_defconfig
文件用于配置当前板级的默认值,并且此处配置的默认值是强制的,注意这点与Kconfig.defconfig
不同;换句话说,如果在此处配置了默认值,那么后续将无法在 Menuconfig 中或者 App 工程目录的prj.conf
文件中再进行修改:
# SPDX-License-Identifier: Apache-2.0
# SoC Configuration
CONFIG_SOC_SERIES_PAN1080=y
CONFIG_SOC_PAN1080XB5=y
# Board Configuration
CONFIG_BOARD_PAN108XXB5_EVB=y
# Kernel Memory Options (Total SRAM 64KB)
CONFIG_MAIN_STACK_SIZE=1280
CONFIG_IDLE_STACK_SIZE=1024
CONFIG_ISR_STACK_SIZE=1024
# Prevent Interrupt Vector Table in RAM
CONFIG_IS_BOOTLOADER=y
# Serial Drivers
CONFIG_SERIAL=y
CONFIG_UART_INTERRUPT_DRIVEN=y
# UART Console
CONFIG_CONSOLE=y
CONFIG_UART_CONSOLE=y
# Pinmux Driver
CONFIG_PINMUX=y
# GPIO Controller
CONFIG_GPIO=y
# Clock Control
CONFIG_CLOCK_CONTROL=y
# Enable stack sentinel feature to make it easy to find issue
# caused by stack overflow
CONFIG_STACK_SENTINEL=y
# Set default BT log level to 4 (DBG)
# CONFIG_BT_LOG_LEVEL_DBG=y
注:此文件可以根据实际需要进行修改。
3 创建一个自己的 Board¶
3.1 为什么要创建自己的 Board¶
由前面的介绍我们知道,SDK 中已经存在 2 个对应 PAN1080 EVB 的 board,其中的 DTS 文件描述了 EVB 的板级硬件资源以及各板级硬件模块之间的连接关系,Kconfig 文件中则配置了能保证各个例程均能正确运行所需要开启的 Zephyr 功能。
而然,对于一个实际项目来说,一定有单独的板级硬件,其中的硬件资源可能与 EVB 上的完全不同了,并且使用过程中所需的板级 Kconfig 配置也大概率会与 EVB 不同,因此,为自己的项目重新创建一个 zephyr board 是一个必要且合理的选择。
3.2 如何创建 Board¶
创建 Board 最简单的方法是从当前已有的模板中修改,方法如下(假设新的 board 硬件主控 SoC 型号与 pan108xxb5_evb 相同,如 PAN1080LB5
,并将新的 board 命名为my_custom_board
):
将
zephyr\boards\arm
路径下的pan108xxb5_evb
目录整体拷贝一份,并重新命名为my_custom_board
;进入
my_custom_board
子目录:将
pan108xxb5_evb.yaml
文件删除;分别将
pan108xxb5_evb.dts
和pan108xxb5_evb_defconfig
文件重命名为my_custom_board.dts
和my_custom_board_defconfig
;打开
Kconfig.board
文件,将其中的 Kconfig 定义修改为:config BOARD_MY_CUSTOM_BOARD bool "My Custom Board"
打开
Kconfig.defconfig
文件,将其开头的 if 判断条件,以及 BOARD 默认值改为:if BOARD_MY_CUSTOM_BOARD config BOARD default "my_custom_board" ... endif # BOARD_MY_CUSTOM_BOARD
打开
my_custom_board_defconfig
文件,将当前的 Board Configuration 修改为新的 board 名称:... # Board Configuration CONFIG_BOARD_MY_CUSTOM_BOARD=y ...
打开
my_custom_board.dts
文件,修改根节点下的model
与compatible
值,以与 EVB 作区分:... / { model = "My custom Board"; compatible = "vendor,my-custom-board", "panchip,pan1080a-afld"; ...
至此,一个除名称不同外,各种配置完全与 EVB 相同的可用 board 就创建好了;这时候我们打开
ZAL
工具,在 Board 下拉菜单上可以看到新创建的board已经被成功识别:我们选择这个新增的
my_custom_board
,编译 Synchronization 例程:直接点击
Flash
按钮进行烧录,查看 UART 串口 Log,可以看到例程成功运行,并且 board 名称也已经与我们新修改的相同:
注意:在实际项目中,仅仅将 Board 重命名是不够的,后续还应根据实际需要:
修改 DTS 文件中的其他部分,以符合实际的板级硬件情况;
修改 Kconfig 文件中的其他部分,以符合当前项目的实际需求;
4 更多相关文档¶
Zephyr Board Porting Guide:Zephyr官方板级目录移植指南