这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » DIY与开源设计 » 电子DIY » 【瑞萨RA8D1测评】RA8D1+lwIP网络验证与TCPOTA的实验记录

共1条 1/1 1 跳转至页

【瑞萨RA8D1测评】RA8D1+lwIP网络验证与TCPOTA的实验记录

菜鸟
2026-10-19 10:48:51     打赏

大家好,记录一下最近在 CPKCOR-RA8D1B 核心板 + CPKEXP-EKRA8X1 扩展板上移植 FreeRTOS + lwIP,并尝试 OTA 升级的过程。

目前的结论先放在前面:lwIP 的 HTTP、TCP Echo、UDP Echo、MQTT 已经在开发板上实测通过;OTA 的 PC 工具、固件包、设备端 Server 和 Bootloader 已完成第一版构建及本地模拟测试,但真实开发板上的完整 OTA 升级尚未成功验证。调试中我发现过 Bootloader 和应用链接地址冲突,已经修改了程序地址,但仍不成功 不知道什么原因借助ai也没有解决,第一次开发瑞萨mcu经验不足 希望和大家交流一下经验。下面我介绍一下配置和跑通的测试。

1. 硬件与软件环境
- 核心板:CPKCOR-RA8D1B,MCU:RA8D1 / R7FA8D1BHECBD- 扩展板:CPKEXP-EKRA8X1- IDE:e² studio- FSP:6.3.0- 编译器:LLVM for ARM 21.1.1- RTOS:FreeRTOS- 网络栈:lwIP

- 开发板静态 IP:192.168.1.12

下面还开发板连接和实物图片:

 核心板上已经集成了以太网 MAC 控制器,完整的底层硬件链路还需要以太网PHY、隔离变压器、RJ45接口。CPKEXP-EKRA8x1 扩展板提供了外部硬件,我们直接接线即可 需要注意的是以太网phy和摄像头冲突 这两个不能同时使用 我们这里不使用摄像头 不用管

 2. lwIP 工程配置与初始化

工程通过 FSP 配置 Ethernet、PHY 和 Renesas lwIP Ethernet netif,生成 g_ether0、PHY 和 g_lwip_ether0_instance等实例。应用使用 FreeRTOS 端口,lwIP 的 TCP/IP 核心线程由 tcpip_init()创建。这里我先不赘述 大家可以看一下【瑞萨RA8D1 LVGL/LWIP评测】RA8D1部署FreeRTOS+LWIP-电子产品世界论坛大佬的帖子来 移植lwip

2.1 静态 IP 配置
当前 lwipopts.h虽启用了 DHCP 支持,但应用入口没有调用 dhcp_start(),所以实际使用的是静态地址。核心代码来自 
src/lwip_thread_entry.c:
void LwIP_Init(void)
{
    tcpip_init(NULL, NULL);

    IP4_ADDR(&ipaddr, 192, 168, 1, 12);
    IP4_ADDR(&gw, 192, 168, 1, 1);
    IP4_ADDR(&netmask, 255, 255, 255, 0);

    netif_add(&gnetif, &ipaddr, &netmask, &gw,
              &g_lwip_ether0_instance,
              &rm_lwip_ether_init,
              &tcpip_input);

    netif_set_default(&gnetif);
    netif_set_up(&gnetif);
    netif_set_link_up(&gnetif);
    netif_set_link_callback(&gnetif, ethernet_link_status_updated);
}

网络接口在启用之后在运行各项服务

LwIP_Init();

udp_echo_server_init();   /* UDP Echo :7 */
tcp_echo_server_init();   /* TCP Echo :5001 */
httpd_init();             /* HTTP      :80 */
mqtt_client_init();       /* MQTT      :1883 */
ota_tcp_server_init();    /* OTA TCP   :5002 */

3. lwIP 功能验证过程

 3.1 HTTP 页面

先在 PC 浏览器访问 http://192.168.1.12/。页面能正常加载后,说明以太网链路、静态地址和 lwIP httpd 服务已连通。

如下图:

lwip_http_browser.png

3.2 TCP Echo
TCP Echo Server 监听 5001端口。PC 使用 VOFA+ 选择 TCP 客户端模式,连接 192.168.1.12:5001,发送 hello tcp;开发板将收到的数据原样回传。RTT 中能看到客户端地址和接收长度,VOFA+ 中能看到回显。


服务端关键代码来自 src/tcp_echo_server_thread.c:
connected = accept(sock, (struct sockaddr *)&client_addr, &sin_size);

while (1)
{
    recv_data_len = recv(connected, recv_data, RECV_DATA, 0);
    if (recv_data_len <= 0)
        break;

    write(connected, recv_data, (size_t)recv_data_len);
}
 3.3 UDP Echo

UDP Echo Server 监听端口 7。VOFA+ 选择 UDP 客户端模式,将远端 IP 设为 192.168.1.12、远端端口设为 7,发送数据后可以看到开发板回传。

int n = lwip_recvfrom(sock, recv_buf, RECV_BUF_SIZE, 0,
                      (struct sockaddr *)&client_addr, &addr_len);

if (n > 0)
{
    lwip_sendto(sock, recv_buf, (size_t)n, 0,
                (struct sockaddr *)&client_addr, addr_len);
}

lwip_udp_client.png

3.4 MQTT 发布

PC 运行 Mosquitto Broker,地址 192.168.1.10:1883。开发板连接后周期性向 /test主题发布 Hello Renesas! cnt:n,MQTTX 能持续收到消息。

#define PORT  1883
#define TOPIC "/test"

IP4_ADDR(&host_ip, 192, 168, 1, 10);
mqtt_client_connect(client, &host_ip, PORT,
                    mqtt_connection_cb, NULL, &ci);

snprintf(payload, sizeof(payload), "Hello Renesas! cnt:%d", i);
mqtt_publish(client, TOPIC, payload, (u16_t)strlen(payload),
             qos, retain, mqtt_pub_request_cb, NULL);

lwip_mqtt_publish.png

阶段结论:HTTP、TCP、UDP、MQTT 均有开发板实测截图和 RTT 输出。至此基础的网络功能已经验证完成。


4. OTA 架构探索
参考了基于 GD32 与 LwIP 的 TCP OTA 固件升级实现 - 技术栈,借鉴设备 TCP Server、PC TCP Client、分帧发送和逐帧 ACK 的思路。没有照搬文章中的 GD32 Flash/FatFs 处理,而是复用 RA8D1 工程中已有的 OSPI W25Q128 驱动、包格式及 新建了一个LED 工程里面的 Bootloader 。
```text
PC 图形上位机
  ├─ 读取 lwip_rtos.elf
  ├─ 提取应用 Flash 段并生成 BIN
  ├─ 封装、校验 R8OT OTA 包
  └─ TCP 连接 192.168.1.12:5002,分块发送
                         │
                         ▼
RA8D1 lwIP OTA Server
  ├─ START / DATA / END 状态机,逐帧 ACK
  ├─ 写入 W25Q128 OSPI 暂存区
  └─ 校验整包 CRC 和镜像信息,写 metadata 后复位
                         │
                         ▼
Bootloader
  ├─ 检查 OSPI metadata 和镜像 CRC
  ├─ 安装到片内应用区
  └─ 校验向量表并跳转
```

当前分区规划:

| 镜像/区域 | 地址 | 用途 |
|---|---:|---|
| LED Bootloader | 片内 Flash `0x02000000` 起始,128 KB | 检查升级、安装应用、启动应用 |
| lwip_rtos 应用 | 片内 Flash `0x02020000` 起始 | 正常运行的网络应用 |
| OTA 暂存区 | OSPI 偏移 `0x00100000` 起始 | 保存完整 `.ota` 包 |

4.1 OTA 帧格式
帧采用小端序:
| 命令 | 帧内容 | 含义 |
|---|---|---|
| START `0x01` | `cmd:u8 + package_size:u32 + name_len:u8 + name` | 开始升级 |
| DATA `0x02` | `cmd:u8 + data_len:u16 + data` | 发送数据块 |
| END `0x03` | `cmd:u8 + package_crc32:u32` | 完成并校验 |
| ACK `0x79` | 单字节 | 当前帧接受 |
| NACK `0x1F` | 单字节 | 当前帧拒绝 |

4.2 TCP 半包/粘包处理

TCP 是字节流,不能假定一次 `netconn_recv()` 就是一帧。`ota_stream_read()` 按协议要求的长度从 netbuf 拼接数据,并保留当前 buf 的读取偏移。
static bool ota_stream_read(struct netconn *conn,
                            ota_stream_t *stream,
                            uint8_t *dest,
                            uint16_t len)
{
    uint16_t copied = 0U;

    while (copied < len)
    {
        if (stream->p_buf == NULL)
        {
            if (netconn_recv(conn, &stream->p_buf) != ERR_OK)
                return false;
            stream->offset = 0U;
        }

        u16_t total = netbuf_len(stream->p_buf);
        u16_t available = (u16_t)(total - stream->offset);
        u16_t requested = (u16_t)(len - copied);
        u16_t wanted = (available < requested) ? available : requested;
        u16_t actual = netbuf_copy_partial(stream->p_buf,
                                           &dest[copied], wanted,
                                           stream->offset);
        if (actual == 0U)
            return false;

        copied = (uint16_t)(copied + actual);
        stream->offset = (u16_t)(stream->offset + actual);
        if (stream->offset >= total)
        {
            netbuf_delete(stream->p_buf);
            stream->p_buf = NULL;
            stream->offset = 0U;
        }
    }
    return true;
}

4.3 DATA 写入与 END 校验
设备收到 DATA 后检查包大小边界,顺序写入 OSPI 暂存区,累计传输 CRC32,并在每块写入成功后回复 ACK:
if ((length == 0U) ||
    (length > session.package_size - session.received_size) ||
    !ota_stream_read(conn, &stream, data, length) ||
    !external_flash_write(session.flash_offset, data, length))
{
    ota_send_byte(conn, OTA_NACK);
    break;
}

session.crc = ota_crc32_update(session.crc, data, length);
session.received_size += length;
session.flash_offset += length;
ota_send_byte(conn, OTA_ACK);

5. Bootloader 调试过程与地址冲突
第一次在 e² studio 调试 LED.elf 后,程序没有进入应用,而是停在 startup.c 的 Default_Handler()。当时的调用栈显示 Bootloader 经过 application_vector_is_valid() 和 boot_to_existing_application(),随后异常跳转。

bootloader_default_handler.png


随后检查两个工程的 map 文件,发现应用 lwip_rtos.elf`当时仍从 0x02000000链接,而该区域正是 Bootloader 所在地址。也就是说 Bootloader 和应用的向量表发生了重叠,Bootloader 读取到的应用向量并不是有效应用入口。
排查过程还发现两处工程配置问题:
1. e² studio 重新生成时,Debug/memory_regions.lld 被恢复为默认 Flash 起点 0x02000000,此前的应用分区改动没有可靠地保存在工程 linker 输入中。2. lwip_rtos Debug_Flat.launch中的 image/symbol 配置曾指向另一台电脑的绝对路径,可能加载了错误 ELF。后来将 script/memory_regions.lld固定为工程控制的 linker 输入,并让script/fsp.lld明确引用该文件;Debug launch 的镜像和符号路径改为当前工程 Debug/lwip_rtos.elf。修复后的 map 显示:
FLASH_START = 0x02020000
FLASH_LENGTH = 0x001d8000
__flash_vectors$$ = 0x02020000

这是静态链接证据,说明当前 ELF 的向量表地址与 Bootloader 约定一致。

 6. 验证结果
已完成
- HTTP 页面、TCP Echo、UDP Echo 和 MQTT 已在开发板上实测通过,并有上面的截图/RTT 记录。- OTA Server、上位机客户端及 Bootloader 本地构建通过。- 应用与 Bootloader 分区已在 map 中检查,应用向量表从 `0x02020000` 开始。- 当前 ELF 已提取为 BIN、封装为 `.ota`,本地包校验返回 `verify=ok`。- PC 客户端与本地模拟 TCP 设备完成 START/DATA/END、逐帧 ACK、CRC 和数据一致性测试。
尚未完成
- 开发板上的完整 OTA 下载、Bootloader 安装、重启后新应用启动尚未跑通。- lwIP 当前未启用 netconn 接收超时;客户端断开后依赖 TCP 连接关闭检测结束会话。- 暂不支持断点续传、TLS、数字签名、版本防回退、A/B 分区和掉电自动回滚。- Bootloader 擦写单一应用区期间掉电,当前不能保证自动恢复旧固件;现阶段仅适用于开发验证。
7. 后续调试计划
1. 确认烧录的 Bootloader 是当前 `LED.elf`,并确认应用使用修正分区后的 `lwip_rtos.elf`。2. 烧录应用时不要选择全片擦除,避免同时擦掉 Bootloader。3. 通过 RTT 确认 Bootloader 能跳转,应用启动后能看到 `[OTA TCP] listen=5002`。4. 在上位机 GUI 中选择当前 ELF,生成 OTA 包并连接 `192.168.1.12:5002`。5. 对照 RTT 检查传输 CRC、Bootloader 安装结果和跳转日志。6. OTA 成功后重新回归 Ping、TCP、UDP、HTTP、MQTT。
总结:本次已完成 lwIP 基础网络功能的实板验证,也完成 OTA 软件框架、固件包生成、Bootloader/app 分区修复和本地协议模拟测试。当前最大未完成项仍是开发板上的 OTA 安装闭环;分区冲突的失败现象、排查过程和静态修复证据已记录,后续需要用最新 ELF 重新进行硬件验证。

参考方案:基于 GD32 与 LwIP 的 TCP OTA 固件升级实现 - 技术栈

感谢@枫雪天大佬的文章【瑞萨RA8D1 LVGL/LWIP评测】RA8D1部署FreeRTOS+LWIP-电子产品世界论坛移植教程

第一次开发瑞萨mcu经验不足 希望和大家交流一下 我的不足希望大家指正一下还有哪里存在问题 我会继续改正的 共同学习一起进步 谢谢大家!






关键词: CPKCOR-RA8D1评测     RA8D1     网络     验    

共1条 1/1 1 跳转至页

回复

匿名不能发帖!请先 [ 登陆 注册 ]