1. 项目概述与MII_RT模块的核心价值在工业自动化、运动控制这些对时间要求严苛到微秒级的领域传统的基于Linux或RTOS的处理器架构常常会面临一个根本性的挑战操作系统调度、中断延迟以及内存访问的不确定性。当你需要确保一个以太网帧在精确的125微秒周期内被发送或者一个编码器信号必须在几个纳秒内被响应时通用处理器的“软实时”特性就显得力不从心了。这时像TI Sitara系列处理器中的PRU-ICSS可编程实时单元与工业通信子系统这样的硬实时协处理器就成了解决问题的关键。它不是跑操作系统的CPU而是一个独立的、确定性的200MHz微控制器能够直接操纵芯片的引脚和内部硬件模块实现真正的“零延迟”响应。今天我们要深入拆解的就是PRU-ICSS中负责以太网物理层数据吞吐的MII_RTMII实时接口模块。你可以把它想象成PRU与外部PHY芯片之间的一座专用、高效、可编程的数据桥梁。它的核心价值在于将原本需要CPU频繁中断处理的以太网数据包收发工作卸载到PRU这个“硬件加速器”上并通过一系列精巧的硬件队列FIFO和命令接口让PRU能够以周期精确的方式控制每一个字节的流入和流出。这对于实现EtherCAT、PROFINET IRT、EtherNet/IP CIP Sync等工业以太网协议至关重要因为这些协议不仅要求通信更要求通信的时间确定性。简单来说如果你想让你的嵌入式设备成为一个高性能的工业以太网从站或主站或者实现任何需要微秒级精度的网络数据交换那么理解并驾驭MII_RT模块就是你绕不开的必修课。它直接决定了你的数据通路是否高效、延迟是否可控、以及整个通信栈的实时性能上限。2. MII_RT模块整体架构与数据流解析要理解MII_RT我们得先看看它在一个典型的PRU-ICSS应用中是处于什么位置。整个数据通路可以概括为外部PHY芯片 - MII接口RX_DV, RX_DATA, TX_EN, TX_DATA - MII_RT模块 - PRU核心。MII_RT模块在其中扮演了交通枢纽和缓冲区的角色。2.1 核心组件三级FIFO缓冲体系MII_RT模块的数据缓冲并非一个简单的队列而是分为多级每一级都有其特定的职责共同确保了数据流的平滑和PRU处理的灵活性。根据技术手册我们主要关注以下几个关键FIFORX L1 FIFO (32字节)这是数据进入PRU-ICSS的第一站。它直接连接MII接收接口用于缓冲从PHY芯片源源不断送来的以太网帧数据。其32字节的深度通常可存储多个以太网字是为了吸收MII接口25MHz时钟每个时钟传输4位即半字节与PRU处理速度之间的微小波动防止数据溢出。当RX_DV信号有效时数据就被推入此FIFO。TX L1 FIFO (64字节)这是数据离开PRU-ICSS前的最后一个缓冲区连接MII发送接口。它的深度64字节比RX L1更大这背后有重要考量发送侧需要组装完整的帧包括前导码、帧起始定界符SFD、数据、帧校验序列FCS并且可能涉及PRU的实时修改或生成因此需要更大的缓冲空间来避免下溢即MII接口需要发送数据时缓冲区却空了。PRU或自动转发逻辑将待发送的数据写入此FIFO模块硬件会自动将其转换为MII信号流发送出去。RX L2 Buffer这是一个更接近PRU核心的缓冲区或“便签本”Scratch Pad。当使能时它可以作为RX L1 FIFO和PRU寄存器之间的二级缓存。更重要的是当不用于以太网数据接收时通过RXCFG0/1[RX_L2_ENABLE]配置它可以被PRU当作一块通用的32字节x2 Bank的共享内存来使用用于存储临时变量或中间计算结果这为协议处理提供了额外的灵活存储空间。2.2 核心接口R30与R31寄存器PRU核心与MII_RT模块的交互几乎全部通过两个特殊的寄存器完成R30和R31。这是PRU架构的精髓——内存映射的GPIO和事件接口。R31命令与状态接口这是一个多功能寄存器。在MII_RT的上下文中向R31的高16位bit 31:16写入特定值就是向硬件发送命令。例如写入TX_PUSH16命令就是告诉MII_RT模块“把我R30里的数据按照当前配置推送到TX L1 FIFO去”。而从R31的低16位bit 15:0读取则是获取来自RX L1 FIFO的数据。同时R31的某些位也反映了FIFO的状态如WORD_RDY字就绪标志。R30数据输出与掩码接口这个寄存器主要用于发送路径。PRU将待发送的数据写入R30的低16位。更强大的是其高16位可以配置为发送掩码TX Mask。在TX Mask模式下PRU可以实时地、按位选择是将自己生成的数据发送出去还是将刚从接收路径得到的数据经过可能的字节交换后转发出去。这为实现数据透传、实时修改或协议转换提供了硬件级的原子操作能力。2.3 核心数据通路模式MII_RT模块的数据流不是固定的可以通过配置寄存器主要是TXCFG0/1和RXCFG0/1来切换以适应不同的应用场景寄存器模式Register Mode这是最灵活、最常用的模式。PRU通过主动读取R31来获取接收数据通过向R30写入并发送R31命令来控制发送数据。PRU对每一个字节或字的处理都有完全的控制权可以实现复杂的协议解析和封装。自动转发模式Auto-Forward Mode当设置TXCFG0/1[TX_AUTO_SEQUENCE]时数据帧可以从RX L1 FIFO直接自动转发到TX L1 FIFO完全无需PRU干预。这种模式延迟极低适用于简单的网络交换或回环测试场景。但请注意在此模式下PRU无法对经过的数据进行任何处理。TX Mask模式这是寄存器模式下的一个高级特性。它允许PRU在发送数据时动态地混合来自接收路径的数据和PRU自身生成的数据。其操作由公式TXDATA (R30_data MASK) | (RXDATA ~MASK)定义。通过配置R30的高16位作为掩码PRU可以逐位决定数据来源实现诸如实时替换帧中特定字段如目标地址、状态字而无需先将整个帧读入PRU内存再写回极大地提升了效率和实时性。理解这三层FIFO、两个核心寄存器以及几种数据通路模式就掌握了MII_RT模块的静态骨架。接下来我们要看PRU如何通过“发号施令”来让这个骨架动起来。3. PRU R31命令接口的深度剖析与实战编程如果说MII_RT模块是硬件舞台那么R31命令接口就是PRU核心指挥这个舞台的“遥控器”。向R31[31:16]的特定位写入‘1’会产生一个单时钟脉冲的命令信号直接控制MII_RT内部的状态机。这些命令是精细控制数据流的关键。3.1 发送路径命令详解与配合时序发送命令主要用于构建和发出一个以太网帧。一个典型的帧发送流程需要按顺序触发一系列命令。我们假设PRU已经将要发送的数据准备在了某个内存区域并且已经配置好了TX Mask等参数。帧开始与数据推送 (TX_PUSH8/TX_PUSH16)作用将R30[15:0]寄存器中的数据可能经过Mask处理推入TX L1 FIFO。TX_PUSH8推送一个字节使用低8位TX_PUSH16推送两个字节。实战注意手册中特别强调如果数据没有被完全掩码即需要混合接收数据TX_PUSH命令必须先于对应的TX_POP命令发生。这是因为硬件需要先锁定发送数据的来源。在编时通常的序列是设置R30数据和掩码 - 执行TX_PUSH- 如果需要接收数据执行RX_POP。代码示例伪代码// 假设我们要发送两个字节 0xABCD且不使用Mask全部使用R30数据 R30 0xABCD; // 将数据写入R30低16位 R31 (1 25); // 设置TX_PUSH16命令位bit 25其他位为0并写入R31触发命令帧结束与CRC (TX_EOF,TX_CRC_LOW,TX_CRC_HIGH)TX_EOF(bit 29)指示当前推入的数据是帧的最后一笔。发送此命令后MII_RT模块会开始计算或追加帧校验序列FCS并完成帧的发送。TX_CRC_LOW(bit 26) TX_CRC_HIGH(bit 27)当不使用硬件自动CRC而由PRU软件计算CRC时需要使用这两个命令将计算好的CRC值32位分高低16位推入FIFO。必须注意时序TX_CRC_HIGH命令结束CRC计算并将高16位CRC值推入FIFO之后需要等待至少6个时钟周期TXCRC0/1寄存器中的值才会有效然后才能发出TX_CRC_LOW命令推送低16位。关键配合TX_EOF命令可以与TX_CRC_ERRbit 31组合在帧尾强制插入一个错误字节(0xA5)用于测试或特定协议需求。但前提是必须使能自动前导码转发(TX_AUTO_PREAMBLE)。错误插入与FIFO复位 (TX_ERROR_NIBBLE,TX_RESET)TX_ERROR_NIBBLE(bit 28)在帧中插入一个错误半字节nibble使帧无效。通常用于物理层容错测试。TX_RESET(bit 30)复位TX L1 FIFO清空所有内容。这是从TX FIFO溢出错误中恢复的关键操作。一旦检测到发送FIFO满或错误应首先执行此命令进行复位。3.2 接收路径命令详解与状态管理接收命令主要用于从RX FIFO中读取数据和管理接收状态。数据弹出 (RX_POP8/RX_POP16)作用RX_POP8使接收数据流前进一个字节RX_POP16前进两个字节。只有在使用R31读取数据即寄存器模式时才需要此命令。执行RX_POP后新的数据才会出现在R31[15:0]中供PRU读取。至关重要的延迟手册明确警告RX_POP命令发出后需要等待2个时钟周期WORD_RDY或BYTE_RDY状态位才会更新。PRU固件必须确保在发出RX_POP命令后至少间隔2个周期再去检查R31的WORD_RDY位bit 30需查具体映射或读取数据否则会读到旧数据或状态。这是新手最容易忽略的硬件时序坑。代码示例伪代码// 等待接收数据就绪假设WORD_RDY映射到R31的某个状态位 while (!(R31 (1 WORD_RDY_BIT))) { // 空循环或执行其他任务 } // 数据就绪读取一个16位字 received_data R31 0xFFFF; // 读取低16位数据 // 发出POP命令让硬件准备下一个字 R31 (1 17); // 设置RX_POP16命令位bit 17 // !!! 重要这里必须等待至少2个时钟周期才能再次检查WORD_RDY !!! // 可以通过插入NOP指令或执行其他不依赖新数据的操作来实现延迟 __delay_cycles(2); // 伪代码表示延迟2个周期状态清除命令 (RX_SOF_CLR,RX_SFD_CLR,RX_EOF_CLR,RX_ERROR_CLR)作用这些命令bit 20, 21, 22, 23用于清除R31中对应的状态标志位。例如当PRU检测到RX_EOF帧结束标志后在处理完该帧后需要向RX_EOF_CLR位写‘1’来清除该标志以便识别下一帧的开始。实战技巧通常在一个帧处理循环的开始或结束阶段统一检查并清除这些状态位是一个良好的编程习惯。接收FIFO复位 (RX_RESET, bit 18)作用复位RX L1 FIFO清空所有内容。用于从接收FIFO溢出等错误中恢复。手册指出如果在活动帧期间断言RX_RESET它会1) 终止当前帧2) 阻塞所有新数据3) 清空FIFO4) 使RX状态机回到空闲状态5) 产生EOF事件6) 如果帧未达到最小尺寸则产生最小帧错误。典型用例在检测到RX_EOF后如果软件决定丢弃后续数据或进行错误恢复可以立即发出RX_RESET。3.3 命令组合与原子操作手册强调了一个关键点当需要在同一时刻执行多个命令时PRU固件必须在一条指令中设置所有这些命令位。这是因为对R31的写入操作是原子性的。例如需要在帧尾同时标记EOF和插入CRC错误那么就需要构造一个值同时设置TX_EOF位和TX_CRC_ERR位然后一次性写入R31。// 原子操作同时发送TX_EOF和TX_CRC_ERR命令 uint32_t command 0; command | (1 31); // TX_CRC_ERR command | (1 29); // TX_EOF R31 command; // 单条指令写入两个命令同时生效理解并正确运用这些命令是编写稳定、高效PRU以太网处理固件的基石。任何时序的疏忽都可能导致数据错位、丢失或硬件状态机挂起。4. 数据通路配置实战从寄存器到帧收发掌握了命令我们来看看如何通过配置寄存器搭建起我们需要的数据通路。这就像在硬件上“布线”决定了数据从哪里来到哪里去以及经过怎样的处理。4.1 字节与半字节顺序交换由于PRU核心是小端Little-Endian字节序而网络数据通常是大端Big-EndianMII_RT模块提供了硬件级的字节/半字节交换功能这能极大减轻PRU软件的处理负担。接收侧交换 (RXCFG0/1[RX_BYTE_SWAP])默认0R31[15:8] 字节1 {半字节3, 半字节2}R31[7:0] 字节0 {半字节1, 半字节0}。这符合MII接口先传高半字节的常规顺序。使能1R31[15:8] 字节0 {半字节1, 半字节0}R31[7:0] 字节1 {半字节3, 半字节2}。这相当于对16位字内的两个字节进行了交换。何时使用如果你的协议数据是网络字节序大端而PRU处理时需要小端序可以设置此位让硬件在数据存入R31前就完成交换PRU读到的就是正确顺序的数据。发送侧交换 (TXCFG0/1[TX_BYTE_SWAP])类似地控制着从R30寄存器到TX FIFO时数据字节和掩码字节的顺序。配置一致性务必确保发送和接收的交换配置与你的整个数据处理流程匹配。一个常见的策略是在接收和发送都使能字节交换这样PRU软件可以完全以本地小端序处理数据硬件负责与网络大端序的转换。4.2 前导码处理策略以太网帧前导码7字节0x55 1字节SFD 0xD5通常由硬件处理。MII_RT提供了灵活的配置RX_CUT_PREAMBLE决定是否将接收到的前导码传递给RX L1/L2 FIFO。通常应裁剪掉因为协议处理一般不关心前导码。RX_AUTO_FWD_PRE决定是否将接收到的前导码自动转发到TX L1 FIFO。在自动转发或某些桥接模式下可能有用。TX_AUTO_PREAMBLE这是一个非常实用的功能。当使能时TX接口逻辑会自动生成并附加前导码到TX数据流在第一次向TX L1 FIFO推送数据时生效。这意味着PRU软件无需在内存中存储或发送前导码字节简化了帧组装。但要注意自动生成的前导码会占用TX FIFO的空间。软件必须考虑这一点避免因FIFO空间计算错误导致溢出。4.3 PRU与MII端口复用器配置这是MII_RT模块一个强大的灵活性特性。默认映射是PRU0 - TX1/RX0 PRU1 - TX0/RX1。但你可以通过配置寄存器改变PRU核心与物理MII端口的连接关系。接收复用器允许为每个PRU核心选择其接收数据来自哪个MII接口RX_MII0 或 RX_MII1。例如你可以将两个MII端口的接收数据都送给PRU0处理实现单核监控双网口。发送复用器允许为每个MII发送端口选择数据来源来自PRU0、PRU1甚至来自另一个MII接口的接收路径实现硬件直通。配置时机警告手册特别强调复用器的选择线在一个帧的传输过程中不应改变否则会导致数据交换错误。因此配置应在通信初始化阶段完成或在确保没有活跃帧时进行。4.4 一个完整的寄存器模式数据收发流程示例假设我们要配置PRU0通过MII Port 0接收和发送数据使用硬件自动前导码并使能字节交换以简化软件处理。初始化配置通常在PRU初始化代码或主机配置中完成设置RXCFG0[RX_BYTE_SWAP] 1使接收数据在存入R31时转换为小端序。设置TXCFG0[TX_BYTE_SWAP] 1使发送数据从R31取出时转换回网络序。设置TXCFG0[TX_AUTO_PREAMBLE] 1启用发送自动前导码。设置RX_CUT_PREAMBLE 1裁剪接收前导码。配置复用器将PRU0的RX连接到RX_MII0TX连接到TX_MII0。清除TX_AUTO_SEQUENCE确保使用寄存器模式。接收中断服务例程或轮询循环伪代码void pru_eth_rx_handler() { // 等待一个完整帧开始SOF或数据就绪WORD_RDY while (!(R31 RX_WORD_RDY_MASK)) { // 可加入超时或休眠逻辑 } // 读取帧数据直到结束 do { uint16_t data_word R31 0xFFFF; // 读取数据 // 处理data_word例如存入缓冲区 process_rx_data(data_word); // 发出POP命令获取下一个字 R31 RX_POP16_CMD; // 等待2周期硬件延迟 __delay_cycles(2); // 检查是否帧结束EOF if (R31 RX_EOF_MASK) { // 帧接收完成 finalize_frame_processing(); // 清除EOF状态位 R31 RX_EOF_CLR_CMD; break; } } while (1); }发送一个数据帧的伪代码void pru_send_ethernet_frame(uint16_t *data_buffer, uint32_t data_len_words) { // 可选复位TX FIFO确保干净状态 R31 TX_RESET_CMD; // 循环发送数据负载 for (int i 0; i data_len_words; i) { R30 data_buffer[i]; // 将数据写入R30 R31 TX_PUSH16_CMD; // 推送数据到TX FIFO // 注意这里通常不需要延迟硬件会处理FIFO写入 } // 发送帧结束命令硬件会自动添加CRC如果使能 R31 TX_EOF_CMD; // 等待发送完成可通过查询状态或中断 // ... }5. 高级功能与性能优化实战在基础的数据通路搭建起来之后我们需要关注如何让它跑得更稳、更快、更省资源。这部分内容往往在数据手册中一笔带过但却是实战中的关键。5.1 TX Mask模式的精妙应用TX Mask模式是MII_RT的“杀手级”特性它允许在数据流经硬件时进行实时修改。其核心公式TXDATA (R30 MASK) | (RXDATA ~MASK)意味着MASK位为1的对应位发送数据来自R30PRU提供。MASK位为0的对应位发送数据来自RXDATA实时接收路径的数据。实战场景1实时帧转发与地址替换假设你需要设计一个简单的2端口交换机其中一个端口收到的帧需要将其源MAC地址替换为设备自身的MAC地址后从另一个端口转发出去。无Mask模式PRU需要将整个帧从RX FIFO读入内部内存修改MAC地址字段再将整个帧写入TX FIFO。这需要大量内存和CPU周期。使用Mask模式配置为寄存器模式并使能TX Mask。在帧起始目标MAC地址字段将MASK全部设为0直接转发接收到的目标MAC地址。当到达源MAC地址字段时PRU将自身的MAC地址写入R30低16位并将对应位的MASKR30高16位设为全1。然后发出TX_PUSH16命令。这样硬件会自动用R30中的新地址覆盖掉流经的原始地址。后续的数据字段再将MASK设为0恢复直接转发。 这样PRU只在需要修改的6个字节源MAC地址处进行干预其余字节全部由硬件自动转发延迟极低且PRU负载大幅减轻。实战场景2协议数据实时插入在工业协议中常常需要在转发数据包时插入实时状态信息如循环冗余校验值、设备状态字。可以预先将状态字准备好放在PRU内存中。当数据流经过需要插入状态字的位置时PRU将状态字写入R30并设置对应MASK为全1执行TX_PUSH。这种方法实现了“线速”修改对帧转发延迟的影响最小。5.2 FIFO深度管理与溢出预防FIFO溢出是导致数据丢失的最常见原因。虽然MII_RT有硬件流控但PRU软件必须积极管理。TX L1 FIFO (64字节)在使能TX_AUTO_PREAMBLE后前导码会占用FIFO空间。一个最大1518字节的以太网帧需要约1526字节的FIFO空间含前导码、SFD和FCS远超64字节。因此PRU绝不能一次性将整个大帧的数据全部推入FIFO。必须采用“流式”推送推入一部分数据等待FIFO有空间通过查询状态或使用中断再推入下一部分。或者确保你的应用帧长较小不会超过FIFO深度。RX L1 FIFO (32字节)如果PRU处理速度跟不上接收速度RX FIFO会溢出。预防措施包括优化PRU代码确保中断服务例程或轮询循环尽可能高效。使用RX_POP后的延迟严格遵守2周期延迟规则避免因过早查询状态导致的忙等待或错误弹出。及时复位一旦检测到溢出错误可能通过状态位或帧校验错误发现应立即使用RX_RESET命令清空FIFO恢复到一个已知状态而不是尝试处理可能已损坏的数据。5.3 利用RX L2作为高速共享内存当RXCFG0/1[RX_L2_ENABLE]被禁用时RX L2的32字节x2 Banks就变成了两块宝贵的共享内存。PRU可以通过XFR快速寄存器指令高速访问它们。用途存储协议解析的临时变量、统计计数器、时间戳、或作为一个小型的邮箱mailbox与另一个PRU核心或主机CPU进行低延迟通信。性能优势访问速度与访问寄存器文件相当远快于访问外部DDR内存。对于需要频繁存取中间结果的实时算法非常有用。注意在Scratch Pad模式下RX_RESET命令对它无效。需要软件自行管理其内容的初始化和一致性。5.4 调试与性能统计PRU_ICSS_PRU_CTRL寄存器组提供了一些有用的调试信息CYCLE寄存器记录PRU使能后的运行周期数。可以用于粗略的性能分析和任务执行时间测量。STALL寄存器记录PRU因等待指令获取而停滞的周期数。这个值异常高通常意味着指令存储器访问遇到了瓶颈可能是代码位置不佳或内存冲突需要优化。GPREG0-GPREG31当PRU被禁用时主机可以通过这些寄存器直接查看和修改PRU内部通用寄存器的值是强大的调试工具。6. 常见问题排查与避坑指南在实际项目中使用MII_RT你几乎一定会遇到下面这些问题。这里记录了我踩过的坑和总结的排查思路。6.1 数据错位或乱码症状接收或发送的数据字节顺序不对比如0x1234变成了0x3412。排查首先检查RX_BYTE_SWAP和TX_BYTE_SWAP配置。这是最常见的原因。确认你的软件对字节序的期望与硬件配置是否一致。检查MII接口的连线。MII的TXD[3:0]和RXD[3:0]每位应对应连接确保没有错位。在TX Mask模式下检查MASK寄存器的设置是否正确。错误的MASK会导致数据来源混乱。6.2 发送帧不完整或CRC错误症状发送的帧被对端丢弃Wireshark显示帧校验错误或帧过短。排查检查TX_EOF命令是否在帧数据的最后正确发出了TX_EOF命令没有它硬件不知道帧结束不会添加FCS。检查TX_AUTO_PREAMBLE如果使能了自动前导码PRU软件发送的数据不应包含前导码和SFD。如果包含了会导致帧结构错误。检查FIFO溢出是否因为一次性写入数据太多导致TX FIFO溢出溢出后数据会丢失。确保流式推送并监控FIFO状态如果硬件提供状态位。手动CRC计算错误如果使用PRU软件计算CRC确保算法正确并且严格按照TX_CRC_HIGH- 等待6周期 -TX_CRC_LOW的顺序推送。一个常见的错误是等待周期不足。6.3 接收不到数据或数据丢失症状PRU始终读不到数据或只能收到部分帧。排查检查RX_POP时序这是头号嫌疑犯。你是否在发出RX_POP16/8命令后等待了至少2个时钟周期才去读取R31或检查WORD_RDY如果没有你读到的就是旧数据或旧状态。在RX_POP后插入几条NOP指令是最简单的验证方法。检查PHY和链路状态确保物理链路已建立link upPHY配置正确。检查复用器配置PRU核心是否连接到了正确的MII RX端口RXCFG0/1中的复用选择寄存器是否正确检查FIFO溢出使用RX_RESET复位FIFO然后重新测试。如果复位后能收到一帧然后又收不到了很可能是PRU处理太慢导致溢出。优化代码或考虑使用更大的缓冲区如果支持或更快的PRU时钟。检查前导码裁剪如果RX_CUT_PREAMBLE设置错误可能导致帧起始定位失败。6.4 自动转发模式不工作症状设置了TX_AUTO_SEQUENCE但数据没有从RX端口转发到TX端口。排查确保发送和接收的MII端口通过复用器正确连接到了直通路径。自动转发通常需要配置TX复用器选择源为“另一个MII接口的RX”。检查TX和RX的使能位是否都已正确设置。确认在自动转发模式下你没有同时让PRU去操作TX FIFO如发送TX_PUSH命令这会造成冲突。6.5 性能瓶颈分析症状系统无法达到预期的吞吐量或实时性。排查查看STALL寄存器如果停滞周期数占总周期数的比例很高说明指令获取是瓶颈。尝试将最关键的、循环内的代码段移动到PRU的内部RAM如果可用或更靠近零等待周期的存储器中。分析PRU汇编代码使用clpru编译器的优化选项如-O2并检查生成的汇编代码消除不必要的内存访问和分支。评估数据通路是否使用了最高效的模式对于简单的转发自动转发模式延迟最低。对于需要修改的转发TX Mask模式比完全软件处理更快。对于复杂协议解析寄存器模式是唯一选择。双PRU协作对于高吞吐量应用可以考虑让一个PRU核心专门处理接收RX另一个核心专门处理发送TX通过共享内存如RX L2 Scratch Pad或外部存储器传递数据实现流水线处理。驾驭PRU-ICSS的MII_RT模块是一个从理解硬件逻辑到精细控制软件时序的完整过程。它要求开发者同时具备硬件思维和软件精度。开始时可能会被各种配置和时序问题困扰但一旦打通你将获得一个强大且确定性的实时网络处理引擎足以应对最严苛的工业通信挑战。记住多利用示波器或逻辑分析仪观察关键信号如TX_EN,RXDV, PRU的GPIO调试引脚结合寄存器的配置值很多问题都会变得直观。