扩展板
扩展板也称为“附加板”或“子板”,连接到开发板上以扩展其功能和服务,让原型开发更简单、更模块化。在 Zephyr 中,扩展板功能提供符合 Zephyr 格式的扩展板描述,使扩展板更容易与应用兼容。
启用扩展板
在 west 命令中添加相应的 --shield 参数,即可启用对一个或多个扩展板的支持:
west build -b your_board --shield x_nucleo_idb05a1 --shield x_nucleo_iks01a1 your_app
也可以在项目的 CMakeLists.txt 中将其设为默认值:
set(SHIELD x_nucleo_iks01a1)
扩展板接口
扩展板由两个关键特征定义:
物理连接器 - 机械接口
电气信号 - 每个引脚的实际功能
扩展板与开发板之间的连接通过 Devicetree 文件描述:
开发板侧:开发板的 Devicetree 文件使用 GPIO 连接节点 将连接器引脚映射到微控制器的实际 GPIO 引脚。该文件还为通过连接器引出的总线定义标签(例如
arduino_i2c、arduino_spi、arduino_uart)。扩展板侧:扩展板的 .overlay 文件引用这些相同的标签,以描述其组件如何连接到开发板。
构建时,开发板的 Devicetree 与扩展板的 overlay 合并,形成完整的硬件配置描述。
例如,假设你有一块带有 Arduino 连接器但没有内置加速度计的开发板。你可以通过 Arduino 扩展板添加加速度计:
开发板的 Devicetree 定义了一个
arduino_i2c标签:它表示 Arduino 连接器上引出的 I2C 总线加速度计扩展板的 overlay 文件也引用
arduino_i2c,以表明它使用同一条 I2C 总线。如果需要使用连接器上的 GPIO 引脚,它会引用开发板 Devicetree 中定义的 GPIO 连接节点(例如arduino_header)。
随后,当你为这块开发板及其扩展板进行构建时,Zephyr 会自动将它们“连接”起来。
备注
某些开发板和扩展板可能仅支持扩展板硬件接口的部分功能。有关更多详细信息,请参阅各自的文档。
Arduino MKR
这是 Arduino MKR 开发板的外形规格。
相关的 Devicetree 节点标签:
arduino_mkr_header有关 GPIO 引脚定义以及在 Devicetree 文件中使用时需要包含的文件的详细信息,请参阅arduino-mkr-header。arduino_mkr_i2carduino_mkr_spiarduino_mkr_serial
Arduino Nano
这是 Arduino Nano 开发板的外形规格。
相关的 Devicetree 节点标签:
arduino_nano_header有关 GPIO 引脚定义以及在 Devicetree 文件中使用的包含文件的详细信息,请参阅arduino-nano-header。arduino_nano_i2carduino_nano_spiarduino_nano_serial
Arduino Uno R3
这是 Arduino Uno R3 开发板的外形规格。
相关的 Devicetree 节点标签:
arduino_header有关 GPIO 引脚定义以及在 Devicetree 文件中使用的包含文件的详细信息,请参阅arduino-header-r3。arduino_adc请参阅arduino,uno-adcarduino_pwm请参阅arduino-header-pwmarduino_serialarduino_i2carduino_spi
有关技术细节,请参阅 Arduino Uno R3 pinout 。
摄像头和显示器连接器
这些连接器描述了摄像头和显示器的连接方式(严格来说,它们并非扩展板)。
ESP-01
这是用于 ESP-01 Wi-Fi 模块的 8 引脚排针接口。
相关的 Devicetree 节点标签:
esp_01_header有关 GPIO 引脚定义以及在 Devicetree 文件中使用的包含文件的详细信息,请参阅esp-01-header。esp_01_serial
Feather
这是 Adafruit Feather 系列开发板的外形规格。用于 Feather 开发板的扩展板称为 Featherwing。
相关的 Devicetree 节点标签:
feather_headerGPIO 引脚定义请参见adafruit-feather-header。feather_adcfeather_i2cfeather_serialfeather_spi
Microbit
此接口用于 Microbit 开发板的板边连接器。
GPIO 引脚定义和技术要求链接请参见 microbit,edge-connector 。
mikroBUS™
这是由 Mikroe 开发的附加板接口标准。
相关的 Devicetree 节点标签:
mikrobus_headerGPIO 引脚定义和技术规范链接请参见mikro-bus。mikrobus_adcmikrobus_i2cmikrobus_pwmmikrobus_spimikrobus_serial
请注意,具有多个 mikroBUS™ 连接器的开发板可能会定义诸如 mikrobus_2_spi 这样的标签。
Pico
这是 Raspberry Pi Pico 开发板的外形规格。
相关的 Devicetree 节点标签:
pico_headerGPIO 引脚定义请参见raspberrypi,pico-header。pico_i2c一个节点标签,与节点标签pico_i2c0或pico_i2c1指向同一节点。它引用应优先使用或默认使用的节点。pico_i2c0pico_i2c1pico_serialpico_spi
ST Morpho
意法半导体的开发板通常使用 ST Morpho 扩展板接口。
相关的 Devicetree 节点标签:
st_morpho_header有关 GPIO 引脚定义以及可在 Devicetree 文件中使用的包含文件的详细信息,请参阅st-morpho-header。st_morpho_lcd_spist_morpho_flash_spi
ST Zio
意法半导体的 STM32 Nucleo-144 开发板提供 ST Zio 连接器,它是 Arduino Uno V3 连接器的扩展,通过四个排针(CN7、CN8、CN9 和 CN10)引出更多 STM32 I/O。
相关的 Devicetree 节点标签:
st_zio_header有关 GPIO 引脚定义以及可在 Devicetree 文件中使用的包含文件的详细信息,请参阅st-zio-header。
STMod+
这是部分意法半导体 Discovery 开发板和评估开发板上配备的 20 引脚扩展连接器。
相关的 Devicetree 节点标签:
stmod_plus_connector有关 GPIO 引脚定义以及可在 Devicetree 文件中使用的包含文件的详细信息,请参阅st,stmod-plus-connector。stmod_adcstmod_i2cstmod_pwmstmod_serialstmod_spi
当外设连接到 STMod+ 连接器并在开发板的 Devicetree 中启用时,开发板可能会提供额外的接口标签。
Xiao
这是 Seeeduino XIAO 开发板的外形规格。
相关的 Devicetree 节点标签:
xiao_d有关 GPIO 引脚定义,请参阅seeed,xiao-gpio。xiao_spixiao_i2cxiao_serialxiao_adcxiao_dac
zephyr_i2c / Stemma QT / Quiic
这些是四引脚 I2C 连接器。SparkFun 将这些连接器称为“Qwiic”,Adafruit 则将其称为“Stemma QT”。I2C 连接器有四个引脚:GND、+3.3 伏、I2C 数据和 I2C 时钟。最常见的物理连接器是引脚间距为 1.0 mm 的 JST-SH。
由于品牌名称不同,该接口统一标记为“zephyr_i2c”。
有关说明和更多详细信息的链接,请参阅 stemma-qt-connector 和 grove-header 。
相关的 Devicetree 节点标签:
zephyr_i2c
ST M.2 串行存储器连接器
部分 STMicroelectronics Nucleo-144 开发板提供 ST 专用的 M.2 串行存储器连接器,用于通过 XSPI 连接外部串行存储器,同时提供 I2C 和连接器 GPIO 等辅助信号。
相关的 Devicetree 节点标签:
m2mem_connector有关 GPIO 引脚定义以及在 Devicetree 文件中使用的包含文件的详细信息,请参阅st,m2-memory-connector。m2mem_i2cm2mem_xspi
扩展板移植与配置
扩展板配置文件位于 boards/shields 下的开发板目录中:
boards/shields/<shield>
├── shield.yml
├── <shield>.overlay
├── Kconfig.shield
├── Kconfig.defconfig
└── pre_dt_shield.cmake
这些文件提供的扩展板配置如下:
shield.yml :此文件以 YAML 格式提供扩展板的元数据。它必须包含以下字段:
name:在 Kconfig 和构建系统中使用的扩展板名称(必填)full_name:扩展板的完整商业名称(必填)vendor:扩展板的制造商或供应商(必填)supported_features:扩展板支持的硬件功能列表(可选)。为了帮助用户了解扩展板支持的功能,而无需深入查看其 overlay 文件,可以使用supported_features字段列出扩展板支持的功能类型。这些值应与 dts/bindings/binding-types.txt 文件中定义的值一致。
示例:
name: foo_shield full_name: Foo Shield for Arduino vendor: acme supported_features: - display - input
<shield>.overlay :此文件以 Devicetree 格式提供扩展板描述,并在编译前与开发板的 Devicetree 合并。
Kconfig.shield :此文件定义用于扩展板默认配置的扩展板 Kconfig 符号。为便于应用使用,此处的扩展板默认配置应与 编写 Devicetree 中的配置保持一致。
Kconfig.defconfig :此文件定义扩展板的默认配置,并与 编写 Devicetree 保持一致。因此,配置扩展板时应牢记,启用功能是应用的职责。
pre_dt_shield.cmake :此可选文件可用于向 Devicetree 编译器
dtc传递额外参数。
此外,为避免与可能在开发板层面定义的设备发生名称冲突,建议在扩展板的 Devicetree 描述中采用 <device>_<shield> 形式的设备节点标签,例如:
sdhc_myshield: sdhc@1 {
reg = <1>;
...
};
添加源代码
可以向扩展板添加源代码,以满足扩展板特有的配置要求(例如初始化例程、时序约束等),使其能够与不同的 Zephyr 组件正常协同工作。
备注
扩展板中的源代码不得用于上述用途之外的其他目的。可在多个扩展板(和/或目标)之间复用的通用功能不应放在这里。
要将源代码实际纳入构建,请添加一个 CMakeLists.txt 文件以及相应的源文件(在 CMake 中引用这些源文件的方式与 Zephyr 的其他部分相同,例如开发板)。
开发板兼容性
扩展板与开发板之间的硬件兼容性取决于是否采用常见开发板(如 Arduino 和 96boards)所使用的通用连接器。为实现软件兼容性,开发板还必须提供与其支持的连接器相匹配的配置。
这需要在两个不同的层面完成:
引脚复用:应正确配置连接器引脚,使其与扩展板引脚匹配
Devicetree:开发板的 Devicetree 文件
BOARD.dts应为每个连接器接口定义一个备用节点标签。例如,对于 Arduino I2C:
arduino_i2c: &i2c1 {};
开发板专用的扩展板配置
如果需要进行修改以使扩展板适配特定开发板或开发板修订版,可以向扩展板添加针对该开发板或开发板修订版的覆盖文件,以覆盖特定开发板所使用的扩展板描述,如下所示:
boards/shields/<shield>
└── boards
├── <board>_<revision>.overlay
├── <board>.overlay
├── <board>.defconfig
├── <board>_<revision>.conf
└── <board>.conf
扩展板变体
某些扩展板可能支持多个变体或修订版。在这种情况下,可以提供多个版本的扩展板描述:
boards/shields/<shield>
├── <shield_v1>.overlay
├── <shield_v1>.defconfig
├── <shield_v2>.overlay
└── <shield_v2>.defconfig
在这种情况下,可以使用扩展板特定的修订版名称:
west build -b None --shield shield_v2 your_app
还可以为特定的扩展板修订版提供开发板专用的配置:
boards/shields/<shield>
├── <shield_v1>.overlay
├── <shield_v1>.defconfig
├── <shield_v2>.overlay
├── <shield_v2>.defconfig
└── boards
└── <shield_v2>
├── <board>.overlay
└── <board>.defconfig
GPIO nexus 节点
扩展板外设访问的 GPIO 必须使用扩展板的 GPIO 抽象来标识,例如由 arduino-header-r3 兼容标识提供的抽象。提供该排针接口的开发板必须将排针引脚映射到 SoC 特定的引脚。为此,需要在开发板的 Devicetree 文件中加入一个如下所示的 nexus node :
arduino_header: connector {
compatible = "arduino-header-r3";
#gpio-cells = <2>;
gpio-map-mask = <0xffffffff 0xffffffc0>;
gpio-map-pass-thru = <0 0x3f>;
gpio-map = <0 0 &gpioa 0 0>, /* A0 */
<1 0 &gpioa 1 0>, /* A1 */
<2 0 &gpioa 4 0>, /* A2 */
<3 0 &gpiob 0 0>, /* A3 */
<4 0 &gpioc 1 0>, /* A4 */
<5 0 &gpioc 0 0>, /* A5 */
<6 0 &gpioa 3 0>, /* D0 */
<7 0 &gpioa 2 0>, /* D1 */
<8 0 &gpioa 10 0>, /* D2 */
<9 0 &gpiob 3 0>, /* D3 */
<10 0 &gpiob 5 0>, /* D4 */
<11 0 &gpiob 4 0>, /* D5 */
<12 0 &gpiob 10 0>, /* D6 */
<13 0 &gpioa 8 0>, /* D7 */
<14 0 &gpioa 9 0>, /* D8 */
<15 0 &gpioc 7 0>, /* D9 */
<16 0 &gpiob 6 0>, /* D10 */
<17 0 &gpioa 7 0>, /* D11 */
<18 0 &gpioa 6 0>, /* D12 */
<19 0 &gpioa 5 0>, /* D13 */
<20 0 &gpiob 9 0>, /* D14 */
<21 0 &gpiob 8 0>; /* D15 */
};
这指定了如何将 <&arduino_header 11 0> 这样的 Arduino 引脚引用转换为 <&gpiob 4 0> 这样的 SoC GPIO 引脚引用。
在 Zephyr 中,GPIO 指定符通常有两个参数(由 #gpio-cells = <2> 表示):引脚编号和一组标志。标志的低 6 位对应可在 Devicetree 中配置的特性。在某些情况下,需要使用非零标志值来告知驱动程序特定引脚的行为,例如:
drdy-gpios = <&arduino_header 11 GPIO_ACTIVE_LOW>;
预处理后,这会变成 <&arduino_header 11 1> 。通常,这种标志的存在会导致映射查找失败,因为没有标志值为非零的映射条目。 gpio-map-mask 属性指定,在查找时,使用引脚编号的所有位以及标志中除低 6 位以外的所有位来识别指定符。然后, gpio-map-pass-thru 指定将标志的低 6 位复制过去,因此 SoC GPIO 引用会按预期变为 <&gpiob 4 1> 。
有关此功能的更多信息,请参阅 nexus node 。