TFTP协议在嵌入式系统中的实现
如果从MAC层收到一个以太网帧,先把收到的以太网帧转变为相应的帧结构再去掉其以太网侦头部, 其中skb_pop(skb, ETH_HLEN)把数据指针往后移动ETH_HLEN个字节,而且真正的数据长度也做相应的变化..然后根据帧中的协议字段判断其上层为什么协议.这里帧格式采用的是RFC894,如果其上层为arp协议,将去掉以太网头部的数据交由ARP处理,同样如果其上层协议为IP,也做类似的处理. arp_rcv_packet(skb)只处理的ARP请求消息,如果发现其为ARP请求,则发送ARP应答. 接下来就是把这个ARP应答包发出去,发送了ARP应答后把刚才请求的者的MAC地址和其IP保存在本机中,其实现采用了简单循环区,利用数组.首先检查缓冲区中有无此项,如果有则直接用该项的索引,如果没有则重新分配索引, 把传进来的MAC 和IP 赋给新分配的索引 i,。 如果MAC层发现收到的包上层协议为IP,则执行[1]: 首先检查接受者是不是本机IP,通过检查后,去掉IP头部,再检查其上层协议类型,如果为UDP,则将包转交给上层的UDP协议处理其中udp_rcv_packet(skb)先去掉UDP头部,再检查其对应的上层协议,这里只实现了TFTP协议,对应语句为skb_pop(skb, sizeof(struct udphdr)); 其中tftp_rcv_packet(skb)根据TFTP头部中操作类型而采取不同的动作.对应代码为: 其中tftp_rcv_wrq(skb)先得到请求者的IP和PORT,再发送块编号为0的ACK包.然后为数据传输做些初始化工作,具体为设置接受缓冲区和接受数据长度。:因为TFTP是包装在UDP里面的,所以首先欲留出UDP头部的空间,这里要注意的是在UDP层除了为自己留空间外其又会欲留出IP头的空间,而在IP层除了为自己留空间外其又会欲留出MAC头的空间.如此便留出了整个协议栈所要求的头部空间.调用关系为 然后该函数按照ACK包的格式(在TCP/IP祥解 I 协议>160)赋相应的值.最后将此包交由下层的UDP协议处理.那么此时UDP层是怎么处理的呢?udp_send(skb, client_ip, TFTP, client_port);和TFTP层处理有些类似,先加入自己的头部信息并赋相应的值.然后再交由下层处理, 在IP层其处理的思路也大致差不多,其中ip_send(skb, ip, UDP)定义在ip/_ip.c.其先查看ARP缓冲区中有无此项,如无则返回错误.对应代码为,然后先加入自己的头部信息并赋相应的值.然后再交由下层处理。 tftp_rcv_data(skb)首先判断接受到的包的目的IP和PORT是不是本机的TFTP协议,通过判断后,再看接受到的包的确认序列号是不是和本机TFTP要求的一致,即看是不是发生了丢包.如果没有则当前接受到的包有效,存入缓冲区,并发送确认序号对应代码为: 5.结束语 本文对S3C44B0X+RTL8019开发,实现了系统通过网络与PC机通信,充分满足嵌入式小系统网络通信需要,改善了了一般嵌入式系统通过串口通信速度慢、可靠性低的弊端。并且适当调整程序,可实现基于UDP的其它上层协议。
if(ntohs(eth_hdr->h_proto) == ETH_P_IP)
ip_rcv_packet(skb);
if (ntohs(udp_hdr->dest) == TFTP)
tftp_rcv_packet(skb);
switch (ntohs(tftp_hdr->th_opcode)) {
/* 只处理写请求和DATA */
case WRQ:
tftp_rcv_wrq(skb); break;
case DATA:
tftp_rcv_data(skb); break;
…}
udp_skb_reserve(skb)—ip_skb_reserve(skb)—eth_skb_reserve(skb);
if (client_block == ntohs(tftp_hdr->th_block)) {
/* 接受一个数据分组 */
len = skb->len - sizeof(struct tftphdr);
memcpy(buf + data_len, tftp_hdr->th_data, len);
data_len += len;
tftp_send_ack(tftp_hdr, client_block);
client_block++;
…
如果当前接受到的数据小于512字节,则说明传送完毕,但是当发生丢包时,就要求对方重传.采用的机制很简单,就是要求重传确认序号小的分组。
- Linux嵌入式系统开发平台选型探讨(11-09)
- 嵌入式系统中文输入法的设计(03-02)
- 基于MPC755的嵌入式计算机系统设计(05-10)
- WinCE下光电编码器的驱动程序设计(04-12)
- 为什么嵌入式开发人员要使用FPGA(05-13)
- VxWorks几种常用的延时方法介绍(05-16)