在 RT-Thread 上开发 Ambiq Apollo2 超低功耗 MCUBSP 结构、构建流程与外设驱动全解析【免费下载链接】rt-threadRT-Thread is an open source IoT Real-Time Operating System (RTOS). https://rt-thread.github.io/rt-thread/项目地址: https://gitcode.com/gh_mirrors/rt/rt-thread本指南以 RT-Thread 仓库中bsp/apollo2目录为核心系统讲解 Ambiq Micro Apollo2 评估板SKT的软硬件特性、RT-Thread BSP 工程结构、Keil/GCC 构建方式、板级初始化流程以及 UART、ADC、I2C、LED 等外设驱动的移植实现。读完本文你将掌握如何在 Apollo2 超低功耗平台上搭建 RT-Thread 开发环境、按需裁剪并启用外设驱动并理解其亚阈值功耗与深度休眠机制与 RT-Thread 空闲线程的配合方式。Ambiq Apollo2 评估板实物图SKT 版Apollo2 MCUAmbiq 第二代超低功耗控制器Apollo2 是 Ambiq Micro 推出的 Apollo MCU 产品系列中的第二代控制器其核心卖点是 Ambiq 的专利亚阈值功率优化技术Subthreshold Power Optimized TechnologySPOT平台。SPOT 技术使芯片可以在亚阈值电压区域工作从而在保持性能的同时实现数量级的功耗下降——按官方描述其功耗通常比性能相近的其他 MCU 产品降低 5 至 10 倍。这一特性决定了整个 BSP 的设计取向从系统时钟的选择、外设的开关控制到空闲时自动进入深度休眠处处都在为省电服务。从架构上看Apollo2 采用32 位 ARM Cortex-M4F 微控制器集成高达1 MB 闪存和256 KB RAM足以承载无线电协议栈与传感器处理开销同时仍保留充足的应用代码空间。芯片还提供串行主机接口IOM与 UART 端口用于和加速度计、陀螺仪、磁力计等外部传感器及射频模块通信。在仓库中该 BSP 的工程名与配置集中在bsp/apollo2目录其 Kconfig 通过SOC_APOLLO2符号自动选择ARCH_ARM_CORTEX_M4、RT_USING_COMPONENTS_INIT与RT_USING_USER_MAIN见 Kconfig是典型的 Cortex-M4 系列 BSP 配置入口。Apollo2 核心特性一览以下特性清单完整来自 BSP 的 README.md同时结合 rtconfig.h 与板级驱动源码进行了交叉印证可作为选型与驱动开发的参数依据。类别特性说明超低供电电流10 μA/MHz3.3 V 下从 Flash 执行从 RAM 执行同为 10 μA/MHz处理器ARM Cortex-M4最高 48 MHz含浮点单元FPU与内存保护单元MPU中断唤醒中断控制器WIC32 个中断支持在休眠时由外设唤醒存储器最多 1 MB Flash、256 KB 低漏电 RAM另有 16 KB 1/2 路组相联 Cache片外传感器接口14 bit、15 通道、最高 1.2 MS/s ADC电压比较器±2 ℃ 精度温度传感器串行外设6× I2C/SPI 主机 1× I2C/SPI 从机2× UARTPDM 单/双声道麦克风输入时钟源32.768 kHz XTAL、1.024 kHz LFRC、48 MHz HFRCRTC 基于 Ambiq AM08X5/18X5 系列工作范围1.8–3.6 V-4085 ℃封装选项2.5×2.5 mm 49 脚 CSP34 GPIO4.5×4.5 mm 64 脚 BGA50 GPIO从 RT-Thread 移植的角度看有几个参数直接决定了驱动代码的写法系统滴答基准板级代码使用 32.768 kHz 的 XTALSTIMER而非 ARM SysTick 作为 tick 源这从 board.c 中的SYSTICK_CLOCK_HZ (32768UL)与WAKE_INTERVAL计算可以看出。tick 频率由 rtconfig.h 的RT_TICK_PER_SECOND 500决定即每 1/500 秒触发一次比较中断。串口资源芯片提供 2 个 UARTBSP 默认启用 UART0GPIO1TX、GPIO2RX115200 波特率作为控制台UART1 的引脚为 GPIO8TX、GPIO9RX见 uart.c。ADC 通道评估板上将电池电压采样接到 GPIO35/ADCSE714 bit、软件触发 CTIMER 周期触发详见下文 ADC 一节。BSP 工程结构总览bsp/apollo2目录的布局遵循 RT-Thread 标准 BSP 组织方式各子目录职责清晰applications/main.c用户入口默认实现一个 LED 闪烁演示线程board/板级初始化与各外设驱动包含board.c、board.h以及uart.c、adc.c、i2c.c、spi.c、led.c、gpio.c、pdm.c、pwm.c、rtc.c、smbus.c、flash.c等libraries/Ambiq 官方 HALam_hal_*系列与寄存器定义regs/下的am_reg_*.h以及 Keilstartup_keil.s、GCCstartup_gcc.c、IARstartup_iar.c三种启动文件KconfigBSP 配置入口定义SOC_APOLLO2rtconfig.h当前工程的裁剪配置已生成rtconfig.pySCons 构建工具链配置project.uvprojx / template.uvprojxKeil MDK 工程rtthread.sctKeil 分散加载文件rtthread_link.ldGCC 链接脚本。构建环境与烧录流程构建方式由 rtconfig.py 控制默认工具链为KeilCROSS_TOOLkeilEXEC_PATHC:/Keil_v5同时支持 GCC如 Sourcery GCCarm-none-eabi-前缀。需要特别注意的是当前 BSP 尚未支持 IAR选择 iar 时脚本会直接报错退出见 rtconfig.py因此请勿在 IAR 环境下尝试构建本 BSP。各工具链的使用方式如下Keil MDK直接打开 project.uvprojx编译后由POST_ACTION调用fromelf生成rtthread.bin可通过板载 JTAG/SWD 调试接口烧录GCC 命令行设置环境变量RTT_CCgcc与RTT_EXEC_PATH指向工具链 bin 目录执行scons构建链接脚本使用 rtthread_link.ld最终产物为rtthread.binPOST_ACTION通过objcopy -O binary生成。工程还提供了分散加载文件 rtthread.sctKeil 构建时由armlink --scatter使用见 rtconfig.py。GCC 构建的链接参数中通过-u,am_reset_isr强制引用启动文件中的复位入口对应 GCC 启动文件 startup_gcc.c。板级初始化时钟、滴答与低功耗配置板级初始化入口是 board.c 中的rt_hw_board_init()它由 RT-Thread 启动流程在进入 main 之前调用主要完成以下工作系统时钟调用am_hal_clkgen_sysclk_select(AM_HAL_CLKGEN_SYSCLK_MAX)将系统时钟设为最高频率48 MHzCache 使能使用am_hal_cachectrl_defaults默认配置使能 16 KB Cache低功耗初始化am_low_power_init()使能内部 buck 转换器、初始化电源控制块、关闭复位后默认打开的电压比较器若未启用 RTC则让 RTC 运行在 LFRC 上并停掉 XT、禁用 RTC 振荡器见 board.c系统滴答SysTick_Configuration()使用 STIMER 的 Compare A 中断作为 tick 源——先使能中断、配置 STIMER 为清零冻结模式、设置比较增量WAKE_INTERVAL再以 32.768 kHz XTAL 启动见 board.c。对应的中断服务函数am_stimer_cmpr0_isr中调用rt_tick_increase()驱动 RT-Thread 时钟节拍见 board.c空闲低功耗钩子在启用RT_USING_IDLE_HOOK时将deep_power_save()注册为 idle 钩子board.c。该函数先am_hal_interrupt_master_disable()再调用am_hal_sysctrl_sleep(AM_HAL_SYSCTRL_SLEEP_DEEP)进入深度睡眠唤醒后重新使能中断见 board.c——这就是 RT-Thread 空闲线程与 Apollo2 超低功耗能力结合的落点系统无事可做时自动休眠中断到来时唤醒FPU 与存储优化通过am_hal_sysctrl_fpu_enable()使能 FPU 并开启惰性压栈lazy stacking降低中断开销同时调用am_hal_pwrctrl_memory_enable(AM_HAL_PWRCTRL_MEMEN_FLASH512K)关闭未使用的 Flash/SRAM 区块以节省功耗见 board.c串口与堆初始化初始化 UART、将控制台设备设置为uart0并以AM_SRAM_BEGIN到AM_SRAM_END256 KB见 board.h为堆区调用rt_system_heap_init()。堆起点根据编译器不同取自Image$$RW_IRAM1$$ZI$$LimitKeil、__segment_end(HEAP)IAR或__bss_endGCC见 board.c。外设驱动实现解析BSP 在board/下为每个外设提供了独立的驱动文件统一通过board.h中的宏开关如RT_USING_UART0、RT_USING_ADC、RT_USING_I2C0、RT_USING_SPI1、RT_USING_LED0等进行裁剪见 board.h。下面挑选四个有代表性的驱动展开。UART 串口驱动uart.cuart.c 将 Ambiq HAL 的 UART 封装为 RT-Thread 的rt_serial_device引脚分配UART0 为 GPIO1(TX)/GPIO2(RX)UART1 为 GPIO8(TX)/GPIO9(RX)启用时通过am_hal_gpio_pin_config带上 24K 上拉见 uart.c参数映射am_configure将 RT-Thread 的serial_configure波特率、数据位、停止位、校验位逐项映射到am_hal_uart_config_t默认波特率 115200并配置 7/8 级 RX FIFO 与 256 字节收发缓冲见 uart.c中断驱动使能AM_HAL_UART_INT_RX_TMOUT | AM_HAL_UART_INT_RXISR 中根据中断状态向 RT-Thread 上报RT_SERIAL_EVENT_RX_IND/RT_SERIAL_EVENT_TX_DONE见 uart.c从而支持 finsh/MSH 控制台与中断接收注册rt_hw_uart_init()以uart0/uart1名称注册两个串口设备并挂接中断入口am_uart0_isr/am_uart1_isr见 uart.c。控制台设备名由 rtconfig.h 的RT_CONSOLE_DEVICE_NAME uart0决定与 board 初始化中rt_console_set_device的调用相互对应。ADC 电池采样adc.cadc.c 实现了一个完整的定时触发 中断批量采集 消息队列上报的 ADC 采样链路非常值得参考通道定义电池电压接 GPIO35AM_HAL_PIN_35_ADCSE7ADC 槽位为AM_HAL_ADC_SLOT_CHSEL_SE714 bit 分辨率见 adc.c定时触发CTIMER3 以 2.048 kHz 时钟、ADC_CTIMER_COUNT 2048/512 - 1分频得到 512 Hz 采样率并开启am_hal_ctimer_adc_trigger_enable()让定时器直接触发 ADC见 adc.c中断采集ADC 中断中读取 FIFO按AM_HAL_ADC_FIFO_SLOT判断槽位每攒够 8 个采样点就通过消息队列adcbat_mq发送给应用层见 adc.c应用侧通过am_adc_data_get()阻塞接收rt_mq_recv等待时间RT_WAITING_FOREVER自动初始化通过INIT_BOARD_EXPORT(rt_hw_adc_init)在板级初始化阶段自动执行见 adc.c。I2C 主机驱动i2c.ci2c.c 基于 Ambiq 的 IOMI/O Master模块实现 RT-Thread I2C 总线设备多实例引脚定义了 I2C0GPIO5SCL/GPIO6SDA、I2C2GPIO27/GPIO25、I2C3GPIO42/GPIO43、I2C4GPIO39/GPIO40四组引脚映射见 i2c.c总线参数默认 I2C 模式、100 kHz 时钟AM_HAL_IOM_100KHZ写阈值 4、读阈值 60见 i2c.c传输接口rt_i2c_master_xfer遍历 RT-Thread 的rt_i2c_msg数组读操作调用am_hal_iom_i2c_read写操作调用am_hal_iom_i2c_write见 i2c.c从而接入 RT-Thread I2C 框架可配合 sensor 类驱动使用。LED 与 PIN 驱动led.cled.c 展示了如何用 RT-Thread PIN 设备驱动板上 LED板上 4 个 LED 分别位于 GPIO46/47/48/49rt_hw_led_on(0)拉低点亮、rt_hw_led_off(0)拉高熄灭低电平有效见 led.c通过INIT_DEVICE_EXPORT(rt_hw_led_init)在设备初始化阶段配置引脚为输出并默认熄灭见 led.c额外导出了 finsh 命令ledled 0 1点亮 LED0、led 0 0熄灭便于在 MSH 控制台下直接验证见 led.c。应用示例LED 闪烁线程applications/main.c 提供了一个最小可运行的应用模板在main()中动态初始化一个名为led的静态线程栈 512 字节优先级RT_THREAD_PRIORITY_MAX/3时间片 5线程入口以 0.5 秒为周期交替调用rt_hw_led_on(0)/rt_hw_led_off(0)期间通过rt_thread_delay(RT_TICK_PER_SECOND/2)让出 CPU见 main.c。若未启用 finsh则同时通过rt_kprintf打印计数值便于在无控制台环境下观察运行状态。这段示例同时演示了两个要点一是空闲钩子会在该线程阻塞期间被触发从而自动进入 Apollo2 深度休眠二是建议把真实业务线程建立在main之前完成的初始化之上避免在组件初始化未完成时访问外设。在 Apollo2 上继续深入本文介绍的内容对应仓库中的以下路径读者可按需深入BSP 根目录与文档bsp/apollo2/README.md板级初始化与低功耗bsp/apollo2/board/board.c、bsp/apollo2/board/board.h外设驱动bsp/apollo2/board/uart.c、bsp/apollo2/board/adc.c、bsp/apollo2/board/i2c.c、bsp/apollo2/board/led.c工程配置bsp/apollo2/Kconfig、bsp/apollo2/rtconfig.h、bsp/apollo2/rtconfig.pyAmbiq HAL 与寄存器层bsp/apollo2/libraries/drivers/hal、bsp/apollo2/libraries/drivers/regs启动文件Keil/GCC/IARbsp/apollo2/libraries/startup。如果需要将 Apollo2 用于电池供电的传感采集场景建议重点阅读adc.c的定时触发与消息队列设计以及board.c的深度休眠钩子——这两处是理解RT-Thread 调度 Apollo2 亚阈值功耗协同工作的最佳入口。【免费下载链接】rt-threadRT-Thread is an open source IoT Real-Time Operating System (RTOS). https://rt-thread.github.io/rt-thread/项目地址: https://gitcode.com/gh_mirrors/rt/rt-thread创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
