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网络子系统架构图 应用层(socket/bind/send/recv) 协议栈层(TCP/UDP/IP) 网络设备层(net_device/ops) 设备驱动层(硬件操作/中断处理) 用户空间 内核空间 硬件层

这张图把Linux网络子系统的四层架构和它们之间的关系展示得很清楚。从应用层到硬件层,数据一路向下,每一层都有明确的职责。做驱动开发,你主要跟网络设备层和设备驱动层打交道。

小技巧:刚开始接触网络驱动时,可以先从简单的虚拟网卡驱动入手,比如内核自带的loopback驱动。它不涉及真实硬件,但能帮你理解net_device的注册、数据收发流程。我当年就是这么入门的。

好了,这一章的内容就到这里。记住,网络驱动开发的核心就是理解数据怎么从应用层跑到硬件上,以及反过来怎么从硬件收回来。搞清楚了这条数据通路,后面的代码实现就水到渠成了。


公众号:蓝海资料掘金营,微信deep3321