嵌入式Linux系统高级开发工程师.ppt

上传人:小飞机 文档编号:4975369 上传时间:2023-05-27 格式:PPT 页数:35 大小:288.11KB
返回 下载 相关 举报
嵌入式Linux系统高级开发工程师.ppt_第1页
第1页 / 共35页
嵌入式Linux系统高级开发工程师.ppt_第2页
第2页 / 共35页
嵌入式Linux系统高级开发工程师.ppt_第3页
第3页 / 共35页
嵌入式Linux系统高级开发工程师.ppt_第4页
第4页 / 共35页
嵌入式Linux系统高级开发工程师.ppt_第5页
第5页 / 共35页
点击查看更多>>
资源描述

《嵌入式Linux系统高级开发工程师.ppt》由会员分享,可在线阅读,更多相关《嵌入式Linux系统高级开发工程师.ppt(35页珍藏版)》请在三一办公上搜索。

1、嵌入式Linux系统高级开发讲义,第四天 日程,嵌入式Linux网络子系统分析 嵌入式Linux网卡驱动编写实例,日程安排,嵌入式Linux网络子系统分析,ISO/OSI七层协议模型,TCP/IP协议族,TCP(Transmission Control Protocol)传输控制协议,基于连接的服务UDP(User Datagram Protocol)用户数据报协议,无连接的服务IP(Internet Protocol)Internet协议,信息传递机制,OSI模型与TCP/IP协议的对比,TCP或UDP,IP和路由,网卡驱动,TelnetFTPWWW等,消息包的逐层递增,Linux网络协议栈

2、分层,系统调用接口层协议无关的接口层,就是SOCKET层。(屏蔽底层的不同协议,以便与系统调用层之间的接口可以简单,统一)网络协议实现层(IP,ICMP,ARP,RARP,TCP,UDP等)与具体设备无关的驱动接口层驱动程序层,日程安排,嵌入式Linux网卡驱动编写网络设备驱动程序简介device数据结构sk_buff数据结构内核的驱动程序接口以太网控制器,sk_buff结构,一个sk_buff代表着一个网络报文。既包含报文的数据,也包含报文的控制信息。struct sk_buff struct net_device*dev;/接收和发送sk_buff的设备 union h;/h,nh,mac

3、等指向sk_buff中各层报文头 unsigned char*head,*data,*tail,*end;/head和tail指向已分配空间的开头和结尾,data和tail分别是有效数据的开头与结尾。,sk_buff分配与释放,分配:struct sk_buff*alloc_skb(unsigned int size,int gfp_mask)克隆:struct sk_buff*skb_clone(struct sk_buff*skb,int gfp_mask)释放:void kfree_skb(struct sk_buff*skb),sk_buff的操作函数,在sk_buff缓冲区的尾部添加

4、数据。unsigned char*skb_put(struct sk_buff*skb,unsigned int len)在sk_buff缓冲区的头部添加数据。unsigned char*skb_push(struct sk_buff*skb,unsigned int len)在填充sk_buff缓冲区前保留报文头空间。void skb_reserve(struct sk_buff*skb,unsigned int len)从数据包头中删除数据。如剥离报文硬件头部。unsigned char*skb_pull(struct sk_buff*skb,int len),编写网络驱动程序,发送和接收

5、 这是一个网络设备最基本的功能如一块网卡所做的无非就是收发工作。所以驱动程序里要告诉系统发送函数在哪里,系统在有数据要发送时就会调用发送程序。驱动程序由于是直接操纵硬件的,所以网络硬件有数据收到,最先能得到这个数据的也就是驱动程序,它负责把这些原始数据进行必要的处理,然后送给系统。这里,操作系统必须要提供两个机制:找到驱动程序的发送函数驱动程序把收到的数据送给系统,net_device结构成员,一个net_device,表示一个网络设备。struct net_devicechar nameIFNAMSIZE;/设备名称 ulong base_addr;/网络接口的I/O基地址 uchar ir

6、q;/中断号 ushort hard_header_len;/硬件头的长度(14)char addr_len;/MAC地址长度 char dev_addr/设备的硬件MAC地址 ushort flags;/接口标志。可以设置网络设备为混杂模式,组播模式,回环设备,UP状态标志,不执行ARP等等。网络设备的各种操作方法,net_device常用方法成员,初始化:int(*init)(struct net_device*dev)打开接口:int(*open)(struct net_device*);停止接口:int(*stop)(struct net_device*);数据发送:int(*hard

7、_start_xmit)(struct sk_buff*skb,struct net_device*);建立硬件头:int(*hard_header)(.)获取统计信息:,网络设备驱动注册,分配net_device:struct net_device*alloc_netdev(int sizeof_priv,char*name,void(*setup)(struct net_device*);net_device初始化给net_device结构的成员赋值注册net_device:register_netdev(struct net_device*),网络驱动程序的-初始化(init),驱动程序

8、必须有一个初始化方法在把驱动程序载入系统的时候会调用这个初始化程序。它做以下几方面的工作:检测设备:在初始化程序里你可以根据硬件的特征检查硬件是否存在,然后决定是否启动这个驱动程序。配置和初始化硬件:在初始化程序里可以完成对硬件资源的配置,比如即插即用的硬件就可以在这个时候进行配置(Linux内核对PnP功能没有很好的支持,可以在驱动程序里完成这个功能)。配置或协商好硬件占用的资源以后,就可以向系统申请这些资源。有些资源是可以和别的设备共享的,如中断。有些是不能共享的,如IO、DMA。初始化device结构中的变量让硬件正式开始工作,网络驱动程序打开,打开(open)open这个方法在网络设备

9、驱动程序里是在网络设备被激活的时候被调用(即设备状态由down-up)实际上很多在initialize中的工作可以放到这里来做。比如资源的申请、硬件的激活。如果dev-open返回非0(error),则硬件的状态还是down open方法另一个作用是如果驱动程序做为一个模块被装入,则要防止模块卸载时设备处于打开状态。使能队列netif_start_queue(dev);,网络驱动程序关闭,关闭(stop)close方法做和open相反的工作。可以释放某些资源以减少系统负担。close是在设备状态由up转为down时被调用的close方法必须返回成功(0=success)禁止队列netif_st

10、op_queue(dev);,网络驱动程序发送,发送(hard_start_xmit)所有的网络设备驱动程序都必须有这个发送方法。在系统调用驱动程序的xmit时,发送的数据放在一个sk_buff结构中。一般的驱动程序把数据传给硬件发出去。也有一些特殊的设备比如loopback把数据组成一个接收数据再回送给系统,或者 dummy设备直接丢弃数据。如果发送成功,hard_start_xmit方法里释放sk_buff,返回0(发送成功)如果设备暂时无法处理,比如硬件忙,则返回1。这时如果dev-tbusy置为非0,则系统认为硬件忙,要等到dev-tbusy置0以后才会再次发送。tbusy的置0任务一

11、般由中断完成。,网络驱动程序发送(续),硬件在发送结束后产生中断,这时可以把tbusy置0,然后用mark_bh()调用通知系统可以再次发送。在发送不成功的情况下,也可以不置dev-tbusy为非0,这样系统会不断尝试重发。如果hard_start_xmit发送不成功,则不要释放sk_buff。传送下来的sk_buff中的数据已经包含硬件需要的帧头。所以在发送方法里不需要再填充硬件帧头,数据可以直接提交给硬件发送。sk_buff是被锁住的(locked),确保其他程序不会存取它。,网络驱动程序接收,接收(reception)驱动程序并不存在一个接收方法。有数据收到应该是驱动程序来通知系统的。一

12、般设备收到数据后都会产生一个中断,在中断处理程序中驱动程序申请一块sk_buff(skb),从硬件读出数据放置到申请好的缓冲区里。接下来填充sk_buff中的一些信息。skb-dev=dev,判断收到帧的协议类型,填入skb-protocol(多协 议的支持)。把指针skb-mac.raw指向硬件数据然后丢弃硬件帧头(skb_pull)。,网络驱动程序接收(续),还要 设置skb-pkt_type,标明第二层(链路层)数据类型。可以是以下类型:PACKET_BROADCAST:链路层广播 PACKET_MULTICAST:链路层组播 PACKET_SELF:发给自己的帧 PACKET_OTHE

13、RHOST:发给别人的帧(监听模式时会有这种帧)最后调用netif_rx()把数据传送给协议层。netif_rx()里数据放入处理队列然后返回,真正的处理是在中断返回以后,这样可以减少中断时间。调用netif_rx()以后,驱动程序就不能再存取数据缓冲区skb。,网络驱动程序硬件帧头,硬件一般都会在上层数据发送之前加上自己的硬件帧头,比如以太网(Ethernet)就有14字节的帧头。这个帧头是加在上层ip、ipx等数据包的前面的。驱动程序提供一个hard_header方法,协议层(ip、ipx、arp等)在发送数据之前会调用这段程序。硬件帧头的长度必须填在dev-hard_header_len

14、,这样协议层回在数据之前保留好硬件帧头的空间。这样hard_header程序只要调用skb_push然后正确填入硬件帧头就可以了。,网络驱动程序硬件帧头(续1),在协议层调用hard_header时,传送的参数包括:数据的sk_buff device指针Protocol目的地址(daddr)源地址(saddr)数据长度(len)数据长度不要使用sk_buff中的参数,因为调用hard_header时数据可能还没完全组织好 saddr是NULL的话是使用缺省地址(default)daddr是NULL表明协议层不知道硬件目的地址如果hard_header完全填好了硬件帧头,则返回添加的字节数。,网

15、络驱动程序的基本方法地址解析,地址解析(xarp)有些网络有硬件地址(比如Ethernet),并且在发送硬件帧时需要知道目的硬件地址。这样就需要上层协议地址(ip、ipx)和硬件地址的对应。这个对应是通过地址 解析完成的。需要做arp的的设备在发送之前会调用驱动程序的rebuild_header方法。调用的主要参数包括:指向硬件帧头的指针协议层地址如果驱动程序能够解析硬件地址,就返回1,如果不能,返回0。对rebuild_header的调用在net/core/dev.c的do_dev_queue_xmit()里。,网络驱动程序参数设置和统计数据,参数设置和统计数据 在驱动程序里还提供一些方法供

16、系统对设备的参数进行设置和读取信息。一般只有超级用户(root)权限才能对设备参数进行设置。设置方法有:dev-set_mac_address()当用户调用ioctl类型为SIOCSIFHWADDR时是要设置这个设备的mac地址。一般对mac地址的设置没有太大意义的。,网络驱动程序参数设置和统计数据(续),dev-set_config()当用户调用ioctl时类型为SIOCSIFMAP时,系统会调用驱动程序的set_config方法。用户会传递一个ifmap结构包含需要的I/O、中断等参数。除次之外驱动程序还可以提供一个dev-get_stats方法,返回一个enet_statistics结构

17、,包含发送接收的统计信息。ioctl的处理在net/core/dev.c的dev_ioctl()和dev_ifsioc()里,硬件发送忙时的处理,主CPU的处理能力一般比网络发送要快,所以经常会遇到系统有数据要发,但上一包数据网络设备还没发送完。因为在Linux里网络设备驱动程序一般不做数据缓存,不能发送的数据都是通知系统发送不成功,所以必须要有一个机制在硬件不忙时及时通知系统接着发送下面的数据。一般对发送忙的处理在前面设备的发送方法(hard_start_xmit)里已经描述过,即如果发送忙,置tbusy为1。处理完发送数据后,在发送结束中断里清tbusy,同时用mark_bh()调用通知系

18、统继续发送。但在具体实现驱动程序时发现,这样的处理系统好象并不能及时地知道硬件已经空闲了,即在mark_bh()以后,系统要等一段时间才会接着发送。造成发送效率很低。实现时不把tbusy置1,让系统始终认为硬件空闲,但是报告发送不成功。系统会一直尝试重发。这样处理就运行正常了。,流量控制,网络数据的发送和接收都需要流量控制。这些控制是在系统里实现的,不需要驱动程序做工作。每个设备数据结构里都有一个参数dev-tx_queue_len,这个参数 标明发送时最多缓存的数据包。在Linux系统里以太网设备(10/100Mbps)tx_queue_len一般设置为100,串行线路(异步串口)为10。实

19、际上,设置了dev-tx_queue_len并不是为缓存这些数据申请了空间。这个参数只是在收到协议层的数据包时判断发送队列里的数据是不是到了tx_queue_len的限度,以决定这一包数据加不加进发送队列。发送时另一个方面的流控是更高层协议的发送窗口(TCP协议里就有发送窗口)。达到了窗口大小,高层协议就不会再发送数据。接收流控也分两个层次。netif_rx()缓存的数据包有限制。另外高层协议也会有一个最大的等待处理的数据量。发送和接收流控处理在net/core/dev.c的do_dev_queue_xmit()和netif_rx()中,日程,分析CS8900驱动程序,CS8900的硬件扩展,

20、CS8900与CPU的扩展参见硬件原理图,CS8900的地址信息,基地址中断号,CS8900的操作方法,写地址,再读/写数据static inline u16 cs8900_read(struct net_device*dev,u16 reg)outw(reg,dev-base_addr+PP_Address);return(inw(dev-base_addr+PP_Data);static inline void cs8900_write(struct net_device*dev,u16 reg,u16 value)outw(reg,dev-base_addr+PP_Address);outw(value,dev-base_addr+PP_Data);,CS8900的代码分析,参见源代码 driver/net/cs8900/cs8900.c模块初始化打开设备发送数据接收数据其它,

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 生活休闲 > 在线阅读


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号