FreeCalypso > hg > freecalypso-sw
comparison 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 |
comparison
equal
deleted
inserted
replaced
64:a481d648278a | 65:a7da6648a7f8 |
---|---|
1 /* | |
2 * In this module we are going to implement the flash program-bin command: | |
3 * programming flash using a binary file as the data source. | |
4 */ | |
5 | |
6 #include <sys/types.h> | |
7 #include <sys/stat.h> | |
8 #include <stdio.h> | |
9 #include <stdint.h> | |
10 #include <stdlib.h> | |
11 #include "flash.h" | |
12 | |
13 extern struct flash_bank_info flash_bank_info[2]; | |
14 | |
15 flashcmd_progbin(argc, argv, bank) | |
16 char **argv; | |
17 { | |
18 struct flash_bank_info *bi; | |
19 u_long flashoff, fileoff, len; | |
20 char *strtoul_endp; | |
21 FILE *binf; | |
22 struct stat filestat; | |
23 char *targv[4], shortarg[10], longarg[513]; | |
24 u_char databuf[256]; | |
25 int reclen, cc; | |
26 | |
27 if (argc < 4 || argc > 6) { | |
28 inv: fprintf(stderr, | |
29 "usage: %s %s flash-offset binfile [file-offset [length]]\n", | |
30 argv[0], argv[1]); | |
31 return(-1); | |
32 } | |
33 flashoff = strtoul(argv[2], &strtoul_endp, 16); | |
34 if (*strtoul_endp) | |
35 goto inv; | |
36 bi = flash_bank_info + bank; | |
37 if (flashoff >= bi->total_size) { | |
38 fprintf(stderr, | |
39 "error: specified flash offset exceeds bank size (0x%lx)\n", | |
40 (u_long) bi->total_size); | |
41 return(-1); | |
42 } | |
43 if (flashoff & 1) { | |
44 fprintf(stderr, "error: flash offset must be even\n"); | |
45 return(-1); | |
46 } | |
47 binf = fopen(argv[3], "r"); | |
48 if (!binf) { | |
49 perror(argv[3]); | |
50 return(-1); | |
51 } | |
52 fstat(fileno(binf), &filestat); | |
53 if (!S_ISREG(filestat.st_mode)) { | |
54 fprintf(stderr, "%s is not a regular file\n", argv[3]); | |
55 fclose(binf); | |
56 return(-1); | |
57 } | |
58 if (argc > 4) { | |
59 fileoff = strtoul(argv[4], &strtoul_endp, 16); | |
60 if (*strtoul_endp) { | |
61 fclose(binf); | |
62 goto inv; | |
63 } | |
64 if (fileoff > filestat.st_size) { | |
65 fprintf(stderr, | |
66 "error: specified file offset exceeds file length\n"); | |
67 fclose(binf); | |
68 return(-1); | |
69 } | |
70 } else | |
71 fileoff = 0; | |
72 if (argc > 5) { | |
73 len = strtoul(argv[5], &strtoul_endp, 16); | |
74 if (*strtoul_endp) { | |
75 fclose(binf); | |
76 goto inv; | |
77 } | |
78 if (len > filestat.st_size - fileoff) { | |
79 fprintf(stderr, | |
80 "error: specified file offset+length exceed file length\n"); | |
81 fclose(binf); | |
82 return(-1); | |
83 } | |
84 } else | |
85 len = filestat.st_size - fileoff; | |
86 if (!len) { | |
87 printf("Length is zero - nothing to do!\n"); | |
88 fclose(binf); | |
89 return(0); | |
90 } | |
91 if (len > bi->total_size - flashoff) { | |
92 fprintf(stderr, | |
93 "error: specified flash offset+length exceed bank size (0x%lx)\n", | |
94 (u_long) bi->total_size); | |
95 fclose(binf); | |
96 return(-1); | |
97 } | |
98 if (len & 1) { | |
99 fprintf(stderr, "error: program length must be even\n"); | |
100 fclose(binf); | |
101 return(-1); | |
102 } | |
103 | |
104 /* finally done with the arg parsing etc, can get to work now */ | |
105 sprintf(shortarg, "%lx", (u_long) bi->base_addr); | |
106 targv[0] = "AMFB"; | |
107 targv[1] = shortarg; | |
108 targv[2] = 0; | |
109 tpinterf_make_cmd(targv); | |
110 if (tpinterf_send_cmd() < 0) { | |
111 fclose(binf); | |
112 return(-1); | |
113 } | |
114 cc = tpinterf_pass_output(1); | |
115 if (cc) { | |
116 fclose(binf); | |
117 return(cc); | |
118 } | |
119 fseek(binf, fileoff, SEEK_SET); | |
120 targv[0] = "AMFW"; | |
121 targv[1] = shortarg; | |
122 targv[2] = longarg; | |
123 targv[3] = 0; | |
124 while (len) { | |
125 if (len >= 256) | |
126 reclen = 256; | |
127 else | |
128 reclen = len; | |
129 cc = fread(databuf, 1, reclen, binf); | |
130 if (cc != reclen) { | |
131 fclose(binf); | |
132 fprintf(stderr, "error reading from %s\n", argv[3]); | |
133 return(-1); | |
134 } | |
135 sprintf(shortarg, "%lx", flashoff); | |
136 build_flashw_hex_string(databuf, longarg, reclen >> 1, 0); | |
137 tpinterf_make_cmd(targv); | |
138 if (tpinterf_send_cmd() < 0) { | |
139 fclose(binf); | |
140 return(-1); | |
141 } | |
142 cc = tpinterf_pass_output(8); /* 8 s timeout */ | |
143 if (cc) { | |
144 fclose(binf); | |
145 return(cc); | |
146 } | |
147 flashoff += reclen; | |
148 len -= reclen; | |
149 } | |
150 fclose(binf); | |
151 return(0); | |
152 } |