二、tftp实现与说明(二)

本文详细介绍了uboot环境下tftp客户端的实现,与内核中的区别在于发送方式,uboot通过将数据放入网卡发送缓冲区。此外,还探讨了如何在uboot中返回传输和升级进度,包括自定义结构体和利用udp_tx接口进行网络传输的步骤。
摘要由CSDN通过智能技术生成

  上一讲中了解了tftp的原理和代码的具体实现之后,这一讲具体对uboot客户端环境下的tftp升级进行说明。与之前自己实现的tftp客户端不同的是,uboot中还没有实现创建udp的接口,只是通过将传输信息必要的信息放入一定的字符数组位置中,然后将该字符数组放入网卡的发送缓冲区中,由网卡实现数据解析和发送。
  接下来就uboot的tftp客户端实现和uboot怎么发送传输和升级进度进行详细的说明。

uboot的tftp客户端实现

int cmd_tftp(int argc, char *argv[])
{
    ...
tftp:
    if (net_tftp(ac, buf, byte_count, fname)) //调用net_tftp接口
        return ERR_OK;
    else
        return ERR_FILE;
    ...
}

int net_tftp(int put, unsigned long dest_address, unsigned int bytecount, char *file)
{
    img.addr = dest_address;
    img.count = bytecount;
    printf("tftp %s %s:%s \n", (put ? "put" : "get"),
           inet_ntoa(&bootvars.server), file);
    return ((tftp(file, (put ? upload_file : download_file)))? 1 : 0);      //调用tftp接口
}

//uboot中具体实现tftp客户端的接口
int tftp(const char *name, int (*func) (unsigned char *, int, int, int))
{
    static unsigned short iport = 2000;
    unsigned short oport, len, block = 0, prevblock = 0, txblk = 0;
    int bcounter = 0, retry = 0, timeout, result;
    struct tftp_t *tr;
    struct nbuf *pkt;
    int packetsize = TFTP_DEFAULTSIZE_PACKET;                   //和前一章说明的一样,这里的数据包限定完整长度为TFTP_DEFAULTSIZE_PACKET,即512字节
    unsigned long server = bootvars.server;                 //全局变量,这里表示的是uboot环境变量中设置的服务器IP
    unsigned long data;
    short put = (func == upload_file);                      //这里的put变量用于后续区分执行是上传文件还是下载文件
    await_reply(AWAIT_QDRAIN, 0, 0);
    tp.opcode = put ? htons(TFTP_WRQ) : htons(TFTP_RRQ);            //前面讲过,TFTP_WRQ和TFTP_RRQ分别表示的是tftp协议中开始处的请求上传及请求下载选项
    len = 1 + sizeof (tp.ip) + sizeof (tp.udp) +                //发送必要信息:发送的总数据长度
        sizeof (tp.opcode) + sprintf((char *) tp.u.rrq, "%s%coctet", name, 0);

    //!!!
    if (0 == udp_tx(server, ++iport, TFTP_PORT, len, &tp))          //!!!发现这里通过udp_tx进行信息发送,必要的发送信息包括:服务器地址,发送端口号,TFTP接收端端口号(69)以及发送信息;
        return (0);

    //在发送完上传请求或者下载请求后,进入接收服务器返回的信息并处理阶段
    while (1)
    {
        timeout = rfc951_sleep(block ? TFTP_REXMT : TIMEOUT, retry);
        data = (unsigned long) iport;
        result = await_reply(AWAIT_TFTP, &data, timeout);
        if (ESC == result)
            return 0;

    //超时,进入重发机制
        if (0 == result)
        {
            if (!block && (MAX_TFTP_RETRIES > retry++))
            {
                if (0 == udp_tx(server, ++iport, TFTP_PORT, len, &tp))
                    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值