[RA4 & RA6] 适配Zephyr OS,快速驱动LED与串口

[复制链接]
17|2
NightfallBallad 发表于 2026-4-25 08:30 | 显示全部楼层 |阅读模式
硬件平台
项目
说明

MCUR7FA4M2AD3CFP (RA4M2, 100-pin LQFP)
内核ARM Cortex-M33, 100 MHz
Flash512 KB Code Flash + 8 KB Data Flash
SRAM128 KB
调试器板载 J-Link OB
时钟24 MHz 晶振 + 32.768 kHz 子时钟引脚分配
功能
引脚
备注

LED1P002 (Port0 Pin2)GPIO Output, Active High
LED2P404 (Port4 Pin4)GPIO Output, Active High
LED3P405 (Port4 Pin5)GPIO Output, Active High
UART TXP109 (TXD9)SCI9, 115200 8N1
UART RXP110 (RXD9)SCI9
I2C SDAP408SCI3
I2C SCLP409SCI3
SWDIOP108J-Link 调试
SWCLKP300J-Link 调试
重要: RA-Eco-RA4M2 的调试串口 UART 使用 SCI9(P109/P110),而非常见的 SCI0。确认方式:参考 FSP 例程 RA4M2PRINTF/ra_cfg.txt 中 g_uart0 的 Channel 配置为 9。

移植文件清单板级支持文件(位于 zephyr/boards/renesas/ra_eco_ra4m2/)
文件
作用

board.yml板子元信息,声明 SoC name = r7fa4m2ad3cfp
board.cmakeJ-Link / pyocd 烧录器配置
ra_eco_ra4m2.yaml板子规格(ram/flash/supported features)
ra_eco_ra4m2.dts设备树定义(LED/UART/I2C/GPIO/时钟等)
ra_eco_ra4m2-pinctrl.dtsi引脚复用定义(UART/I2C)
Kconfig.ra_eco_ra4m2板子 Kconfig,选择对应 SoC
Kconfig.defconfig板级默认配置(使能 GPIO/UART)应用文件(位于 app/ra_eco_ra4m2_hello/)
文件
作用

CMakeLists.txtZephyr 应用构建配置
prj.confKconfig 参数(CONFIG_GPIO, CONFIG_SERIAL 等)
src/main.c主程序:三色 LED 循环闪烁 + UART 日志输出
详细文件说明board.yml
声明板子名和所支持的 SoC:
board:  name: ra_eco_ra4m2  full_name: RA-Eco-RA4M2 (R7FA4M2AD3CFP)  vendor: ra-eco  socs:  - name: r7fa4m2ad3cfpboard.cmake
配置 J-Link 和 pyocd 两种烧录器:
board_runner_args(jlink "--device=R7FA4M2AD")board_runner_args(pyocd "--target=R7FA4M2AD")include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake)include(${ZEPHYR_BASE}/boards/common/pyocd.board.cmake)ra_eco_ra4m2.yamlidentifier: ra_eco_ra4m2name: RA-Eco-RA4M2type: mcuarch: armram: 128flash: 512toolchain:  - zephyr  - gnuarmembsupported:  - gpio  - uart  - usbd  - watchdog  - counter  - adc  - i2c  - spi  - rtcvendor: ra-ecora_eco_ra4m2.dts(设备树)
核心配置:
/model = "RA-Eco-RA4M2";compatible = "renesas,ra_eco_ra4m2", "renesas,ra4m2", "renesas,ra";chosen {    zephyr,console = &uart9;       /* SCI9 on P109/P110 */    zephyr,shell-uart = &uart9;};leds {    led1: gpios = <&ioport0 2 GPIO_ACTIVE_HIGH>;  /* P002 */    led2: gpios = <&ioport4 4 GPIO_ACTIVE_HIGH>;  /* P404 */    led3: gpios = <&ioport4 5 GPIO_ACTIVE_HIGH>;  /* P405 */};ra_eco_ra4m2-pinctrl.dtsi(引脚复用)&pinctrl {    sci9_uart_default: sci9_uart_default {        group1 {            /* TX=P109, RX=P110 */            psels = <RA_PSEL(RA_PSEL_SCI_1, 1, 9)>,                    <RA_PSEL(RA_PSEL_SCI_1, 1, 10)>;        };    };    sci3_i2c_default: sci3_i2c_default {        group1 {            /* SDA=P408, SCL=P409 */            psels = <RA_PSEL(RA_PSEL_I2C, 4, 8)>,                    <RA_PSEL(RA_PSEL_I2C, 4, 9)>;            drive-strength = "medium";        };    };};示例工程prj.confCONFIG_GPIO=yCONFIG_SERIAL=yCONFIG_UART_INTERRUPT_DRIVEN=yCONFIG_UART_CONSOLE=yCONFIG_CONSOLE=yCONFIG_PRINTK=yCONFIG_CLOCK_CONTROL=y
main.c
#include <zephyr/device.h>#include <zephyr/kernel.h>#include <zephyr/sys/printk.h>#include <zephyr/drivers/gpio.h>/* LED nodes from device tree aliases */#define LED0_NODE DT_ALIAS(led0)#define LED1_NODE DT_ALIAS(led1)#define LED2_NODE DT_ALIAS(led2)static const struct gpio_dt_spec led0 = GPIO_DT_SPEC_GET_OR(LED0_NODE, gpios, {0});static const struct gpio_dt_spec led1 = GPIO_DT_SPEC_GET_OR(LED1_NODE, gpios, {0});static const struct gpio_dt_spec led2 = GPIO_DT_SPEC_GET_OR(LED2_NODE, gpios, {0});int main(void){        int ret;        printk("\n");        printk("========================================\n");        printk("  RA-Eco-RA4M2 Hello World\n");        printk("  Zephyr RTOS on R7FA4M2AD3CFP\n");        printk("========================================\n");        /* Check and configure LED0 */        if (device_is_ready(led0.port)) {                ret = gpio_pin_configure_dt(&led0, GPIO_OUTPUT_INACTIVE);                if (ret == 0) {                        printk("LED0 (P405) ready\n");                }        }        /* Check and configure LED1 */        if (device_is_ready(led1.port)) {                ret = gpio_pin_configure_dt(&led1, GPIO_OUTPUT_INACTIVE);                if (ret == 0) {                        printk("LED1 (P404) ready\n");                }        }        /* Check and configure LED2 */        if (device_is_ready(led2.port)) {                ret = gpio_pin_configure_dt(&led2, GPIO_OUTPUT_INACTIVE);                if (ret == 0) {                        printk("LED2 (P002) ready\n");                }        }        printk("LED blink start - check UART @115200 8N1\n");        int i = 0;        while (1) {                /* LED0 on */                if (led0.port && device_is_ready(led0.port)) {                        gpio_pin_set_dt(&led0, 1);                }                /* LED1 off */                if (led1.port && device_is_ready(led1.port)) {                        gpio_pin_set_dt(&led1, 0);                }                /* LED2 off */                if (led2.port && device_is_ready(led2.port)) {                        gpio_pin_set_dt(&led2, 0);                }                printk("Tick %d: LED0=ON, LED1=OFF, LED2=OFF\n", i);                k_sleep(K_MSEC(500));                /* LED0 off */                if (led0.port && device_is_ready(led0.port)) {                        gpio_pin_set_dt(&led0, 0);                }                /* LED1 on */                if (led1.port && device_is_ready(led1.port)) {                        gpio_pin_set_dt(&led1, 1);                }                /* LED2 off */                if (led2.port && device_is_ready(led2.port)) {                        gpio_pin_set_dt(&led2, 0);                }                printk("Tick %d: LED0=OFF, LED1=ON, LED2=OFF\n", i);                k_sleep(K_MSEC(500));                /* LED0 off */                if (led0.port && device_is_ready(led0.port)) {                        gpio_pin_set_dt(&led0, 0);                }                /* LED1 off */                if (led1.port && device_is_ready(led1.port)) {                        gpio_pin_set_dt(&led1, 0);                }                /* LED2 on */                if (led2.port && device_is_ready(led2.port)) {                        gpio_pin_set_dt(&led2, 1);                }                printk("Tick %d: LED0=OFF, LED1=OFF, LED2=ON\n", i);                k_sleep(K_MSEC(500));                i++;        }        return 0;}
编译与烧录编译west build -b ra_eco_ra4m2 app/ra_eco_ra4m2_hello烧录(J-Link OB)west flash -r jlink查看串口输出
使用任意串口工具连接 P109 (TX),波特率 115200 8N1:

【总结】
使用zephyr开发,可以快速实现工程,可以告别复杂的fsp的安装、RASC的配置。

劫灰飞尽古今平 发表于 2026-4-26 19:48 | 显示全部楼层
主的 main.c 里用了 DT_ALIAS (led0) 来获取 LED 节点,很多新手移植的时候,只在 dts 里加了 leds 节点,忘了在 aliases 里把 led0、led1、led2 对应到实际的 LED 节点上,结果编译直接报错,说 DT_ALIAS 找不到节点。我当初就踩了这个坑,对着编译错误看了半天,才发现少了 aliases 的绑定,楼主的代码里用了这个宏,说明已经做好了完整的配置,新手照着改就行。
等我变优秀 发表于 2026-4-28 21:47 | 显示全部楼层
我当初从 STM32 转过来,想当然地以为串口默认用 SCI0,对着 Zephyr 的串口示例改了半天,串口工具里连个乱码都收不到,示波器抓引脚完全没波形,对着 RA4M2 的硬件手册翻了整整一天,才发现板载 J-Link OB 的虚拟串口接的是 P109/P110 对应的 SCI9,根本不是默认的 SCI0。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

7

主题

60

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部
0