📄 dfutool.c
字号:
if (!strcmp(str, "CSR-dfu1") || !strcmp(str, "CSR-dfu2")) { crc = crc32_init(); for (i = 0; i < size - DFU_SUFFIX_SIZE; i++) crc = crc32_byte(crc, buf[i]); printf("Firmware type\t%s\n", str); printf("Firmware check\t%s checksum\n", crc == 0 ? "valid" : "corrupt"); printf("\n"); } free(buf); close(fd);}static void cmd_modify(char *device, int argc, char **argv){}static void cmd_upgrade(char *device, int argc, char **argv){ struct usb_dev_handle *udev; struct dfu_status status; struct dfu_suffix suffix; struct stat st; char *buf; unsigned long filesize, count, timeout = 0; char *filename; uint32_t crc, dwCRC; int fd, i, block, len, size, sent = 0, try = 10; if (argc < 2) { usage(); exit(1); } filename = argv[1]; if (stat(filename, &st) < 0) { perror("Can't access firmware"); exit(1); } filesize = st.st_size; if (!(buf = malloc(filesize))) { perror("Unable to allocate file buffer"); exit(1); } if ((fd = open(filename, O_RDONLY)) < 0) { perror("Can't open firmware"); free(buf); exit(1); } if (read(fd, buf, filesize) < filesize) { perror("Can't load firmware"); free(buf); close(fd); exit(1); } memcpy(&suffix, buf + filesize - DFU_SUFFIX_SIZE, sizeof(suffix)); dwCRC = le32_to_cpu(suffix.dwCRC); printf("Filename\t%s\n", basename(filename)); printf("Filesize\t%ld\n", filesize); crc = crc32_init(); for (i = 0; i < filesize - 4; i++) crc = crc32_byte(crc, buf[i]); printf("Checksum\t%08x (%s)\n", crc, crc == dwCRC ? "valid" : "corrupt"); if (crc != dwCRC) { free(buf); close(fd); exit(1); } printf("\n"); udev = open_device(device, &suffix); if (!udev) exit(1); printf("\r" " " " " " " " " " "); printf("\rFirmware download ... "); fflush(stdout); count = filesize - DFU_SUFFIX_SIZE; block = 0; while (count) { size = (count > 1023) ? 1023 : count; if (dfu_get_status(udev, 0, &status) < 0) { if (try-- > 0) { sleep(1); continue; } printf("\rCan't get status: %s (%d)\n", strerror(errno), errno); goto done; } if (status.bStatus != DFU_OK) { if (try-- > 0) { dfu_clear_status(udev, 0); sleep(1); continue; } printf("\rFirmware download ... aborting (status %d state %d)\n", status.bStatus, status.bState); goto done; } if (status.bState != DFU_STATE_DFU_IDLE && status.bState != DFU_STATE_DFU_DNLOAD_IDLE) { sleep(1); continue; } timeout = (status.bwPollTimeout[2] << 16) | (status.bwPollTimeout[1] << 8) | status.bwPollTimeout[0]; usleep(timeout * 1000); len = dfu_download(udev, 0, block, buf + sent, size); if (len < 0) { if (try-- > 0) { sleep(1); continue; } printf("\rCan't upload next block: %s (%d)\n", strerror(errno), errno); goto done; } printf("\rFirmware download ... %d bytes ", block * 1023 + len); fflush(stdout); sent += len; count -= len; block++; } printf("\r" " " " " " " " " " "); printf("\rFinishing firmware download ... "); fflush(stdout); sleep(1); if (dfu_get_status(udev, 0, &status) < 0) { printf("\rCan't get status: %s (%d)\n", strerror(errno), errno); goto done; } timeout = (status.bwPollTimeout[2] << 16) | (status.bwPollTimeout[1] << 8) | status.bwPollTimeout[0]; usleep(timeout * 1000); if (count == 0) { len = dfu_download(udev, 0, block, NULL, 0); if (len < 0) { printf("\rCan't send final block: %s (%d)\n", strerror(errno), errno); goto done; } } printf("\r" " " " " " " " " " "); printf("\rWaiting for device ... "); fflush(stdout); sleep(10); printf("\n");done: free(buf); close(fd); usb_release_interface(udev, 0); usb_reset(udev); usb_close(udev);}static void cmd_archive(char *device, int argc, char **argv){ struct usb_dev_handle *udev; struct dfu_status status; struct dfu_suffix suffix; char buf[2048]; unsigned long timeout = 0; char *filename; uint32_t crc; int fd, i, n, len, try = 8; if (argc < 2) { usage(); exit(1); } filename = argv[1]; udev = open_device(device, &suffix); if (!udev) exit(1); fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); if (fd < 0) { printf("Can't open firmware file: %s (%d)\n", strerror(errno), errno); goto done; } printf("\r" " " " " " " " " " "); printf("\rFirmware upload ... "); fflush(stdout); crc = crc32_init(); n = 0; while (1) { if (dfu_get_status(udev, 0, &status) < 0) { if (try-- > 0) { sleep(1); continue; } printf("\rCan't get status: %s (%d)\n", strerror(errno), errno); goto done; } if (status.bStatus != DFU_OK) { if (try-- > 0) { dfu_clear_status(udev, 0); sleep(1); continue; } printf("\rFirmware upload ... aborting (status %d state %d)\n", status.bStatus, status.bState); goto done; } if (status.bState != DFU_STATE_DFU_IDLE && status.bState != DFU_STATE_UPLOAD_IDLE) { sleep(1); continue; } timeout = (status.bwPollTimeout[2] << 16) | (status.bwPollTimeout[1] << 8) | status.bwPollTimeout[0]; usleep(timeout * 1000); len = dfu_upload(udev, 0, n, buf, 1023); if (len < 0) { if (try-- > 0) { sleep(1); continue; } printf("\rCan't upload next block: %s (%d)\n", strerror(errno), errno); goto done; } printf("\rFirmware upload ... %d bytes ", n * 1023 + len); fflush(stdout); for (i = 0; i < len; i++) crc = crc32_byte(crc, buf[i]); if (len > 0) { if (write(fd, buf, len) < 0) { printf("\rCan't write next block: %s (%d)\n", strerror(errno), errno); goto done; } } n++; if (len != 1023) break; } printf("\n"); suffix.bcdDFU = cpu_to_le16(0x0100); suffix.ucDfuSignature[0] = 'U'; suffix.ucDfuSignature[1] = 'F'; suffix.ucDfuSignature[2] = 'D'; suffix.bLength = DFU_SUFFIX_SIZE; memcpy(buf, &suffix, DFU_SUFFIX_SIZE); for (i = 0; i < DFU_SUFFIX_SIZE - 4; i++) crc = crc32_byte(crc, buf[i]); suffix.dwCRC = cpu_to_le32(crc); if (write(fd, &suffix, DFU_SUFFIX_SIZE) < 0) printf("Can't write suffix block: %s (%d)\n", strerror(errno), errno);done: close(fd); usb_release_interface(udev, 0); usb_reset(udev); usb_close(udev);}struct { char *cmd; char *alt; void (*func)(char *device, int argc, char **argv); char *opt; char *doc;} command[] = { { "verify", "check", cmd_verify, "<dfu-file>", "Check firmware file" }, { "modify", "change", cmd_modify, "<dfu-file>", "Change firmware attributes" }, { "upgrade", "download", cmd_upgrade, "<dfu-file>", "Download a new firmware" }, { "archive", "upload", cmd_archive, "<dfu-file>", "Upload the current firmware" }, { NULL, NULL, NULL, 0, 0 }};static void usage(void){ int i; printf("dfutool - Device Firmware Upgrade utility ver %s\n\n", VERSION); printf("Usage:\n" "\tdfutool [options] <command>\n" "\n"); printf("Options:\n" "\t-d, --device <device> USB device\n" "\t-h, --help Display help\n" "\n"); printf("Commands:\n"); for (i = 0; command[i].cmd; i++) printf("\t%-8s %-10s\t%s\n", command[i].cmd, command[i].opt ? command[i].opt : " ", command[i].doc); printf("\n");}static struct option main_options[] = { { "help", 0, 0, 'h' }, { "device", 1, 0, 'd' }, { 0, 0, 0, 0 }};int main(int argc, char *argv[]){ char *device = NULL; int i, opt; while ((opt = getopt_long(argc, argv, "+d:h", main_options, NULL)) != -1) { switch(opt) { case 'd': device = strdup(optarg); break; case 'h': usage(); exit(0); default: exit(0); } } argc -= optind; argv += optind; optind = 0; if (argc < 1) { usage(); exit(1); } usb_init(); for (i = 0; command[i].cmd; i++) { if (strcmp(command[i].cmd, argv[0]) && strcmp(command[i].alt, argv[0])) continue; command[i].func(device, argc, argv); exit(0); } usage(); exit(1);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -