设计说明
代码结构
Ethernet 的源码牵涉三个目录
硬件驱动相关
packages/third-party/lwip/contrib/ports/drv/aic/操作系统相关
LwIP 运行需要实现的操作系统相关接口及架构相关的定义 packages/third-party/lwip/contrib/ports/rt-thread/LwIP 内核相关
LwIP 内核协议栈源码 packages/third-party/lwip/src/
文件名称 | 用途 |
---|---|
aic_mac.c | 实际操作 MAC 寄存器的 MAC 驱动源文件 |
aic_mac.h | MAC 驱动头文件 |
aic_mac_ll.c | 非操作 MAC 寄存器 MAC 驱动源文件 |
aic_mac_reg.h | MAC 寄存器定义头文件 |
aic_phy.c | 通用 PHY 驱动源文件 |
aic_phy.h | 通用 PHY 驱动头文件 |
ethernetif.c | LwIP 接口需要调用的核心 MAC 驱动源文件 |
ethernetif.h | LwIP 接口需要调用的 MAC 驱动头文件 |
驱动架构
Luban-Lite GMAC 驱动架构如下图。应用程序可通过标准 Socket 接口或基于 RAW 的 Callback 接口编写应 用逻辑。除此之外,Luban-Lite 在标准 LwIP 上封装了部分测试命令(ArtInChip Tools),如”ping”、”iperf”、”ifconfig”、 “mqtt”等测试命令可供上层开发人员进行基础的测试。
关键流程设计
以太网在初始化过程中会创建三个任务, 三个任务的优先级由高到低分别是:线路链接状态检测任务、 网卡数据包输入任务、以及协议栈处理任务、
-
- 线路链接状态检测任务
-
线路链路状态检测任务是周期轮询的任务,轮询时间一般为 1S 或 2S。主要功能是实时检测当前 网络链路的链接状态,一旦网络链路状态发生改变,就通过当前的链路状态选择当前以太网的打开状态
-
- 网卡数据包输入任务
-
网络包接收任务可以是周期轮询的任务也可以是事件驱动型的任务,主要取决于产品需求。 主要功能是与硬件 DMA 进行协作,读取当前 DMA 已经搬运完成的数据包,并将缓冲区还给 DMA。 然后再将接收完成的数据包交给协议栈任务进行处理
-
- 协议栈处理任务
-
协议栈处理任务为事件驱动型任务,为以太网驱动的核心。事件的来源可以是网络包接收任务、 超时事件、也可以是协议栈自身发出的请求。主要处理数据包的解包、封包、TCP/IP 协议等
MAC 模块初始化一般发生在协议栈初始化之后,驱动层通过 netif_add 接口将 ethernetif_init 传入,并在设置完 LwIP 属性之后调用 ethernetif_init 接口,然后开始执行模块的初始化流程
MAC 初始化完成后,不会直接使能 MAC 的发送与接收,而是当 PHY 自协商完成后,才需要打开 MAC 的全部功能。
当有数据需要发送时,LwIP 协议栈会组织好待发送的网卡数据包,然后调用 low_level_output 接口 完成数据包的发送过程
网卡数据包实际的发送过程只有一种,就是 MAC 内部集成的 DMA 通过发送描述符将数据包发送至网卡 内部的 FIFO(先入先出缓冲区),再由 FIFO 将数据包发送至 PHY 芯片。因此实际的数据包发送过程一 般都是组装 DMA 发送描述符的过程
与发送过程类似,接收过程也需要完全依赖 MAC 内部的 DMA。当一帧完整的以太网数据帧到来时,DMA 将从 MAC 内部的 FIFO 中将数据拷贝至接收描述符描述的缓存地址中,当 DMA 传输完成时,会触发一个 DMA 接收完成中断,软件获取到这一中断事件后,就需要根据当前的描述符找到当前网卡的缓存,并将 以太网数据帧取出。并将 DMA 描述符归还至 DMA
能触发 MAC 中断的事件很多,但在实时系统中一般只开启 MAC 的 DMA 接收完成中断。因此 MAC 的中断 流程设计会相对较简单,只判断是否是接收中断,然后如果是接收中断就释放一个信号量通知网卡 数据包输入任务去 DMA 缓存中取数据