3. 工业以太网协议栈移植基础

在RA系列MCU上实现工业以太网通信,很少从零编写协议栈。工程上更常见的做法是:以Renesas FSP(Flexible Software Package)为底层硬件抽象与驱动基础,在其上集成第三方协议栈,如EtherCAT Slave Stack、PROFINET RT Stack或lwIP。FSP负责芯片外设、时钟、引脚、中断与RTOS适配,第三方协议栈负责协议状态机、报文处理与应用接口。移植的核心工作,就是让这两层在数据通路、时间基准、内存与任务调度上正确对接。

一、FSP与协议栈的分层关系

FSP本身不是协议栈,它提供的是HAL/BSP层能力:以太网MAC驱动(如RA的ETHERC/EDMAC)、PHY管理(MDIO)、DMA描述符、中断回调、Cache维护以及RTOS适配层。第三方协议栈通常自带网络接口层(NIC驱动适配层),移植时需要在FSP的以太网驱动与协议栈的NIC接口之间建立“胶水层”。这个胶水层一般包含四个动作:初始化MAC与PHY、注册收发回调、实现帧的发送与接收、处理链路状态变化。

以EtherCAT Slave Stack为例,其底层通常要求一个“ESC(EtherCAT Slave Controller)访问层”。RA芯片若使用外置ESC(如LAN9252、ET1100),则FSP侧主要提供SPI/并行总线驱动与中断;若使用内置ESC的RA型号,则FSP提供ESC寄存器访问与PDI接口。PROFINET RT Stack则更依赖标准以太网MAC,通常要求支持VLAN优先级、组播过滤与精确的发送时间戳。lwIP作为轻量TCP/IP栈,移植重点是ethernetif.c中的low_level_output()与low_level_input(),以及sys_arch.c中的信号量、邮箱与线程封装。

FSP + 第三方协议栈 分层集成结构 应用层 / 用户任务 EtherCAT 过程数据映射 · PROFINET IO 数据 · lwIP Socket / HTTP / Modbus TCP 第三方协议栈 EtherCAT Slave Stack 状态机 · 邮箱 · PDO · DC PROFINET RT Stack RT帧 · 组播 · 看门狗 lwIP TCP/UDP · IP · ARP · ICMP 移植胶水层(NIC / ESC 适配) low_level_output / low_level_input · ESC 寄存器读写 · 中断注册 · 链路状态回调 · Cache 维护 sys_arch 信号量 / 邮箱 / 线程封装 · 时间戳获取 Renesas FSP(HAL / BSP / RTOS 适配) ETHERC / EDMAC PHY / MDIO DMAC / DTC FreeRTOS / ThreadX 适配 RA MCU 硬件:Cortex-M33/M4 · 以太网MAC · ESC(内置或外置)· PHY

二、RTOS适配:FreeRTOS与ThreadX的差异点

FSP的RTOS适配层(rm_freertos_port或rm_threadx_port)已经封装了互斥量、信号量、事件组与线程创建。移植第三方协议栈时,真正需要关注的是协议栈自身的OS抽象层。以lwIP为例,它通过sys_arch.c定义了一套OS接口:sys_sem_new、sys_mutex_new、sys_mbox_new、sys_thread_new、sys_now。在FreeRTOS下,这些分别映射到xSemaphoreCreateBinary、xSemaphoreCreateMutex、xQueueCreate、xTaskCreate和xTaskGetTickCount;在ThreadX下则映射到tx_semaphore_create、tx_mutex_create、tx_queue_create、tx_thread_create和tx_time_get。

一个容易出错的点是sys_now()的时基。lwIP用它计算TCP重传超时与ARP老化。若FreeRTOS的configTICK_RATE_HZ设为1000,则sys_now返回毫秒;若设为100,则必须乘以10换算。ThreadX的tx_time_get返回的是tick数,同样需要按TX_TIMER_TICKS_PER_SECOND换算。时基不一致会导致TCP连接在高负载下频繁超时,而现象往往表现为“能ping通但传大文件断流”。

三、内存与任务划分

工业以太网协议栈对内存的要求集中在三处:报文缓冲区(PBUF/Frame Buffer)、协议控制块(PCB/状态机实例)和DMA描述符。RA的以太网驱动通常使用固定数量的发送与接收描述符,例如发送8个、接收16个,每个描述符指向一个约1536字节的缓冲区。若协议栈再申请一份PBUF,则同一帧会被拷贝两次。优化方向是让协议栈直接使用驱动提供的缓冲区,或使用零拷贝接口(如lwIP的pbuf_alloced_custom)。

任务划分上,建议至少分出三个优先级层次:最高优先级给周期性过程数据任务(EtherCAT的PDO周期任务或PROFINET的RT发送任务),周期通常为1ms或更短;中优先级给协议栈主循环或TCP/IP线程;低优先级给应用逻辑与诊断。以FreeRTOS为例,可设置过程数据任务优先级为configMAX_PRIORITIES-2,lwIP的tcpip_thread为configMAX_PRIORITIES-3,应用任务为2。中断优先级方面,以太网接收中断应高于configMAX_SYSCALL_INTERRUPT_PRIORITY,但发送完成中断可适当降低,避免频繁打断过程数据任务。

四、时间同步基础

EtherCAT使用分布式时钟(DC),PROFINET使用PTCP或IEEE 1588。无论哪种,底层都需要一个高精度时间戳。RA的ETHERC/EDMAC在接收和发送时可产生时间戳,通常来自PTP计时器或系统计数器。移植时要确认三件事:时间戳的捕获点是在MII接口还是MAC内部;时间戳的单位与回绕周期;以及如何把时间戳传递给协议栈。以EtherCAT DC为例,从站需要根据主站发送的ARMW/FRMW报文调整本地系统时间偏移,使各从站时钟与参考时钟对齐。若时间戳抖动超过1μs,DC同步误差会明显增大,表现为过程数据抖动或同步丢失。

移植检查顺序建议:先让FSP以太网驱动能收发原始帧(可用回环或抓包验证),再接入协议栈的NIC层,最后处理RTOS时基与时间戳。跳过第一步直接调协议栈,往往会把驱动问题误判为协议栈问题。

五、一个可参考的移植参数示例

以下参数为教学示例,用于说明各层需要对齐的配置项,并非实测结果。假设使用RA6M3 + FreeRTOS + lwIP,以太网MAC时钟25MHz,PHY为KSZ8081,系统主频200MHz。

配置项示例值说明
发送描述符数8对应8个1536字节缓冲区
接收描述符数16接收侧留更多余量
FreeRTOS tick1000Hzsys_now直接返回毫秒
lwIP线程优先级configMAX_PRIORITIES-3低于过程数据任务
PBUF_POOL_SIZE16与接收描述符匹配
MEM_SIZE16KBlwIP堆,按应用调整
时间戳源PTP计时器需确认捕获点与单位

移植完成后,判断是否成功不能只看“能通信”。建议依次验证:原始帧收发是否正常;协议栈能否完成一次完整的状态机转换(如EtherCAT从INIT到OP);过程数据周期是否稳定;时间同步误差是否在协议允许范围内。只有这四项都通过,才能认为FSP与第三方协议栈的集成是可靠的。