可以了解并学习Uboot的tftp流程

嵌入式技术

1368人已加入

描述

int tftp_download(char *filename, ulong msec_max, int cnt_max, ulong addr)

{

...

TftpRRQTimeoutMSecs = msec_max;   //100

TftpRRQTimeoutCountMax = cnt_max;  //0

setenv("netretry", "no");

load_addr = addr;             //下载到内存的地址

copy_filename(BootFile, filename, sizeof(BootFile));

size = NetLoop(TFTP);

if(size < 0)

return ERROR;

else

flush_cache(addr,size);

...

}

int NetLoop(proto_t protocol)

{

...

switch (protocol) 
{

case TFTP:
TftpStart();
break;

case DHCP:
BootpTry = 0;
NetOurIP = 0;
DhcpRequest(); 
break;
case BOOTP:

BootpTry = 0;
NetOurIP = 0;
BootpRequest ();
break;

case RARP:
RarpTry = 0;
NetOurIP = 0;
RarpRequest ();
break;
case PING:
PingStart();
break;
case NFS:
NfsStart();
break;
case CDP:
CDPStart();
break;
case NETCONS:
NcStart();
break;
case SNTP:
SntpStart();
break;
case DNS:
DnsStart();
break;

}

...

}

void TftpStart (void)

{

...

//设置参数

NetSetTimeout (TftpTimeoutMSecs * CFG_HZ, TftpTimeout);
NetSetHandler (TftpHandler);

...

//发送

TftpSend ();

...

}

static void TftpSend (void)

{

...

//容错

//开始组包

pkt = NetTxPacket + NetEthHdrSize() + IP_HDR_SIZE;

//针对各种状态组包

switch (TftpState) 

{

case STATE_RRQ:

xp = pkt;

s = (ushort *)pkt;
if(TftpState == STATE_WRQ)
*s++ = htons(TFTP_WRQ);
else

*s++ = htons(TFTP_RRQ);
pkt = (uchar *)s;
strcpy ((char *)pkt, tftp_filename);
pkt += strlen(tftp_filename) + 1;
strcpy ((char *)pkt, "octet");
pkt += 5 /*strlen("octet")*/ + 1;
strcpy ((char *)pkt, "timeout");
pkt += 7 /*strlen("timeout")*/ + 1;
sprintf((char *)pkt, "%lu", TftpTimeoutMSecs / 1000);
pkt += strlen((char *)pkt) + 1;
memcpy((char *)pkt, "tsize\0000\0", 8);
pkt += 8;
if(TftpState == STATE_WRQ)
pkt += sprintf((char *)pkt,"blksize%c%d%c", 0,TftpBlkSizeOption,0);
else
pkt += sprintf((char *)pkt,"blksize%c%d%c", 0,TftpBlkSizeOption,0);
if (!ProhibitMcast && (Bitmap=malloc(Mapsize)) && eth_get_dev()->mcast) 
{
free(Bitmap);
Bitmap=NULL;
pkt += sprintf((char *)pkt,"multicast%c%c",0,0);
}
len = pkt - xp;
break;

case STATE_WRQ:

...

case STATE_OACK:

...

case STATE_DATA:

...

case STATE_TOO_LARGE:

...

case STATE_BAD_MAGIC:

...

case STATE_ACK:

...

}

//发送

NetSendUDPPacket(NetServerEther, TftpServerIP, TftpServerPort, TftpOurPort, len);

}

int NetSendUDPPacket(uchar *ether, IPaddr_t dest, int dport, int sport, int len)

{

//容错:目标IP

//容错:ether 发ARP

if (memcmp(ether, NetEtherNullAddr, 6) == 0) 

{

NetArpWaitPacketIP = dest;
NetArpWaitPacketMAC = ether;

pkt = NetArpWaitTxPacket;
pkt += NetSetEther (pkt, NetArpWaitPacketMAC, PROT_IP);

NetSetIP (pkt, dest, dport, sport, len);
memcpy(pkt + IP_HDR_SIZE, (uchar *)NetTxPacket + (pkt - (uchar *)NetArpWaitTxPacket) + IP_HDR_SIZE, len);

NetArpWaitTxPacketSize = (pkt - NetArpWaitTxPacket) + IP_HDR_SIZE + len;

NetArpWaitTry = 1;
NetArpWaitTimerStart = get_timer(0);
ArpRequest();
return 1; 

}

//容错:time 发ARP

if (times == 10000) 
{
times = 0;

NetArpWaitPacketIP = dest;

NetArpWaitPacketMAC = ether;

pkt = NetArpWaitTxPacket;
pkt += NetSetEther(pkt, NetArpWaitPacketMAC, PROT_IP);

NetSetIP(pkt, dest, dport, sport, len);
memcpy(pkt + IP_HDR_SIZE, (uchar *)NetTxPacket + (pkt - (uchar *)NetArpWaitTxPacket) + IP_HDR_SIZE, len);

NetArpWaitTxPacketSize = (pkt - NetArpWaitTxPacket) + IP_HDR_SIZE + len;

NetArpWaitTry = 1;
NetArpWaitTimerStart = get_timer(0);
ArpRequest();
}

//组包发送

times++;

pkt = (uchar *)NetTxPacket;

pkt += NetSetEther (pkt, ether, PROT_IP);
NetSetIP (pkt, dest, dport, sport, len);
(void) eth_send(NetTxPacket, (pkt - NetTxPacket) + IP_HDR_SIZE + len);

...

}

至此,(void) eth_send(NetTxPacket, (pkt - NetTxPacket) + IP_HDR_SIZE + len);开始转向各个网卡驱动的发送函数。



 

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分