物联网嵌入式操作系统实时系统【免费下载链接】RIOTRIOT - The friendly OS for IoT项目地址https://gitcode.com/GitHub_Trending/riot/RIOT点击查看免费下载本指南深入讲解 RIOT OS 测试应用tests/periph/uart_locate_pins源码位于 tests/periph/uart_locate_pins它通过软件 UARTsoft_uart模块在每一个 GPIO 引脚上以 9600 Bd 的符号率逐位发送该引脚自身的名字从而帮助开发者在没有板卡原理图或引脚标注不明时仅凭一个 UART 适配器逐脚探测即可确认 GPIO 编号。读完本文你将掌握该工具的工作原理、消息编码格式、构建与使用步骤以及如何定制引脚探测列表、修改波特率并从源码层面理解软件 UART 的位时序实现。这个工具解决什么问题在实际嵌入式开发中经常遇到以下场景拿到了没有原理图、或丝印不清的评估板无法确认某个物理引脚对应的GPIO_PIN(port, pin)编号芯片的硬件 UART 引脚被复用、或者硬件 UART 资源不足想临时用任意 GPIO 输出调试信息需要确认某个引脚是否可用作输出例如确认其没有被连接到晶体、复位电路等特殊外设。uart_locate_pins正是为这种盲探引脚场景设计的它在每个 GPIO 上通过软件模拟的 UART 反复发送一行文本文本内容就是当前引脚的名字。只要把 UART 适配器依次接到各个引脚上从串口终端读到的内容就能立刻告诉你你现在接的是哪个引脚。工作原理软件 UART 逐引脚广播引脚名该应用的思路非常直接见 main.c维护一个待探测引脚的列表pins[]数组循环遍历该列表对每个引脚调用soft_uart_init()初始化软件 UART构造一行包含引脚编号与引脚字母名的文本用soft_uart_write()把该文本逐位bit-bang发送出去发送完成后调用soft_uart_poweroff()关闭 UART再继续下一个引脚如此无限循环。它没有使用芯片的硬件 UART 外设而是完全依靠soft_uart驱动——一个纯软件实现的 UART由通用定时器timer 普通 GPIO 配合产生串口波形因此任何支持periph/gpio与periph/timer的 RIOT 板卡都可以运行不依赖硬件 UART 引脚。根据 drivers/include/soft_uart.h 的说明该模块正是用于硬件 UART 不可用的场合需要注意的是当前实现收发不能同时进行因此本工具只使用发送方向TX。引脚消息的编码格式main.c中发送的每行消息由两段组成对应fmt模块的格式化函数见 main.cPport.pin / P字母pin\n其中Pport.pin以数字形式给出端口号与引脚号例如P0.0表示 port 0、pin 0P字母pin以字母形式给出端口A port_num与引脚号例如PA0即 GPIO A 的第 0 脚行尾是\n换行符便于串口终端逐行显示。两种表示法同时输出方便与芯片数据手册中的命名如PA0以及 RIOT 的GPIO_PIN(0, 0)写法互相印证。消息通过fmt_u16_dec()把无符号整数转成十进制字符串再逐字节送入soft_uart_write()整个过程不依赖printf和 stdio——这正是该测试在 Makefile 中引入stdio_null模块的原因见下文。源码剖析从引脚表到发送循环1. 待探测引脚列表所有被探测的引脚集中定义在main.c顶部的静态数组main.cstatic const struct { uint8_t port_num; uint8_t pin_num; } pins[] { { .port_num 0, .pin_num 0, }, };源码注释main.c特别提醒请根据实际需要调整这个列表不一定要包含所有引脚——例如连接到外部晶体的引脚被强制驱动为输出时可能表现异常应当从列表中排除。默认模板只探测P0.0PA0实际使用前需要把它展开成目标芯片的全部 GPIO。2. 软件 UART 配置应用为唯一的软件 UART 实例定义了配置main.csoft_uart_conf_t soft_uart_config[] { { .tx_pin GPIO_UNDEF, .rx_pin GPIO_UNDEF, .tx_timer TIMER_DEV(0), .timer_freq MHZ(1), }, };tx_pin/rx_pin初始为GPIO_UNDEF因为发送引脚会在主循环里被动态切换为当前探测的引脚tx_timer使用定时器 0TIMER_DEV(0)timer_freq MHZ(1)即定时器以 1 MHz 工作。该值必须能被波特率整除才有良好的时序精度soft_uart驱动对此有专门的校验见下文底层实现一节。需要说明的是这个配置文件覆盖了soft_uart模块自带的默认配置。驱动默认参数位于 drivers/soft_uart/include/soft_uart_params.h默认rx_pin/tx_pin均为GPIO_UNDEF、RX 定时器为 timer 0、TX 定时器为 timer 1、频率MHZ(1)、标志为 0。而本应用通过自定义的 include/soft_uart_params.h 重定义了soft_uart_config数组extern声明并固定SOFT_UART_NUMOF为 1正如其文件头注释所说这是为了在每次切换引脚配置时节省内存、避免使用驱动默认的静态参数数组。3. 主循环切换引脚 → 初始化 → 发送 → 关闭主循环main.c核心逻辑如下while (1) { for (unsigned i 0; i ARRAY_SIZE(pins); i) { gpio_t pin GPIO_PIN(pins[i].port_num, pins[i].pin_num); soft_uart_config[0].tx_pin pin; soft_uart_init(0, UART_SYMBOL_RATE, NULL, NULL); /* ...构造 P0.0 / PA0\n 消息... */ soft_uart_write(0, (void *)buf, (size_t)pos - (size_t)buf); soft_uart_poweroff(0); } }关键点GPIO_PIN(port, pin)把 (端口号, 引脚号) 组合成 RIOT 的gpio_t句柄soft_uart_init(0, UART_SYMBOL_RATE, NULL, NULL)传入NULL回调表示只初始化TX 发送模式见 drivers/include/soft_uart.h 的说明soft_uart_write()是阻塞发送——它会等到全部字节发送完毕才返回drivers/include/soft_uart.h保证当前引脚发完消息后才切换到下一个发送完毕调用soft_uart_poweroff()把该引脚释放接着探测下一个引脚外层while(1)让整个扫描无限循环因此你可以在任意时刻接入 UART 适配器等待当前周期轮询到该引脚即可收到消息。4. 波特率可配置波特率通过编译期宏UART_SYMBOL_RATE提供默认 9600main.c#ifndef UART_SYMBOL_RATE # define UART_SYMBOL_RATE 9600 #endif也就是说即使不修改源码也可以用CFLAGS -DUART_SYMBOL_RATE...或make CFLAGS-DUART_SYMBOL_RATE115200调整符号率。9600 Bd 是 UART 适配器与串口工具最通用的默认档位绝大多数 USB-TTL 转换器无需额外配置即可使用。构建与运行Makefile 要点应用的构建配置位于 Makefile值得注意的有几点BOARD ? nucleo-f767zi # 让本应用的 soft_uart_params.h 优先于驱动自带的版本被找到 INCLUDES -I$(abspath $(CURDIR))/include include ../Makefile.periph_common USEMODULE soft_uart USEMODULE fmt # 不需要 stdio USEMODULE stdio_null # 本应用不需要多线程 DISBALE_MODULE core_thread默认板卡为nucleo-f767ziNucleo-144 上的 STM32F767ZI可通过BOARD...覆盖头文件路径注入INCLUDES -I.../include保证链接器优先找到本应用自定义的 soft_uart_params.h而不是驱动目录下的默认版本Makefile 注释明确说明了这一目的模块选择启用soft_uart与fmt轻量整数格式化并通过stdio_null关闭标准输出——因为本应用不需要 stdio裁剪内核DISBALE_MODULE core_thread移除了多线程支持进一步减小镜像体积注意此处是 Makefile 中实际的拼写RIOT 的模块裁剪机制会据此跳过对应模块同时继承 tests/periph/Makefile.periph_common 与 tests/Makefile.tests_common后者默认BOARD ? native、默认开启DEVELHELP并给自动化测试注入交互同步与栈使用统计模块。编译、烧录与使用步骤在 RIOT 仓库根目录下按以下步骤操作# 1. 进入测试目录 cd tests/periph/uart_locate_pins # 2. 编译默认板卡 nucleo-f767zi也可显式指定其他板卡 make BOARDnucleo-f767zi # 3. 烧录到目标板 make BOARDnucleo-f767zi flash # 4. 打开串口终端波特率 96008N1 # 例如minicom -D /dev/ttyUSB0 -b 9600然后把 USB-TTL UART 适配器的RX引脚连接到目标板上的任意一个 GPIO适配器的GND必须与目标板共地观察串口终端输出例如收到P0.0 / PA0就说明当前接的正是PA0依次把适配器换到其他引脚逐一记录每个引脚对应的编号若某引脚始终无输出则该引脚可能是特殊用途引脚如晶体/复位/电源或已被从pins[]列表中排除。每次换脚无需重新烧录——应用会无限循环轮询整个引脚表。软件 UART 底层原理位时序如何生成要理解为什么这个工具能在任意 GPIO 上模拟出 9600 Bd 的串口需要深入soft_uart驱动的实现drivers/soft_uart/soft_uart.c。波特率到定时器节拍的换算初始化时驱动根据配置的定时器频率计算每一位对应的定时器 tick 数soft_uart.cctx-bit_time (cfg-timer_freq baudrate / 2) / baudrate; unsigned accuracy (100 * cfg-timer_freq / ctx-bit_time) / baudrate; if (accuracy 110 || accuracy 90) { return UART_NOBAUD; }bit_time 每个数据位的定时器计数个数四舍五入取整驱动还校验换算精度若(100 * timer_freq / bit_time) / baudrate落在 90%110% 区间之外则直接返回UART_NOBAUD拒绝该波特率。这正是配置里要求timer_freq取MHZ(1)1 MHz的原因——1 MHz 对 9600 属于整除关系1,000,000 / 9600 ≈ 104.17 tick/位精度足够通过校验。发送定时器中断驱动逐位翻转 GPIO发送一字节的逻辑在soft_uart_write_byte()soft_uart.c与定时器回调_tx_timer_cb()soft_uart.c中把待发字节左移 1 位空出的最低位作为起始位低电平按 8 数据位 1 停止位的帧结构把 8 个数据位和停止位拼进byte_tx用timer_set_periodic()让定时器以bit_time为周期周期性触发中断每次定时器回调把byte_tx的最低位写进gpio_write(cfg-tx_pin, ...)然后右移一位直到整帧发完清定时器并释放同步信号量soft_uart_write()soft_uart.c在持有互斥锁的前提下逐字节调用上述过程实现整条消息的阻塞发送。因此每个引脚的bit-bang本质上是GPIO 被配置为普通推挽输出由定时器中断在每个位时刻精确翻转电平从而在引脚上产生标准的 UART 帧波形。这也解释了为什么soft_uart_config里必须指定一个可用的硬件定时器以及为什么tx_timer/timer_freq的选取直接决定能否在目标波特率下稳定工作。与periph/uart的接口一致性从 drivers/include/soft_uart.h 可以看到soft_uart_init、soft_uart_mode、soft_uart_write、soft_uart_poweron/poweroff的签名刻意与periph/uart保持一致并复用uart_rx_cb_t等类型。这意味着soft_uart可以作为硬件 UART 的即插即用替代品本测试应用正是利用了这一设计把任意 GPIO临时变成串口 TX。定制指南根据你的目标板通常需要改动三处定制项位置说明探测引脚列表main.c 的pins[]展开为芯片全部或目标GPIO 的 (port, pin) 对剔除晶体等特殊引脚符号率main.c 的UART_SYMBOL_RATE或编译期-DUART_SYMBOL_RATE...默认 9600改大需同步调整串口终端设置并注意soft_uart的精度校验软件 UART 定时器/频率main.c 的soft_uart_config[]更换tx_timer、timer_freq频率应为波特率的倍数此外include/soft_uart_params.h 通过SOFT_UART_NUMOF 1固定实例数量、以extern复用main.c中可变的配置数组这一模式在你想把本应用改造成动态引脚输出调试口时同样可以复用。总结tests/periph/uart_locate_pins是 RIOT 生态中一个非常实用的小工具它把soft_uart驱动的任意 GPIO 可变身为串口 TX能力发挥到极致用逐引脚 bit-bang 引脚名的方式把未知板卡的引脚映射问题转化为一根 UART 适配器 一个串口终端就能解决的简单探测过程。其核心价值在于零硬件 UART 依赖完全基于软件 UART任何支持 timer GPIO 的板卡可用消息自解释同时输出P0.0与PA0两种格式方便对照数据手册即改即用通过pins[]数组、UART_SYMBOL_RATE宏与自定义soft_uart_config[]即可适配任意目标板。如果你正在为一款引脚标注不明的开发板编写板级支持或者想快速确认某颗新芯片的 GPIO 编号这个工具可以让你在几分钟内拿到完整的引脚对照表。赞分享物联网嵌入式操作系统实时系统【免费下载链接】RIOTRIOT - The friendly OS for IoT项目地址https://gitcode.com/GitHub_Trending/riot/RIOT点击查看免费下载相关推荐安全找回比特币钱包btcrecover离线模式与数据提取脚本详解安全找回比特币钱包btcrecover离线模式与数据提取脚本详解 比特币钱包密码或助记词遗忘是加密货币用户常见的痛点而 btcrecover 作为一款开源的应用安全区块链CLIRIOT OS 在 STM32L496G-DISCO 开发板上的外设支持与引脚映射全解析RIOT OS 在 STM32L496G DISCO 开发板上的外设支持与引脚映射全解析 导读 本文以 RIOT 操作系统中 stm32l496g disco物联网嵌入式操作系统实时系统RIOT OS 中的 Adafruit Feather M0 板级支持从引脚映射到 WiFi/LoRa 无线实战RIOT OS 中的 Adafruit Feather M0 板级支持从引脚映射到 WiFi/LoRa 无线实战 Adafruit Feather M0 是物联网嵌入式操作系统实时系统上一篇Open NSynth Super多GPU加速如何高效生成音频嵌入下一篇如何在macOS上快速安装Brooklyn屏幕保护程序终极指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
