FreeCalypso > hg > freecalypso-sw
diff loadtools/flprogbin.c @ 65:a7da6648a7f8
fc-loadtool: flash program-bin command implemented, compiles
author | Michael Spacefalcon <msokolov@ivan.Harhan.ORG> |
---|---|
date | Fri, 28 Jun 2013 21:12:22 +0000 |
parents | |
children | 98f855e58c9f |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/loadtools/flprogbin.c Fri Jun 28 21:12:22 2013 +0000 @@ -0,0 +1,152 @@ +/* + * In this module we are going to implement the flash program-bin command: + * programming flash using a binary file as the data source. + */ + +#include <sys/types.h> +#include <sys/stat.h> +#include <stdio.h> +#include <stdint.h> +#include <stdlib.h> +#include "flash.h" + +extern struct flash_bank_info flash_bank_info[2]; + +flashcmd_progbin(argc, argv, bank) + char **argv; +{ + struct flash_bank_info *bi; + u_long flashoff, fileoff, len; + char *strtoul_endp; + FILE *binf; + struct stat filestat; + char *targv[4], shortarg[10], longarg[513]; + u_char databuf[256]; + int reclen, cc; + + if (argc < 4 || argc > 6) { +inv: fprintf(stderr, + "usage: %s %s flash-offset binfile [file-offset [length]]\n", + argv[0], argv[1]); + return(-1); + } + flashoff = strtoul(argv[2], &strtoul_endp, 16); + if (*strtoul_endp) + goto inv; + bi = flash_bank_info + bank; + if (flashoff >= bi->total_size) { + fprintf(stderr, + "error: specified flash offset exceeds bank size (0x%lx)\n", + (u_long) bi->total_size); + return(-1); + } + if (flashoff & 1) { + fprintf(stderr, "error: flash offset must be even\n"); + return(-1); + } + binf = fopen(argv[3], "r"); + if (!binf) { + perror(argv[3]); + return(-1); + } + fstat(fileno(binf), &filestat); + if (!S_ISREG(filestat.st_mode)) { + fprintf(stderr, "%s is not a regular file\n", argv[3]); + fclose(binf); + return(-1); + } + if (argc > 4) { + fileoff = strtoul(argv[4], &strtoul_endp, 16); + if (*strtoul_endp) { + fclose(binf); + goto inv; + } + if (fileoff > filestat.st_size) { + fprintf(stderr, + "error: specified file offset exceeds file length\n"); + fclose(binf); + return(-1); + } + } else + fileoff = 0; + if (argc > 5) { + len = strtoul(argv[5], &strtoul_endp, 16); + if (*strtoul_endp) { + fclose(binf); + goto inv; + } + if (len > filestat.st_size - fileoff) { + fprintf(stderr, + "error: specified file offset+length exceed file length\n"); + fclose(binf); + return(-1); + } + } else + len = filestat.st_size - fileoff; + if (!len) { + printf("Length is zero - nothing to do!\n"); + fclose(binf); + return(0); + } + if (len > bi->total_size - flashoff) { + fprintf(stderr, + "error: specified flash offset+length exceed bank size (0x%lx)\n", + (u_long) bi->total_size); + fclose(binf); + return(-1); + } + if (len & 1) { + fprintf(stderr, "error: program length must be even\n"); + fclose(binf); + return(-1); + } + + /* finally done with the arg parsing etc, can get to work now */ + sprintf(shortarg, "%lx", (u_long) bi->base_addr); + targv[0] = "AMFB"; + targv[1] = shortarg; + targv[2] = 0; + tpinterf_make_cmd(targv); + if (tpinterf_send_cmd() < 0) { + fclose(binf); + return(-1); + } + cc = tpinterf_pass_output(1); + if (cc) { + fclose(binf); + return(cc); + } + fseek(binf, fileoff, SEEK_SET); + targv[0] = "AMFW"; + targv[1] = shortarg; + targv[2] = longarg; + targv[3] = 0; + while (len) { + if (len >= 256) + reclen = 256; + else + reclen = len; + cc = fread(databuf, 1, reclen, binf); + if (cc != reclen) { + fclose(binf); + fprintf(stderr, "error reading from %s\n", argv[3]); + return(-1); + } + sprintf(shortarg, "%lx", flashoff); + build_flashw_hex_string(databuf, longarg, reclen >> 1, 0); + tpinterf_make_cmd(targv); + if (tpinterf_send_cmd() < 0) { + fclose(binf); + return(-1); + } + cc = tpinterf_pass_output(8); /* 8 s timeout */ + if (cc) { + fclose(binf); + return(cc); + } + flashoff += reclen; + len -= reclen; + } + fclose(binf); + return(0); +}