ILD

dnw2烧些固件
作者:HerbertYuan 邮箱:yuanjp89@163.com
发布时间:2017-9-13 站点:Inside Linux Development

之前的文章分析了如何使用minicom连接USB串口。接着就开始分析如何使用USB接口传输数据到uboot。从网上下载了dnw_linux,包括一个USB驱动secbulk和用户态程序dnw,插入USB,驱动可识别,但是写文件会卡死。之前一直以为是64位linux系统的问题,或者是xhci的问题,但是尝试都失败了,后来在开发板的配套中发现一个dnw程序,可直接传输文件,不需要安装驱动,搜索发现了一个牛人写的dnw2。使用libusb库,不需要驱动程序即可传输文件。源码如下,只修改了第40行,匹配USB的id。

编译方法: cc -lusb -o dnw2 dnw2.c。需要先安装libusb-dev包。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
/* dnw2 linux main file. This depends on libusb.
 *
 * Author:   Fox <hulifox008@163.com>
 * License:   GPL
 *
 */
 
/*
 * dnw2
 * Copyright (C) 2009  xiaogaozi <gaochangjian@gmail.com>
 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
/* 
 * 2017/9/12 HY fetch from: 
 * https://github.com/wzhliang/dnw2/blob/master/dnw2.c
 */
 
#include <stdio.h>
#include <usb.h>
#include <errno.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
 
#define OK6410_SECBULK_IDVENDOR 0x5345    /*0x04e8*/
#define OK6410_SECBULK_IDPRODUCT 0x1234
 
 
struct usb_dev_handle *open_port()
{
    struct usb_bus *busses, *bus;
 
    usb_init();
    usb_find_busses();
    usb_find_devices();
 
    busses = usb_get_busses();
    for (bus = busses; bus; bus = bus->next)
    {
        struct usb_device *dev;
        for (dev = bus->devices; dev; dev = dev->next)
        {
            if (OK6410_SECBULK_IDVENDOR == dev->descriptor.idVendor
                && OK6410_SECBULK_IDPRODUCT == dev->descriptor.idProduct)
            {
                printf("Target usb device found!\n");
                struct usb_dev_handle *hdev = usb_open(dev);
                if (!hdev)
                {
                    perror("Cannot open device");
                }
                else
                {
                    if (0 != usb_claim_interface(hdev, 0))
                    {
                        perror("Cannot claim interface");
                        usb_close(hdev);
                        hdev = NULL;
                    }
                }
                return hdev;
            }
        }
    }
 
    printf("Target usb device not found!\n");
 
    return NULL;
}
 
void usage()
{
    printf("Usage: dnw2 [options] file [address]\n\n");
    printf("Options:\n");
    printf("  -h, --help - This help text.\n\n");
    printf("address - hexadecimal notation, e.g. 0x30800000, default is 0x30800000\n");
}
 
unsigned char *prepare_write_buf(char *filename, unsigned int *len, long addr)
{
    unsigned char *write_buf = NULL;
    struct stat fs;
 
    int fd = open(filename, O_RDONLY);
    if (-1 == fd)
    {
        perror("Cannot open file");
        return NULL;
    }
    if (-1 == fstat(fd, &fs))
    {
        perror("Cannot get file size");
        goto error;
    }
    write_buf = (unsigned char *) malloc(fs.st_size + 10);
    if (NULL == write_buf)
    {
        perror("malloc failed");
        goto error;
    }
 
    if (fs.st_size != read(fd, write_buf + 8, fs.st_size))
    {
        perror("Reading file failed");
        goto error;
    }
 
    printf("Filename : %s\n", filename);
    printf("Filesize : %d bytes\n", (int) fs.st_size);
 
    *((u_int32_t *) write_buf) = addr;  //download address
    *((u_int32_t *) write_buf + 1) = fs.st_size + 10;   //download size;
 
    *len = fs.st_size + 10;
    return write_buf;
 
error:
    if (fd != -1)
        close(fd);
    if (NULL != write_buf)
        free(write_buf);
    fs.st_size = 0;
    return NULL;
 
}
 
int main(int argc, char *argv[])
{
    long addr;
    if (1 == argc || argc > 3)
    {
        usage();
        return 1;
    }
    else if (3 == argc)
    {
        addr = strtol(argv[2], (char**) NULL, 16);
    }
    else
    {
        if (!strcmp(argv[1], "-h") ||
            !strcmp(argv[1], "--help"))
        {
            usage();
            return 0;
        }
        addr = 0x30800000;
    }
 
    struct usb_dev_handle *hdev = open_port();
    if (!hdev)
    {
        return 1;
    }
 
    unsigned int len = 0;
    unsigned char *write_buf = prepare_write_buf(argv[1], &len, addr);
    if (NULL == write_buf)
        return 1;
 
    unsigned int remain = len;
    unsigned int towrite;
    printf("Writing data ...\n");
    while (remain)
    {
        towrite = remain > 512 ? 512 : remain;
        if (towrite !=
            usb_bulk_write(hdev, 0x03, (char *) write_buf + (len - remain),
                           towrite, 3000))
        {
            perror("usb_bulk_write failed");
            break;
        }
        remain -= towrite;
        printf("\r%d\t %d bytes     ", (len - remain) * 100 / len,
               len - remain);
        fflush(stdout);
    }
    if (0 == remain)
        printf("Done!\n");
    return 0;
}


Copyright © linuxdev.cc 2017-2024. Some Rights Reserved.