当前位置: 首页 > article >正文

嵌入式系统 第十三讲 网络设备驱动程序开发

• 网络设备是Linux三大设备之一(另外两类是字符设备,块 设备)。

• 由于网络设备的特殊工作方式,网络驱动程序的开发与字 符设备、块设备驱动的开发有很大的不同。

• 13.1 以太网基础知识

• 以太网(Ethernet):最早由Xerox(施乐)公司创建,于1980年DEC、 lntel和Xerox三家公司联合开发成为一个标准。

• 以太网是应用最为广泛的局域网,包括标准的以太网(10Mbit/s)、 快速以太网(100Mbit/s)和10G(10Gbit/s)以太网,采用的是 CSMA/CD访问控制法,它们都符合IEEE 802.3标准。

CSMA/CD(Carrier Sense Multiple Access/Collision Detection,带有冲突检测的载波 侦听多路存取)是IEEE 802.3使用的一种媒体访问控制方法。

– IEEE 802.3标准:规定了包括物理层的连线、电信号和介质访问层协议的内容。

• 1、早期的以太网

– 1Base-5:使用双绞线电缆,最大网段长度为500m,传输速度为1Mbps。

• 2、10Mb/s以太网

– 10Base-T:使用双绞线电缆,最大网段长度为100m。拓扑结构为星型;10Base-T组网主要硬件设备有:3类或5类非屏蔽双绞线、带有RJ-45插口的以太网卡、 集线器、交换机、RJ-45插头等。

• 3、快速以太网

– 100BASE-TX:是一种使用5类数据级无屏蔽双绞线或屏蔽双绞线的快速以太网技 术。它使用两对双绞线,一对用于发送,一对用于接收数据。

• 4、千兆以太网

– 1000Base-T:带宽1Gb/s,使用超5类双绞线或6类双绞线。

• 5、万兆以太网

– 10GBASE-SR 和10GBASE-SW:主要支持短波(850 nm)多模光纤(MMF),光纤 距离为2m 到300 m。

• 6、4万兆以太网和10万兆以太网

– 标准尚在起草中,尚未发布。

• 13.1.1 CSMA/CD协议

– CSMA/CD(Carrier Sense Multiple Access/Collision Detection,带有冲突检 测的载波侦听多路存取)是IEEE 802.3使用的一种媒体访问控制方法。从 逻辑上可以划分为两大部分:数据链路层的媒体访问控制子层(MAC) 和物理层。它严格对应于ISO开放系统互连模式的最低两层。LLC子层和 MAC子层在一起完成OSI模式的数据链路层的功能。

• CS:载波侦听,Carrier Sense

• MA:多点接入(多路存取),Multiple Access

• CD:冲突检测,Collision Detection

– CSMA/CD的基本原理是:所有节点都共享网络传输信道,节点在发送数 据之前,首先检测信道是否空闲,如果信道空闲则发送,否则就等待; 在发送出信息后,再对冲突进行检测,当发现冲突时,则取消发送。

– CSMA/CD协议的侦听发送策略有三种: ① 非坚持CSMA ② 1-坚持CSMA ③ p-坚持CSMA

– CSMA/CD的控制规程主要包括以下四个处理内容: ① 侦听 ② 数据发送 ③ 冲突检测 ④ 冲突处理

• 13.1.2 以太网帧结构

– 以太网帧结构(帧格式),即在以太网帧头、帧尾中用于实现以 太网功能的域。在以太网的帧头和帧尾中有几个用于实现以太网 功能的域,每个域也称为字段,有其特定的名称和目的。

① Ethernet V2:ARPA,由DEC,Intel和Xerox在1982年公布其标准。

② Ethernet 802.3 RAW:这是1983年Novell发布其划时代的Netware/86 网络套件时采用的私有以太网帧格式。

③ Ethernet 802.3/802.2 SNAP:这是IEEE为保证在802.2 LLC上支持更多 的上层协议同时更好的支持IP协议而发布的标准。

• 13.1.3 嵌入式系统中常用的网络协议

– ARP:地址解析协议,Address Resolution Protocol,是根据IP地址获取物 理地址的一个TCP/IP协议。

– RARP:反向地址转换协议,Reverse Address Resolution Protocol,允许局 域网的物理机器从网关服务器的ARP 表或者缓存上请求其IP 地址。

– IP:网际协议,Internet Protocol,网际协议也就是为计算机网络相互连 接进行通信而设计的协议。

– ICMP:Internet Control Message Protocol,互联网控制消息协议。它是 TCP/IP协议族的一个子协议,用于在IP主机、路由器之间传递控制消息。

– TCP:Transmission Control Protocol,传输控制协议。是一种面向连接 (连接导向)的、可靠的、基于字节流的运输层(Transport layer)通信 协议,由IETF的RFC 793说明(specified)。

– UDP :User Datagram Protocol,用户数据报协议,是OSI(Open System Interconnection,开放式系统互联)参考模型中一种无连接的传输层协议, 提供面向事务的简单不可靠信息传送服务,IETF RFC 768是UDP的正式规 范。

– FTP:File Transfer Protocol,文件传输协议。是TCP/IP 协议组中的协议之 一。FTP协议包括两个组成部分,其一为FTP服务器,其二为FTP客户端。

– TFTP:Trivial File Transfer Protocol,简单文件传输协议。是TCP/IP协议族 中的一个用来在客户机与服务器之间进行简单文件传输的协议,提供不 复杂、开销不大的文件传输服务,端口号为69。

• 13.2 嵌入式网络设备驱动开发概述

• 1、硬件描述

以太网对应于ISO网络分层中的数据链路层和物理层

 – 使用嵌入式以太网接口的两种方式:

嵌入式处理器集成MAC控制器,但是不集成物理层接收器 (PHY),此时需要外接PHY芯片,如RTL8201BL、VT6103等芯 片。

② 嵌入式处理器既不集成MAC控制器,又不集成物理层接收器 (PHY),此时需要外接同时具有MAC控制器和PHY接收器的芯 片,如DM9000、CS8900、SIS900等芯片。

• 2、驱动框架

– 在/dev目录下没有对应的设备文件

– 对网络设备的访问必须使用套接字(Socket),而非读写设备文件。

• 13.3 网络设备驱动基本数据结构

struct net_device(网络设备结构体):包含具体网络设 备的各种信息和操作接口

struct sk_buff(套接字缓冲结构体:是Linux网络子系统 的核心,在Linux网络子系统各层协议中的数据传递实际 上传递的是struct sk_buff结构,它为各层之间的数据交换 单元提供了统一的定义。

• 13.3.1 struct net_device数据结构

struct net_device(网络设备结构体)

– 1、全局信息

网络设备的名称

– char  name[IFNAMSIZ];

设备初始化函数指针

– int (*init)(struct net_device *dev);

– 2、硬件信息

• 设备使用的共享内存起始地址

– unsigned long mem_end;

• 设备使用的共享内存的终止地址

– unsigned long mem_start;

• 设备I/O基址

– unsigned long base_addr;

• 设备中断号

– unsigned int irq;

• 指定多端口设备使用哪个端口

– unsigned char if_port;

• 保存分配给设备DMA通道

– unsigned char dma;

• 设备状态

– unsigned long state;

– 3、接口信息

• 保存最大传输单元大小

– unsigned mtu;

接口类型

– unsigned short type;

• 硬件长度

– unsigned short hard_header_len;

• 存放设备硬件地址MAC地址)

– unsigned char dev_addr[MAX_ADDR_LEN];

• 存放广播地址

– unsigned char broadcast[MAX_ADDR_LEN];

• 接口标志

– unsigned short flags;

– 4、设备操作函数

• 打开接口

– int(*open)(struct net_device *dev);

• 关闭接口

– int(*stop)(struct net_device *dev);

• 启动数据包的发送

– int (*hard_start_xmit) (struct sk_buff *skb, struct net_device *dev);

• 设置设备的组播列表

– void (*set_multicast_list)(struct net_device *dev);

• 设置设备的MAC地址

– int(*set_mac_address)(struct net_device *dev, void *addr);

• 执行接口特有的I/O控制命令

– int(*do_ioctl)(struct net_device *dev, struct ifreq *ifr, int cmd);

• 改变接口的配置

– int (*set_config)(struct net_device *dev, struct ifmap *map);

• 在接口的MTU改变时,采取相应的设置

– int (*change_mtu)(struct net_device *dev, int new_mtu);

• 如果数据包传送超时,则调用该函数解决问题并重新发送数据

– void (*tx_timeout) (struct net_device *dev);

• 用于返回设备状态信息

– struct net_device_stats* (*get_stats)(struct net_device *dev);

• 在禁止中断的情况下,要求驱动程序检测接口下的事件

– viod(*poll_controller)(struct net_devices *dev)

– 5、工具成员

• 记录数据最后一次接收到数据包的时间戳

– unsigned long last_rx;

• 记录数据开始发送时的时间戳

– unsigned long trans_start;

• 在网络层驱动传输已超时,并调用tx_timout之前的最小时间

– intwatchdog_timeo

• 13.3.2 struct sk_buff数据结构

struct sk_buff套接字缓冲结构体

– 1、网络协议头

• sk_buff_data_t        transport_header;

• sk_buff_data_t        network_header;

• sk_buff_data_t        mac_header;

– 2、缓冲区指针

• sk_buff_data_t        tail;

• sk_buff_data_t        end;

• unsigned char        *head, *data;

– 3、操作函数

• static inline struct sk_buff *alloc_skb(unsigned int size, gfp_t priority);

• static inline struct sk_buff *dev_alloc_skb(unsigned int length);

• void kfree_skb(struct sk_buff *skb);

• void kfree_skb(struct sk_buff *skb);

• void dev_kfree_skb(struct sk_buff *skb);

• void dev_kfree_skb_irq(struct sk_buff *skb);

• void dev_kfree_skb_any(struct sk_buff *skb);

• unsigned char *skb_put(structsk_buff *skb, unsigned int len);

• unsigned char *__skb_put(struct sk_buff *skb, unsigned int len);

• unsigned char *skb_push(struct sk_buff *skb, unsigned int len);

• unsigned char *__skb_push(struct sk_buff *skb, unsigned int len);

• int skb_tailroom(const struct sk_buff *skb);

• unsigned int skb_headroom(const struct sk_buff *skb)

• void skb_reserve(struct sk_buff *skb, int len);

• char *skb_pull_rcsum(struct sk_buff *skb, unsigned int len);

• 13.4 网络设备初始化

• 网络设备初始化由struct net_device数据结构的init函数指针指向的函 数完成:

– int (*init)(struct net_device *dev);

• 初始化工作包括以下几个方面的任务:

        ① 检测网络设备的硬件特征,检查物理设备是否存在

        ② 如果检测到网络设备存在,则进行资源配置

        ③ 对struct net_device成员变量进行赋值

• 13.5 打开和关闭接口

• 打开接口的工作由struct net_device数据结构的open函数指针指向的函数完成:

– int (*open)(struct net_device *dev);

• 该函数负责的工作包括请求系统资源,如申请I/O区域DMA通道及中断等资 源,并告知接口开始工作,调用netif_start_queue函数激活网络设备发送队列

– void netif_start_queue(struct net_device *dev); 打开队列

• 关闭接口的工作由struct net_device数据结构的stop函数指针指向的函数完成:

– int (*stop)(struct net_device *dev);

• 该函数需要调用netif_stop_queue函数停止数据包传送:

– void netif_stop_queue(struct net_device *dev); 停止队列

• 13.6 数据接收与发送

• 1、数据发送

– 数据在实际发送的时候会调用struct net_device数据结构的 hard_start_transmit函数指针指向的函数,该函数会将要发送的数据放入 外发队列,并启动数据包发送

• 2、并发控制

– 发送函数可利用struct net_device数据结构的xmit_lock自旋锁来保护临界 区资源

• 3、传输超时

– 驱动程序需要处理超时带来的问题,调用struct net_device数据结构的 tx_timeout函数,并调用netif_wake_queue函数重启设备发送队列

• 4、数据接收

– 在Linux中有两种方式实现数据接收:

• 第一种是中断方式:调用netif_rx函数实现数据接收

• 第二种是轮询方式:调用netif_receive_skb函数实现数据接收。

• 13.7 查询状态与参数设置

• 1、链路状态

– 驱动程序需要掌握当前链路的状态,当链路状态改变时,驱动程序需要 通知内核

• void netif_carrier_off(struct net_device *dev);

• void netif_carrier_on(struct net_device *dev);

• int netif_carrier_ok(const struct net_device *dev);

• 2、设备状态

– 驱动程序的get_stats()函数用于向用户返回设备的状态和统计信息,这些 信息保存在struct net_device_stats结构体中。

 • 3、设置MAC地址

– 调用set_mac_address函数,设置新的MAC地址。

• 4、接口参数设置

• 调用set_config函数,设置I/O地址、中断等信息。

• 13.8 AT91SAM9G45网卡驱动

• 13.8.1 EMAC模块简介

– AT91SAM9G45:嵌入式微处理器

– AT91SAM9G45的EMAC模块是一个完全兼容IEEE 802.3标准的10/100M的以 太网控制器,它包含一个地址检查模块统计和控制寄存器组接收和 发送模块,以及一个DMA接口

• 13.8.2 模块图

 • 13.8.3 功能描述

– 1、时钟

• 系统总线时钟

• 发送时钟

• 接收时钟

– 2、内存接口

• 帧数据在内存和EMAC之间的传输是通过DMA接口实现的。

– 3、接收模块

• 接收模块检查以太网帧的前导帧、FCS、对齐和长度

– 4、发送模块

• 发送模块从DMA接口获取数据,填充前导帧、FCS等字段

• 13.8.4 寄存器描述

– 1、网络控制寄存器(NCR)

– 2、网络配置寄存器(NCFG)

– 3、网络状态寄存器(NSR)

– 4、发送状态寄存器(TSR)

– 5、接收缓冲队列指针寄存器(RBQP)

– 6、发送缓冲队列指针寄存器(TBQP)

– 7、接收状态寄存器(RSR)

– 8、中断状态寄存器(ISR)

• 13.8.5 AT91SAM9G45芯片EMAC控制器驱动 分析

– 1、设备侦测

• 设备侦测主要完成各种资源的初始化工作:

        ① 获取I/O内存的地址,并进行I/O重定向

        ② 获取设备中断号注册中断处理程序

        ③ 初始化net_device结构,并注册该结构

        ④ 初始化时钟,并设置分频器

– 2、设备打开与关闭

• 设备打开时主要完成以下任务:

        ① 分配DMA缓冲区初始化缓冲区;

        ② 初始化硬件

        ③ 打开PHY(物理层)

        ④ 通知上层开启传输

– 3、数据的接收

– 4、数据的发送

 

 

– 5、中断处理

 


http://www.kler.cn/a/457735.html

相关文章:

  • 人工智能(AI)简史:推动新时代的科技力量
  • Java List 集合详解:基础用法、常见实现类与高频面试题解析
  • 一文理解条件竞争漏洞
  • 基于 Python Django 的花卉商城系统的研究与实现
  • 通过Cephadm工具搭建Ceph分布式存储以及通过文件系统形式进行挂载的步骤
  • Unity3D 网络框架设计详解
  • 自动驾驶3D目标检测综述(六)
  • Qt仿音乐播放器:绘画、图片
  • 43243242342
  • 本机实现Llama 7B推理及部署
  • Flume其二,自定义拦截器、选择器、自动容灾、负载均衡
  • 回顾2024加密市场的“得与失”,2025路在何方?
  • HTML 元素:网页构建的基础
  • Lecture 17
  • 概率统计与随机过程--作业5
  • 20. 【.NET 8 实战--孢子记账--从单体到微服务】--简易权限--补充--自动添加接口地址
  • 什么是网络安全等级保护?
  • 机器学习算法基础知识1:决策树
  • python+panddleocr+文本方向分类训练导出测试
  • C++中如何引用别的文件中定义的结构体数组变量
  • 如何做一份出色的PPT?
  • 餐饮收户人另类增长点
  • 2025年创业投资前瞻:AI、可持续发展与基础设施建设的深度整合
  • 被邀请出版Cursor教程书籍是什么体验?
  • 19.springcloud_openfeign之案例
  • JVM实战—4.JVM垃圾回收器的原理和调优