RIOT OS SLWSTK6220A 启动套件详解:EZR32WG 低功耗开发、板级配置与烧录调试实践
【免费下载链接】RIOTRIOT - The friendly OS for IoT项目地址: https://gitcode.com/GitHub_Trending/riot/RIOT
本文基于 RIOT 仓库中 boards/slwstk6220a/doc.md 板卡文档展开,系统介绍 Silicon Labs SLWSTK6220A 启动套件(EZR32WG 无线开发板)在 RIOT-OS 中的硬件资源、外设映射、时钟与低功耗配置要点,以及烧录/调试命令。读完后你将掌握:如何在这块以超低功耗见长的 48 MHz Cortex-M4F 平台上配置时钟源、使能/禁用板载控制器与能量监视器模块,并借助 board.h、periph_conf.h 等板级源码验证文档中的每一条映射。
板卡概览
SLWSTK6220A 是 Silicon Labs 推出的 EZR32WG 868MHz 无线启动套件,核心 MCU 为 EFM32 系列,专为低功耗应用设计:具备节能外设、多种能量模式(Energy Mode)以及极短的唤醒时间。该开发板还集成了一片Advanced Energy Monitor(AEM,高级能量监视器),可以实时测量硬件与代码的功耗,实现代码级(code-level)能耗分析——这是它区别于普通评估板的关键能力。
MCU 规格
| 项目 | 参数 |
|---|---|
| MCU | EZR32WG330F256R60 |
| 内核家族 | ARM Cortex-M4F |
| 系列 | Series 0 |
| 厂商 | Silicon Labs |
| 厂商家族 | EZR32 Wonder Gecko |
| RAM | 32.0 KiB |
| Flash | 256.0 KiB |
| EEPROM | 无 |
| 主频 | 最高 48 MHz |
| FPU | 有 |
| MPU | 有 |
| DMA | 12 通道 |
| 定时器 | 3x 16-bit + 1x 16-bit(低功耗) |
| ADC/DAC | 12-bit ADC、12-bit DAC |
| UART | 2x UART、3x USART、2x LEUART |
| SPI | 3x USART |
| I2C | 2x |
| 供电 Vcc | 1.98 V - 3.8 V |
| 原理图 | 需通过 Silicon Labs Simplicity Studio 下载 |
MCU 数据手册(EZR32WG330_DataSheet)与参考手册(EZR32LG-RM)以及板卡手册(UG200 BRD4502C)均可在 Silicon Labs 官网获取,此处不再列外链。
扩展排针引脚定义(Pinout)
以下为板右侧扩展排针的引脚定义。当排针水平朝向你时,PIN 1 是左下角的触点:
| PIN | PIN | ||
|---|---|---|---|
| 3V3 | 20 | 19 | RES |
| 5V | 18 | 17 | RES |
| PD6 | 16 | 15 | PD7 |
| PD5 | 14 | 13 | PF13 |
| PD4 | 12 | 11 | PB11 |
| PD3 | 10 | 9 | PE1 |
| PD2 | 8 | 7 | PE0 |
| PD1 | 6 | 5 | PC7 |
| PD0 | 4 | 3 | PC6 |
| VMCU | 2 | 1 | GND |
注意:
- Silicon Labs 各启动套件的排针引脚定义并不完全相同,移植代码时务必以对应板卡文档为准;
- 部分引脚在板载控制器(Board Controller)使能时被其占用。
外设映射(Peripheral Mapping)
| 外设 | 编号 | 硬件 | 引脚 | 备注 |
|---|---|---|---|---|
| ADC | 0 | ADC0 | CHAN0: 片内温度 | 端口固定,不支持 14/16-bit 分辨率 |
| DAC | 0 | DAC0 | CHAN0: PB11 | 端口固定,与 I2C 共用 |
| I2C | 0 | I2C0 | SDA: PE0, SCL: PE1 | I2C_SPEED_LOW与I2C_SPEED_HIGH的实际时钟速率有偏差 |
| PWM | 0 | TIMER0 | CHAN0: PF6, CHAN1: PF7 | 映射到 LED0 和 LED1 |
| RTT | - | RTC | RTT 与 RTC 二选一(见下文) | |
| RTC | - | RTC | RTC 或 RTT 二选一(见下文) | |
| SPI | 0 | USART1 | MOSI: PD0, MISO: PD1, CLK: PD2 | |
| Timer | 0 | TIMER1 + TIMER2 | TIMER1 作预分频器(必须相邻) | |
| 1 | LETIMER0 | |||
| UART | 0 | UART0 | RX: PE1, TX: PE0 | STDIO 输出 |
| 1 | LEUART0 | RX: PD5, TX: PD4 | 波特率受限(见下文) |
从 periph_conf.h 可以看到 RIOT 对该映射的具体落实:
- I2C:配置为
I2C1设备,SDA/SCL 为 PE0/PE1,路由位置I2C_ROUTE_LOCATION_LOC2,速率I2C_SPEED_NORMAL,并显式启用内部上拉(use_internal_pull_ups = true)——这解释了板上 SDA/SCL 无需外部上拉电阻的设计。 - SPI:
USART1设备,MOSI/MISO/CLK 为 PD0/PD1/PD2,路由USART_ROUTE_LOCATION_LOC1,与文档一致。 - PWM:
TIMER0设备,两通道引脚 PF6/PF7(路由 LOC2),正好对应板上两颗 LED(PF6=LED0、PF7=LED1),因此 PWM 与 LED 共享引脚。 - Timer 0:
TIMER2计时 +TIMER1预分频的级联(cascade)结构,3 个通道;Timer 1:低功耗LETIMER0,2 个通道。 - UART:
UART_DEV(0)由USART2承担(RX: PB4, TX: PB3),UART_DEV(1)由LEUART0承担(RX: PD5, TX: PD4)。从源码结构看,RIOT 将板载控制器使用的 STDIO 串口分配给了USART2,而文档表格中的 “UART0: PE0/PE1” 描述的是芯片级 UART0 硬件的引脚,两者属于不同层次的路由选择,以periph_conf.h的实际配置为准。
用户接口(按钮与 LED)
| 外设 | 编号 | 宏定义 | 引脚 | 备注 |
|---|---|---|---|---|
| Button | 0 | PB0_PIN | PE3 | |
| 1 | PB1_PIN | PE2 | ||
| LED | 0 | LED0_PIN | PF6 | 黄色 LED |
| 1 | LED1_PIN | PF7 | 黄色 LED |
以上定义均可在 board.h 中找到,其中还封装了便捷的LED0_ON/LED0_OFF/LED0_TOGGLE(gpio_set/gpio_clear/gpio_toggle)宏,应用可直接调用。
板上其他资源
board.h中还定义了以下板级资源:
- 核温传感器:
CORETEMP_ADC = ADC_LINE(0),即 ADC 第 0 通道(片内温度输入); - 低功耗存储 LCD(Sharp LS013B7DH03):
DISP_SPI = SPI_DEV(0),COM 引脚 PE10、CS 引脚 PE11、片选DISP_SELECT_PIN = PA8、电源DISP_POWER_PIN = PA10; - 温湿度传感器 Si7021:挂在
I2C_DEV(0)上,使能引脚SI7021_EN_PIN = PF8; - 板载控制器使能脚:
BC_PIN = PA12。
功能实现状态
| 设备 | ID | 支持 | 备注 |
|---|---|---|---|
| MCU | EZR32WG | 是 | 支持能量模式(Power modes) |
| 底层驱动 | ADC | 是 | |
| DAC | 是 | ||
| Flash | 是 | ||
| GPIO | 是 | 中断在引脚间共享(见参考手册) | |
| I2C | 是 | ||
| PWM | 是 | ||
| RTC | 是 | 以 RTT 或 RTC 方式提供 | |
| SPI | 是 | 仅主模式 | |
| Timer | 是 | ||
| UART | 是 | USART 与 SPI 共享;LEUART 波特率受限 | |
| USB | 否 | ||
| LCD 驱动 | LS013B7DH03 | 是 | 通过 U8g2 包驱动 Sharp 低功耗存储 LCD |
| 温湿度传感器 | Si7021 | 是 | Silicon Labs 温湿度传感器 |
其中 SAUL 传感器接口的默认配置可以在 Makefile.dep 中看到:启用saul_default时自动引入efm32_coretemp、saul_gpio和si7021模块;同时该文件无条件加入boards_common_silabs、silabs_aem、silabs_bc三个公共模块,这正是下文“板载控制器默认使能、AEM 默认使能”两个结论的构建系统证据。
板级配置要点
板载控制器(Board Controller)
该启动套件带有一个 Board Controller,它提供一个虚拟串口,并通过一个 GPIO 引脚使能。
- 默认使能。可通过
make DISABLE_MODULE=silabs_bc关闭该模块。 - 使用虚拟串口前,请确保已安装最新版板载控制器固件。
- 板载控制器固定将虚拟串口配置为115200 波特率、8 位数据、无校验、1 位停止位,MCU 侧必须使用相同参数。
这一约束在驱动源码 boards/common/silabs/drivers/bc/bc.c 中有硬性保障:
#if ((STDIO_UART_DEV) != (UART_DEV(0))) #error "The BC requires UART_DEV(0)." #endif #if ((STDIO_UART_BAUDRATE) != 115200) #error "The BC requires a baud rate of 115200." #endif即 STDIO 必须落在UART_DEV(0)上且波特率必须为 115200,否则编译直接报错;bc_init()随后将BC_PIN(本板为 PA12)配置为输出并置高以激活板载控制器。
另外,低功耗 LCD 在DISP_SELECTED引脚(PA8)为低时会被板载控制器占用。该引脚不由板级初始化代码处理,如果你想在应用中控制这块 LCD,必须自行初始化该引脚。
高级能量监视器(Advanced Energy Monitor)
开发板上的 AEM 可接入 Simplicity Studio 开发软件,测量能耗并与代码关联,实现代码级功耗分析:
- 板载控制器负责测量能耗;
- 为了实时关联代码,驱动会配置CoreDebug外设,通过SWO端口输出 MCU 寄存器与中断数据(PC/IRQ 采样)。
默认使能,可通过make DISABLE_MODULE=silabs_aem关闭。其初始化逻辑见 boards/common/silabs/drivers/aem/aem.c:
void aem_init(void) { /* do not initialize if debugger is not connected */ if (!DBG_Connected()) { return; } /* enable GPIO clock for configuring SWO pins */ ... /* enable PC and IRQ sampling output */ DWT->CTRL = AEM_DWT_CTRL; /* set TPIU prescaler to 16 */ TPI->ACPR = AEM_TPI_ACPR; ... }从源码可见:未连接调试器时aem_init()直接返回(零开销);连接后依次开启 SWO 路由、CoreDebug 的TRCENA、DWT 的 PC/IRQ 采样,并将 TPIU 预分频设为 16、协议设为 NRZ。
注意:Simplicity Studio 关联代码需要调试符号。RIOT 默认使用 GDB 调试符号,而 Simplicity Studio 要求DWARF-2调试符号(GCC 参数-gdwarf-2),使用 AEM 时需据此调整编译参数。
时钟选择
各外设可选的时钟源如下。建议先阅读 Silicon Labs 应用笔记AN0004.0(EFM32 CMU)了解时钟系统。
时钟源:
| 源 | 内部 | 速率 | 备注 |
|---|---|---|---|
| HFRCO | 是 | 14 MHz | 启动时使能,可修改 |
| HFXO | 否 | 48 MHz | |
| LFRCO | 是 | 32.768 kHz | |
| LFXO | 否 | 32.768 kHz | |
| ULFRCO | 否 | 1 kHz | 作为时间源不够可靠 |
时钟分支(Branch)可选的源:
| 分支 | 可用源 | 备注 |
|---|---|---|
| HF | HFRCO, HFXO | 内核与外设 |
| LFA | LFRCO, LFXO | 低功耗定时器 |
| LFB | LFRCO, LFXO, CORELEDIV2 | 低功耗 UART |
CORELEDIV2是一个派生源,取决于为内核供电的时钟源,并做 2 或 4 分频以避免超过最大时钟频率(由 EMLIB 的 EML 机制自动处理)。上表速率针对本启动套件。
时钟频率必须对代码已知,才能保证速率与波特率计算正确。若你的 HFXO/LFXO 与上表不同,请在编译时传入EFM32_HFXO_FREQ=freq_in_hz与EFM32_LFXO_FREQ=freq_in_hz。
分支时钟源可以覆盖,例如添加编译定义CLOCK_LFA=cmuSelect_LFRCO。periph_conf.h 中的默认值印证了该机制:
#ifndef CLOCK_HF #define CLOCK_HF cmuSelect_HFXO #endif #ifndef CLOCK_CORE_DIV #define CLOCK_CORE_DIV cmuClkDiv_1 #endif #ifndef CLOCK_LFA #define CLOCK_LFA cmuSelect_LFXO #endif #ifndef CLOCK_LFB #define CLOCK_LFB cmuSelect_LFXO #endif即默认:HF 走 HFXO(48 MHz 晶振)、核心不分频、LFA/LFB 走 LFXO(外部 32.768 kHz 晶振)。所有宏均带#ifndef保护,允许通过编译定义覆盖。
低功耗外设与 LEUART 波特率限制
低功耗 UART(LEUART)可以使用低速时钟工作。当 LFB 时钟源为 LFRCO 或 LFXO 时,LEUART 在EM2能量模式下仍可用,但波特率被限制在 9600。若需要更高速率,应把 LFB 时钟源切到CORELEDIV2。
注意:此设置不会影响板级定义中的外设映射,请确保应用不要引用这些受限的低功耗外设。
RTC 还是 RTT
RIOT-OS 同时支持Real-Time Ticker(RTT)和Real-Time Clock(RTC)。但该 MCU 家族的硬件只有一个 24-bitReal-Time Counter,本质上只是 ticker。RIOT 提供了 ticker-to-calendar 兼容层,代价是额外代码体积(时间戳与时钟结构之间的互相转换)。按 1 Hz 间隔配置时,RTC 每194 天溢出一次;使用 ticker-to-calendar 模式时该周期被人为延长。因此在该板上,RIOT 通常以 RTT 方式提供计时(periph_conf.h中RTT_FREQUENCY默认 1 Hz),需要日历时间的模块再走兼容层。
与之配套的是 ztimer 配置,见 board.h:默认使用TIMER_DEV(0)、基准 250 kHz(更高精度);若开启CONFIG_EFM32_ZTIMER_USE_LETIMER,则改用TIMER_DEV(1)(LETIMER0)、基准 32.768 kHz,两种模式下ztimer_set/ztimer_sleep的指令开销补偿值(24/28 或 37 周期)也做了区分。
EMLIB 的使用
本移植使用 Silicon Labs 的EMLIB对寄存器访问做抽象:
- 有一定开销,但保证设备被正确初始化、内置芯片勘误(errata)处理并简化开发;最大开销出现在外设配置阶段,大量 read/write/get/set 方法以 inline 或宏实现,无运行时代价;
- EMLIB 附带断言(assertions),可确保外设被正确使用。传入编译定义
DEBUG_EFM即可启用; - EMLIB 采用 zlib 风格许可证(Silicon Labs 授权),允许源码分发。
引脚位置(Pin Locations)
EFM32 平台支持将外设映射到不同引脚(预定义 location)。periph_conf.h中的定义通常由两部分组成:location 编号与实际引脚。实际引脚用于 GPIO 驱动配置,location 用于把外设路由到这些引脚——两者必须匹配,详见数据手册中的路由表。
板级初始化源码解析
板级代码量很小,全部逻辑集中在 board.c:
void board_init(void) { #ifndef RIOTBOOT /* perform common board initialization */ board_common_init(); #ifdef MODULE_SI7021 /* initialize the Si7021 sensor */ gpio_init(SI7021_EN_PIN, GPIO_OUT); gpio_set(SI7021_EN_PIN); #endif #endif }board_common_init()来自公共层 boards/common/silabs/board_common.c,内部调用bc_init()与aem_init()(分别处理板载控制器与 AEM);- 若链接了
si7021驱动模块,则将传感器使能脚SI7021_EN_PIN(PF8)拉高上电; - 处于
RIOTBOOT(bootloader)编译时整体跳过,保持最小化。
boards/slwstk6220a/Makefile 只有一行关键内容DIRS = $(RIOTBOARD)/common/silabs,说明本板复用了 Silicon Labs 公共板级层;而模块依赖、SAUL 默认传感器组合则声明在 Makefile.dep 中,符合 RIOT 的模块依赖惯例。
编译、烧录与调试
烧录需要SEGGER J-Link调试器。RIOT 支持的命令如下:
# 烧录 BOARD=slwstk6220a make flash # 启动 GDB 调试 BOARD=slwstk6220a make debug # 仅启动调试服务器,连接自己的调试器 BOARD=slwstk6220a make debug-server # 部分板卡支持(有限的)模拟运行 BOARD=slwstk6220a make emulate结合前文,常用构建组合示例:
# 关闭板载控制器(需要 PE0/PE1、PA12 等引脚给应用使用) BOARD=slwstk6220a make flash DISABLE_MODULE=silabs_bc # 关闭 AEM(不连接 Simplicity Studio 做功耗分析时) BOARD=slwstk6220a make flash DISABLE_MODULE=silabs_aem # 使用 HFXO/LFXO 非默认频率时 BOARD=slwstk6220a make CFLAGS="-DEFM32_HFXO_FREQ=48000000 -DEFM32_LFXO_FREQ=32768" # 覆盖 LFA 时钟源 BOARD=slwstk6220a make CFLAGS="-DCLOCK_LFA=cmuSelect_LFRCO" # 启用 EMLIB 断言 BOARD=slwstk6220a make CFLAGS="-DDEBUG_EFM"小结
SLWSTK6220A 在 RIOT 中的移植围绕“低功耗”这一主线展开:默认时钟配置使用 HFXO + LFXO 以获得 48 MHz 高性能与 32.768 kHz 精准低频源;LEUART 可在 EM2 下以 9600 波特率继续通信;RTC/RTT 由 24-bit RTC 计数器 + ticker-to-calendar 兼容层折中实现。工程化层面,板载控制器(虚拟串口)与 AEM(代码级能耗分析)均以独立模块silabs_bc/silabs_aem提供、默认使能且可一键禁用,其强制约束(STDIO 必须为 UART0 @ 115200、DWARF-2 符号)在源码中以编译期断言和调试器连接检测实现。所有映射关系均可在 boards/slwstk6220a/include/periph_conf.h、boards/slwstk6220a/include/board.h 与公共层 boards/common/silabs/ 中逐项核验。
【免费下载链接】RIOTRIOT - The friendly OS for IoT项目地址: https://gitcode.com/GitHub_Trending/riot/RIOT
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考