RX系列MCU以太网PHY寄存器访问:阻塞与非阻塞模式深度解析与实战

AI助手已提取文章相关产品:

1. 项目概述

在嵌入式以太网开发里,MAC和PHY之间的“对话”是个基本功,而MII/RMII管理接口(MDC/MDIO)就是它们说悄悄话的专用通道。别看它只有两根线,PHY芯片的“性格”——比如跑100M还是1000M、是全双工还是半双工、甚至是否启用节能模式——全得靠读写它内部的寄存器来设定。很多新手觉得这部分配置是驱动库或者硬件抽象层(HAL)该管的事,直接调个初始化函数就完事了。但真到了调试的时候,比如链路死活不起来,或者网络性能不稳,你迟早得和这些底层的时序、配置选项打交道,否则连问题出在PHY还是软件配置上都搞不清楚。

这次我们聚焦瑞萨(Renesas)RX系列微控制器,它通过一个叫“以太网FIT模块”(Firmware Integration Technology)的软件层,把硬件操作封装成了相对友好的API。但官方手册里关于MII/RMII寄存器访问的细节,特别是阻塞与非阻塞两种模式的差异和实现,往往散落在各个章节和配置项里。我最近在几个工业网关项目上深度使用了RX65N和RX72N,把ETHER_CFG_NON_BLOCKING这个开关从0拨到1,再从1拨回0,来回折腾了好几遍,踩了不少坑,也对这两种访问模式的适用场景和调优方法有了更深的体会。这篇文章,我就结合实测数据和代码片段,把RX系列以太网模块的MII/RMII寄存器访问机制,以及非阻塞API的使用心法,给你彻底讲透。

2. MII/RMII管理接口核心原理与硬件时序

2.1 MDC/MDIO协议基础:PHY的“I2C”

你可以把MDC/MDIO理解成以太网PHY芯片专属的“I2C”总线。MDC是时钟线,由MAC(或MCU内部的以太网控制器)主导;MDIO是双向数据线,负责传输具体的命令和数据。每一次通信,都遵循一个固定的管理帧格式,这个帧包含了起始条件、操作码(读或写)、PHY地址、寄存器地址和要读写的数据。

在RX的以太网FIT模块中,访问PHY寄存器本质上就是由软件或硬件辅助模块,按照这个帧格式,在MDC时钟的节拍下,在MDIO线上生成或解析一串特定的高低电平序列。理解这一点至关重要,因为后续所有关于时序的配置和调试,都是为了让这一串电平信号能够被PHY芯片正确无误地识别。

2.2 阻塞模式(PIR寄存器模拟)的运作机制

当你在配置文件 r_ether_rx_config.h 中将 ETHER_CFG_NON_BLOCKING 设置为 0 时,就选择了阻塞访问模式。在这种模式下,FIT模块会使用一个叫做PIR(PHY Interface Register)的寄存器来模拟MDC/MDIO的时序。

它是怎么工作的? 软件需要直接操作PIR寄存器,手动控制MDC引脚的电平翻转,并按照位(bit)来拼装或解析整个管理帧。例如,要发起一个读操作,你的代码(或驱动底层)需要:

  1. 通过PIR寄存器将MDIO引脚设置为输出模式,并依次输出帧起始码、读操作码、PHY地址和寄存器地址。
  2. 切换MDIO为输入模式,然后在MDC的每个时钟边沿从MDIO引脚读取PHY返回的数据位。
  3. 在整个过程中,CPU需要循环等待,直到整个帧的32位或更多位全部发送/接收完成,函数才会返回。这就是“阻塞”的含义——在访问PHY寄存器的几十微秒内,CPU会被完全占用,无法执行其他任务。

官方手册中图5.3和表5.2给出了一个具体的阻塞模式时序案例。他们用的是R5F565N9ADFB芯片,主频120MHz,PHY是DP83620。表5.3的实测数据非常关键:

时序参数 符号 PHY要求最小值 PHY要求最大值 实测值(参考) 单位
MDC到MDIO(输出)延迟 T1 0 20 8 ns
MDIO(输入)到MDC建立时间 T2 10 - 500 ns
MDIO(输入)到MDC保持时间 T3 10 - 2300 ns
MDC时钟周期 T4 40 - 2840 ns

关键解读与避坑点

  1. T1(8ns) :这个值远小于PHY的最大要求(20ns),说明MCU驱动MDIO引脚变化的速度足够快,是安全的。
  2. T2和T3(500ns & 2300ns) :这两个是 输入建立和保持时间 ,实测值远大于PHY要求的最小值(10ns)。这其实是 软件模拟时序的典型特征 。因为用循环和NOP指令来翻转MDC时钟,其精度和速度远不如硬件,导致时钟周期(T4)长达2840ns(约352kHz),从而使得T2和T3的时间窗口被拉得非常宽裕。虽然通信功能正常,但效率低下。
  3. 核心矛盾 :阻塞模式的缺点显而易见。首先, CPU占用率高 ,每次访问都要“忙等”。其次, 时序由软件循环控制 ,其精度受中断、任务调度影响,在高主频或复杂RTOS环境下可能变得不稳定。最后, MDC频率低 ,当需要频繁读取PHY状态(如链路状态轮询)时,会成为系统性能的瓶颈。

2.3 非阻塞模式(PMGI硬件模块)的运作机制

ETHER_CFG_NON_BLOCKING 设置为 1 ,就启用了非阻塞模式。此时,一个专用的硬件模块——PMGI(PHY Management Interface)——会接管MDC/MDIO的控制。

硬件模块的优势 :PMGI是一个状态机,你只需要通过API向它下达“读PHY地址0x01的寄存器0x01”这样的命令,它就会自动在后台生成正确的MDC时钟和管理帧,完成整个通信过程。在此期间,CPU被完全解放,可以去处理其他任务。当PMGI完成操作后,会产生一个中断,并通过你预先注册的回调函数来通知你结果。

手册中的图5.4和表5.4展示了非阻塞模式的配置,用的是R5F572NNDDBD芯片,并引入了几个关键配置项:

  • ETHER_CFG_PMGI_CLOCK : 设置为2500000,即2.5MHz。这是你希望PMGI硬件产生的MDC时钟频率。
  • ETHER_CFG_PMGI_HOLD_TIME : 设置为7。
  • ETHER_CFG_PMGI_CAPTURE_TIME : 设置为0。

表5.5的实测数据发生了根本性变化:

时序参数 符号 PHY要求最小值 PHY要求最大值 实测值(参考) 单位
MDC到MDIO(输出)延迟 T1 - - 64 ns
MDIO(输入)到MDC建立时间 T2 10 - 332 ns
MDIO(输入)到MDC保持时间 T3 4 - 60 ns
MDC时钟周期 T4 - - 399 ns

关键解读与优势分析

  1. T4(399ns) :对应的MDC频率约为2.5MHz,与配置值完全吻合。这比软件模拟的352kHz快了7倍多, 通信效率大幅提升
  2. T2和T3(332ns & 60ns) :虽然仍比最小值大很多,但这是由硬件时序逻辑保证的, 极其稳定和精确 ,不受软件负载影响。
  3. CPU零占用 :在PMGI工作期间,CPU完全自由。这对于实时性要求高的系统(如需要快速响应网络事件、执行运动控制循环)是至关重要的。
  4. 配置的艺术 PMGI_HOLD_TIME PMGI_CAPTURE_TIME 这两个参数是 确保时序符合PHY芯片AC规格的关键 。它们用来微调PMGI模块在MDC时钟沿前后,对MDIO信号进行采样和保持的时间点。如果实测时序不满足你所用PHY芯片的数据手册要求,就需要调整这两个参数,而不是去改软件延时。

3. 非阻塞API的使用流程与实战代码解析

非阻塞模式不仅仅改变了底层时序,更改变了整个软件驱动的工作方式。你需要从“顺序执行”的思维,切换到“事件驱动”或“状态机”的思维。

3.1 全局状态变量与初始化

非阻塞API的核心思想是“发起请求,等待回调”。因此,我们需要一些全局或模块内的状态变量来跟踪异步操作的进度。

/* 非阻塞操作状态标志 */
volatile bool g_pmgi_busy = false; // PMGI硬件忙标志
volatile bool g_link_status_check_done = false; // 链路检查完成标志
volatile bool g_link_up = false; // 链路最终状态标志
volatile ether_event_t g_last_ether_event; // 记录最后一次以太网事件

/* 回调函数参数结构体指针 */
pmgi_cb_arg_t *g_pmgi_cb_arg;

main 函数或网络初始化任务的开始,必须初始化这些变量,并将回调函数注册到系统中。

void ethernet_init(void) {
    /* 1. 初始化全局状态变量 */
    g_pmgi_busy = true; // 初始化为true,等待Open函数将其置为false
    g_link_status_check_done = false;
    g_link_up = false;

    /* 2. 内存初始化、引脚设置等(根据BSP和硬件设计) */
    R_BSP_Init();
    ether_pin_config(); // 配置ETn_MDC, ETn_MDIO, ETn_TX, ETn_RX等引脚

    /* 3. 注册PMGI中断回调函数 */
    R_ETHER_Control(ETHER_CH0, CONTROL_SET_PMGI_CALLBACK, (void *)pmgi_interrupt_callback);

    /* 4. 初始化ETHERC和EDMAC控制器 */
    R_ETHER_Open_ZC2(); // 首次调用,非阻塞模式启动
}

3.2 主循环中的状态机逻辑

你的主循环或网络任务不再直接调用阻塞函数等待结果,而是不断地检查状态标志,并根据状态决定下一步动作。手册中的图5.5清晰地描绘了这个流程。

void main_loop(void) {
    ethernet_init();

    while (1) {
        /* 状态机:等待PHY初始化完成 */
        if (g_pmgi_busy == false) {
            /* PMGI空闲,可以开始链路检查 */
            if (g_link_status_check_done == false) {
                R_ETHER_CheckLink_ZC(ETHER_CH0); // 非阻塞调用,检查链路
                g_link_status_check_done = true; // 防止重复调用
            }

            /* 状态机:处理链路检查结果 */
            if (g_link_status_check_done == true && g_link_up == false) {
                /* 链路检查已完成,但链路未UP,执行链路处理(如重启自协商) */
                R_ETHER_LinkProcess(ETHER_CH0);
            } else if (g_link_up == true) {
                /* 链路已UP,可以开始正常的网络数据收发 */
                user_network_application();
            }
        }

        /* 执行其他系统任务,CPU不会阻塞在PHY访问上 */
        other_system_tasks();
        R_BSP_SoftwareDelay(10, BSP_DELAY_MILLISECS); // 简单延时,实际项目中用RTOS延时或事件驱动
    }
}

3.3 PMGI中断回调函数的实现

这是非阻塞模式的“心脏”。当PMGI硬件完成任何一个操作(初始化、读PHY、写PHY、链路检查等),都会触发中断并调用这个函数。手册图5.6是其逻辑流程图。

void pmgi_interrupt_callback(void *p_args) {
    pmgi_cb_arg_t *p_decode = (pmgi_cb_arg_t *)p_args;

    /* 根据回调参数中的`mode`判断是哪个操作完成了 */
    switch (p_decode->mode) {
        case OPEN_ZC2:
            if (p_decode->event == PMGI_COMPLETE) {
                g_pmgi_busy = false; // PHY初始化完成,PMGI空闲
                LOG_INFO("PHY Init Complete via PMGI.");
            } else if (p_decode->event == PMGI_ERROR) {
                LOG_ERROR("PHY Init Failed!");
                // 这里可以加入错误恢复机制,如重试或系统复位
            }
            break;

        case CHECKLINK_ZC:
            if (p_decode->event == PMGI_COMPLETE) {
                // 链路检查完成,需要从回调参数或API返回值中解析出实际链路状态
                // 假设通过某个函数或p_decode->data获取到link_stat
                bool link_stat = get_link_status_from_cb_arg(p_decode);
                g_link_status_check_done = true;
                if (link_stat) {
                    g_link_up = true;
                    LOG_INFO("Link is UP.");
                } else {
                    g_link_up = false;
                    LOG_INFO("Link is DOWN.");
                }
            }
            break;

        case LINKPROCESS:
            if (p_decode->event == PMGI_COMPLETE) {
                // 链路处理(如自协商)完成,可以再次触发链路检查
                g_link_status_check_done = false; // 重置标志,让主循环重新检查
                LOG_DEBUG("Link Process Completed.");
            }
            break;

        case WRITEPHY:
        case READPHY:
            // 处理自定义的PHY寄存器读写完成事件
            if (p_decode->event == PMGI_COMPLETE) {
                uint16_t phy_data = p_decode->data; // 假设数据在此
                handle_phy_reg_access_complete(p_decode->phy_reg_addr, phy_data);
            }
            break;

        default:
            LOG_WARN("Unknown PMGI callback mode: %d", p_decode->mode);
            break;
    }

    /* 如果需要,可以在这里更新其他非阻塞处理相关的全局变量 */
}

实操心得与陷阱

  1. 回调函数执行上下文 :这个函数在 中断上下文 中被调用!这意味着你必须遵循中断服务例程(ISR)的所有规则: 快进快出 ,不能调用可能阻塞的函数(如某些RTOS的 vTaskDelay ),对于复杂处理应通过标志位通知任务线程处理。
  2. 共享变量访问 g_pmgi_busy g_link_up 等状态变量在中断和主循环中被共同访问,必须使用 volatile 关键字声明,并在必要时使用临界区保护(如开关全局中断)来确保操作的原子性,避免出现竞态条件。
  3. 错误处理 :一定要处理 PMGI_ERROR 事件。PHY访问可能因为硬件连接不良、PHY芯片未响应、时序不匹配等原因失败。完善的错误处理(如有限次重试、日志记录、系统降级运行)是产品稳定性的保障。

4. 配置选项深度解析与调优指南

r_ether_rx_config.h 这个配置文件是驱动行为的“总开关”。除了 ETHER_CFG_NON_BLOCKING ,还有几个与MII/RMII访问密切相关的配置项,理解它们才能玩转这个驱动。

4.1 ETHER_CFG_PHY_MII_WAIT(阻塞模式专用)

这个配置仅在阻塞模式下生效。它定义了软件在操作MDC引脚(如电平翻转)之间插入的延迟循环次数。 这个值直接决定了软件模拟出的MDC时钟频率和时序。

  • 如何计算? 它的单位是CPU指令周期。例如,在表5.2的环境(ICLK=120MHz)下,设置值为4。假设一个NOP或简单循环消耗几个周期,那么一次“翻转-等待”的耗时决定了T4(时钟周期)。你需要根据你的CPU主频和所需MDC频率来调整它。公式可以粗略估算为: MDC_Period ≈ (2 * ETHER_CFG_PHY_MII_WAIT * Cycles_per_Loop) / ICLK_Frequency
  • 调优方法 :如果PHY访问不稳定,可以尝试增大此值以降低MDC频率、延长建立保持时间。但过大会导致访问过慢。最佳方法是结合逻辑分析仪,测量实际的MDC、MDIO波形,确保T1, T2, T3满足你所用PHY芯片数据手册的AC特性要求。

4.2 PMGI相关配置(非阻塞模式专用)

  • ETHER_CFG_PMGI_CLOCK :这是你 期望 的MDC时钟频率(单位Hz)。驱动会基于PCLKA频率和这个值来计算内部分频器。 这个值不能超过PMGI硬件和PHY芯片支持的最大频率 。常见PHY支持最高2.5MHz或更高,但为了稳定,通常设置为1-2.5MHz。
  • ETHER_CFG_PMGI_HOLD_TIME ETHER_CFG_PMGI_CAPTURE_TIME :这是 时序微调 的利器。它们控制PMGI模块在MDC时钟边沿前后,对MDIO数据线的采样和驱动保持的时间点。
    • HOLD_TIME :在MDC下降沿(或上升沿,具体看实现) 之后 ,PMGI继续保持输出数据稳定的时间。如果PHY芯片读取MDIO数据需要较长的保持时间,可以适当增加此值。
    • CAPTURE_TIME :在MDC上升沿(或采样沿) 之前 ,PMGI提前采样MDIO输入数据的时间。如果MDIO信号到MCU有延迟,可以增加此值以确保在稳定时段采样。
    • 如何设置? 最科学的方法是 查阅PHY芯片数据手册的MDC/MDIO时序图 ,找到 tSU (建立时间)和 tHD (保持时间)的要求,然后通过调整这两个配置项,使得PMGI产生的时序满足要求。手册表5.5的实测值就是一个参考起点。

4.3 模式选择建议:阻塞 vs 非阻塞

特性 阻塞模式 ( NON_BLOCKING = 0 ) 非阻塞模式 ( NON_BLOCKING = 1 )
实现方式 软件循环操作PIR寄存器 PMGI硬件状态机
CPU占用 高,访问期间CPU忙等 极低,访问期间CPU自由
时序精度 低,受中断和软件负载影响 高,由硬件时钟精确控制
MDC频率 低(通常几百kHz) 高(可配置,通常1-2.5MHz)
代码复杂度 低,流程直观(顺序执行) 高,需状态机和回调函数
实时性影响 可能阻塞高优先级任务 对系统实时性影响小
适用场景 对实时性要求不高、初始化阶段、或资源极其有限的简单应用 对系统响应速度要求高、需要频繁监控PHY状态、或基于RTOS的复杂应用

我的经验 :在早期的简单设备上,我用阻塞模式,代码简单粗暴。但在现在的工业网关、需要快速网络故障切换的设备上, 一律使用非阻塞模式 。虽然前期状态机设计稍复杂,但它带来的系统响应能力提升是质的飞跃。特别是当网络链路抖动时,非阻塞的 R_ETHER_LinkProcess R_ETHER_CheckLink_ZC 可以无缝融入RTOS的事件驱动框架,不会卡住整个系统。

5. 常见问题排查与调试技巧实录

5.1 PHY寄存器读写失败

  • 症状 R_ETHER_WritePHY R_ETHER_ReadPHY 返回错误,或回调函数收到 PMGI_ERROR ,但硬件连接正常。
  • 排查步骤
    1. 确认PHY地址 :这是最常出错的地方!不同PHY芯片、不同板卡设计,PHY的MDIO地址可能不同(通常由硬件引脚上下拉决定)。用万用表测量PHY芯片的配置引脚,或仔细阅读板卡原理图和数据手册。常见的地址是0或1,但也可能是其他值。
    2. 检查电源和复位 :确保PHY芯片的供电稳定,且复位引脚已经完成释放。有些PHY需要上电后等待几十毫秒才能响应MDIO命令。
    3. 测量MDC/MDIO波形 这是终极调试手段 。用逻辑分析仪或示波器抓取MDC和MDIO的波形。
      • 看帧格式 :对照MII管理帧格式(前导码、起始位、操作码、地址、数据等),看发出的帧是否正确。
      • 看时序 :测量T1, T2, T3, T4是否满足PHY芯片数据手册的 最小值/最大值 要求。如果不满足,调整 PHY_MII_WAIT 或PMGI的 HOLD_TIME / CAPTURE_TIME
    4. 检查配置宏 :确认 ETHER_CFG_CH0_PHY_ADDRESS (或CH1)是否正确设置为你的PHY地址。

5.2 非阻塞模式下回调函数不执行

  • 症状 :调用了 R_ETHER_Open_ZC2 等函数,但注册的回调函数从未被调用,程序卡住。
  • 排查步骤
    1. 中断未使能 :PMGI中断必须在MCU的中断控制器(ICU)中使能,并且优先级设置正确。检查 r_ether_rx 模块的初始化代码或你的BSP配置,是否正确配置了PMGI中断向量和使能位。
    2. 回调函数注册失败 :确认 R_ETHER_Control(CONTROL_SET_PMGI_CALLBACK, ...) 调用成功,且传入的函数指针正确。
    3. 全局中断未开启 :在 main 函数初始化后期,确保调用了类似 __enable_irq() 的函数开启了全局中断。
    4. 状态机逻辑死锁 :检查你的全局状态变量(如 g_pmgi_busy )初始化是否正确。如果初始化时为 true ,但回调函数里忘记将其置为 false ,主循环就会一直等待。

5.3 链路状态检测异常

  • 症状 :网线已连接,但 R_ETHER_CheckLink_ZC 总是返回链路断开,或者链路状态不稳定。
  • 排查步骤
    1. PHY自协商配置 :大多数PHY默认启用自协商。确保你的MAC端配置(通过 R_ETHER_Open_ZC2 的参数或PHY寄存器配置)与对端设备(如交换机)兼容。有时需要强制指定速度和双工模式。
    2. 读取PHY状态寄存器 :不要只依赖 R_ETHER_CheckLink_ZC 的返回。在非阻塞回调中,或使用 R_ETHER_ReadPHY 直接读取PHY的标准状态寄存器(如BMCR、BMSR)。查看具体的链接状态位、自协商完成位,这能提供更准确的诊断信息。
    3. 硬件连接 :检查RJ45接口、变压器(Magnetics)、以及PHY到RJ45之间的差分线是否焊接良好。差分对需要等长、紧耦合,阻抗匹配为100欧姆。

5.4 软件复位(EDMR.SWR)的致命陷阱

手册第8章“Usage Notes”里提到了一个 极其重要 的警告:在RX64M/RX71M/RX72M/RX72N/RX66N上,如果在EDMAC(以太网DMA控制器)正在传输数据时,将EDMR.SWR(软件复位位)置1, 可能会破坏地址0x00000000到0x0000001F的内存数据

血的教训 :我在一次调试中,因为网络异常试图在运行时调用复位函数重新初始化以太网模块,结果导致系统跑飞。最后排查发现就是触发了这个坑。这段内存通常是中断向量表或关键代码/数据所在区域,被破坏后系统行为完全不可预测。

安全操作指南

  1. 绝对不要在数据收发过程中进行软件复位 。如果需要复位,必须先通过API停止DMA收发,等待所有传输完成,再进行复位操作。
  2. 仔细阅读 R_ETHER_Close R_ETHER_Open_ZC2 的调用顺序。通常,关闭函数会处理DMA停止等清理工作。
  3. 如果可能,考虑使用硬件复位(通过MCU的复位引脚控制PHY)而非软件复位。

6. 与EPTPC Light FIT模块的协同工作

手册第6.1节提到了一个增强功能模块:EPTPC Light FIT。它主要提供两个实用功能:

  1. 简单交换 :对于具有双以太网通道(Channel 0和1)的RX型号(如RX72M),可以在硬件层面实现两个端口之间的数据帧转发,无需CPU干预,适合做简单的双端口交换机。
  2. 组播过滤 :在硬件层面过滤组播帧,只有目的地址匹配预设地址(最多两个)的组播帧才会被提交给CPU,极大减轻了CPU处理无关组播流量的负担,在工业协议(如EtherNet/IP)中非常有用。

关键限制 :需要注意的是, 以太网FIT模块不能同时与EPTPC Light FIT模块和完整的EPTPC FIT模块(支持IEEE 1588精确时间协议)一起使用 。你必须根据需求二选一:

  • 需要简单交换或组播过滤,但不需要IEEE 1588:选择 EPTPC Light ( r_ptp_light_rx )
  • 需要IEEE 1588时间同步功能:选择 完整的EPTPC模块 ( r_ptp_rx ) ,但它可能不包含Light版本的交换和过滤功能。

7. 开发环境与版本兼容性要点

手册第6.2节罗列了庞大的已验证环境列表。这里提炼几个关键信息:

  • 编译器兼容性 :CC-RX、GCC for Renesas RX、IAR for RX三大编译器都支持。但要注意,从Rev1.23开始, 编译器选项默认使用Smart Configurator的配置 。如果你手动修改了工程选项,需要确保与FIT模块兼容,特别是C语言标准(如 -lang=c99 -std=gnu99 )。
  • 版本迭代 :从Rev1.12到1.25,几乎每个版本都修复了重要的软件问题。例如:
    • Rev1.12:修复了 R_ETHER_LinkProcess 在特定条件下链路处理失败的问题。
    • Rev1.15:修复了在中断函数中调用读函数可能无法正常接收,以及链路处理在自协商未完成时卡住的问题。
    • Rev1.17/1.20:修复了缓冲区释放后可能无法接收,或描述符设置错误导致收发异常的问题。
  • 实践建议
    1. 始终使用最新版本的FIT模块 。瑞萨官网会定期更新,修复已知问题。
    2. 在创建新工程时,使用e2 studio的Smart Configurator图形化工具来添加和配置FIT模块,这能最大程度避免手动配置错误(如头文件路径、链接顺序)。
    3. 如果遇到编译错误,如“Could not open source file ‘platform.h’”,首先检查BSP(板级支持包)FIT模块是否已正确添加到工程中,这是所有FIT模块依赖的基础。

调试RX以太网,逻辑分析仪是比仿真器更直观的工具。抓一抓MDC/MDIO的波形,抓一抓以太网帧的收发,很多问题都会一目了然。非阻塞模式初看复杂,但一旦理顺了状态机的逻辑,它带来的系统整体性能提升会让你觉得一切投入都是值得的。尤其是在复杂的网络应用中,让CPU从低速的PHY访问中解脱出来,去处理更重要的协议栈和应用逻辑,是整个系统设计走向成熟的关键一步。

您可能感兴趣的与本文相关内容

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值