1. 网络驱动基础概念
大家好,我是你们的嵌入式Linux网络驱动讲师。今天咱们聊聊网络驱动的基础概念。说实话,这部分内容看起来有点理论化,但别急着跳过——我当年刚入行时也觉得这些协议栈、模型啥的离实际开发很远,直到第一次调不通网口,才明白基础有多重要。
1.1 OSI模型与TCP/IP协议栈
先说说OSI七层模型。这玩意儿是国际标准化组织搞出来的参考模型,说白了就是把网络通信拆成七个层次。从上到下分别是:应用层、表示层、会话层、传输层、网络层、数据链路层、物理层。
你可能会问:实际开发中真要用到七层吗?其实不然。我们嵌入式Linux开发更常用的是TCP/IP四层模型——应用层、传输层、网络层、网络接口层。嗯,这里要注意,TCP/IP模型把OSI的上三层合并成了应用层,把下两层合并成了网络接口层。
核心要点:OSI是理论模型,TCP/IP是实际实现。做驱动开发,重点掌握TCP/IP模型就够了。
我在项目中遇到过一个问题:有个同事把UDP当成可靠传输来用,结果丢包了还一脸懵。这就是没搞懂传输层协议的特性。TCP面向连接、可靠传输,UDP无连接、速度快但不可靠。你想想看,视频通话用UDP没问题,但文件传输用UDP就得自己加确认机制了。
1.2 嵌入式网络硬件概述
接下来聊聊硬件。嵌入式网络硬件,核心就是MAC和PHY这两个芯片。
MAC(媒体访问控制层)
MAC负责数据帧的封装/解封装、地址寻址、差错检测。说白了,它管的是「怎么把数据打包成帧」以及「这个帧该发给谁」。在嵌入式SoC里,MAC通常集成在芯片内部,比如STM32、i.MX系列都自带MAC控制器。
PHY(物理层)
PHY负责把数字信号转换成模拟信号,通过网线发出去。它管的是「怎么在物理介质上传输比特流」。PHY芯片通常是独立的,比如常用的LAN8720、DP83848等。
个人经验:我刚开始做项目时,以为MAC和PHY是同一个芯片。后来发现很多SoC只集成了MAC,需要外接PHY芯片。选型时一定要注意看芯片手册,别买错了。
MII与RMII接口
MAC和PHY之间怎么通信?靠的就是MII或RMII接口。
| 接口类型 | 引脚数 | 时钟频率 | 数据宽度 |
|---|---|---|---|
| MII | 16根 | 25MHz | 4位 |
| RMII | 9根 | 50MHz | 2位 |
MII接口引脚多,但时序简单。RMII引脚少,适合引脚紧张的嵌入式设计。我建议新手优先用RMII,省引脚、布线也方便。不过要注意,RMII需要外部提供50MHz时钟,有些PHY芯片内部可以生成,有些需要外部晶振。
避坑指南:我曾经在一个项目里,RMII的时钟没接对,结果PHY死活不工作。查了两天才发现是时钟源配置错了。所以,硬件设计时一定要仔细核对PHY芯片的时钟要求。
1.3 Linux网络子系统架构概览
好了,硬件说完了,咱们看看软件层面。Linux网络子系统,说白了就是一套从应用层到硬件层的完整数据通路。
它的架构大致分四层:
- 系统调用接口层:用户程序通过socket、bind、send等函数发起网络操作
- 协议栈层:处理TCP、UDP、IP等协议,完成数据封装和解封装
- 网络设备层:统一管理网络设备,提供注册、打开、发送、接收等接口
- 设备驱动层:直接操作硬件寄存器,完成数据收发
你想想看,当你在应用层调用send()发送数据时,数据是怎么一路跑到网线上的?大致流程是:应用数据→socket层→TCP/UDP协议→IP协议→网络设备层→驱动层→PHY芯片→网线。
反过来,接收数据时:网线→PHY芯片→MAC控制器→驱动层→网络设备层→IP协议→TCP/UDP协议→socket层→应用层。
嗯,这里要注意,驱动开发主要关注的是网络设备层和驱动层。协议栈层虽然复杂,但Linux内核已经帮我们实现了,一般不需要修改。
核心要点:驱动开发的核心工作就是实现net_device_ops结构体中的操作函数,包括open、stop、start_xmit、get_stats等。说白了,就是告诉内核「我的网卡怎么打开、怎么关闭、怎么发数据、怎么收数据」。
我个人习惯在开始写驱动前,先画一张架构图,把数据流和关键数据结构理清楚。这样写代码时思路清晰,不容易出错。
这张图把Linux网络子系统的四层架构和它们之间的关系展示得很清楚。从应用层到硬件层,数据一路向下,每一层都有明确的职责。做驱动开发,你主要跟网络设备层和设备驱动层打交道。
小技巧:刚开始接触网络驱动时,可以先从简单的虚拟网卡驱动入手,比如内核自带的loopback驱动。它不涉及真实硬件,但能帮你理解net_device的注册、数据收发流程。我当年就是这么入门的。
好了,这一章的内容就到这里。记住,网络驱动开发的核心就是理解数据怎么从应用层跑到硬件上,以及反过来怎么从硬件收回来。搞清楚了这条数据通路,后面的代码实现就水到渠成了。
公众号:蓝海资料掘金营,微信deep3321