Contiki 3.x
mc1322x-load.c
1 /*
2  * Copyright (c) 2012, Maxim Osipov <maxim.osipov@gmail.com>
3  * Copyright (c) 2010, Mariano Alvira <mar@devl.org> and other contributors
4  * to the MC1322x project (http://mc1322x.devl.org)
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  * notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  * notice, this list of conditions and the following disclaimer in the
14  * documentation and/or other materials provided with the distribution.
15  * 3. Neither the name of the Institute nor the names of its contributors
16  * may be used to endorse or promote products derived from this software
17  * without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  */
31 
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <sys/types.h>
35 #include <sys/stat.h>
36 #include <unistd.h>
37 #include <termios.h>
38 #include <fcntl.h>
39 #include <string.h>
40 #include <stdint.h>
41 
42 
43 char* filename;
44 char* second;
45 char* term = "/dev/ttyUSB0";
46 int baud = B115200;
47 int verbose = 0;
48 char* rts = "rts";
49 char* command;
50 int first_delay = 50;
51 int second_delay = 100;
52 int do_exit = 0;
53 int zerolen = 0;
54 char *args = NULL;
55 
56 struct stat sbuf;
57 struct termios options;
58 char buf[256];
59 int pfd;
60 int ffd;
61 int sfd;
62 
63 void help(void);
64 
65 int main(int argc, char **argv)
66 {
67  int c = 0;
68  int r = 0;
69  int i = 0;
70  uint32_t s = 0;
71  opterr = 0;
72 
73  /* Parse options */
74  while ((c = getopt(argc, argv, "f:s:zt:vu:r:c:a:b:eh")) != -1) {
75  switch (c)
76  {
77  case 'f':
78  filename = optarg;
79  break;
80  case 's':
81  second = optarg;
82  break;
83  case 'z':
84  zerolen = 1;
85  break;
86  case 't':
87  term = optarg;
88  break;
89  case 'v':
90  verbose = 1;
91  break;
92  case 'u':
93  if (strcmp(optarg, "115200")) {
94  baud = B115200;
95  } else if (strcmp(optarg, "57600")) {
96  baud = B115200;
97  } else if (strcmp(optarg, "19200")) {
98  baud = B19200;
99  } else if (strcmp(optarg, "9600")) {
100  baud = B9600;
101  } else {
102  printf("Unknown baud rate %s!\n", optarg);
103  return -1;
104  }
105  break;
106  case 'r':
107  rts = optarg;
108  break;
109  case 'c':
110  command = optarg;
111  break;
112  case 'a':
113  first_delay = atoi(optarg);
114  break;
115  case 'b':
116  second_delay = atoi(optarg);
117  break;
118  case 'e':
119  do_exit = 1;
120  break;
121  case 'h':
122  case '?':
123  help();
124  return 0;
125  default:
126  abort();
127  }
128  }
129  /* Get other arguments */
130  if (optind < argc)
131  args = argv[optind];
132 
133  /* Print settings */
134  if (verbose) {
135  printf("Primary file (RAM): %s\n", filename);
136  printf("Secondary file (Flash): %s\n", second);
137  printf("Zero secondary file: %s\n", zerolen == 1 ? "Yes" : "No");
138  printf("Port: %s\n", term);
139  printf("Baud rate: %i\n", baud);
140  printf("Flow control: %s\n", rts);
141  printf("Reset command: %s\n", command);
142  printf("Exit after load: %s\n", do_exit == 1 ? "Yes" : "No");
143  printf("Delay 1: %i\n", first_delay);
144  printf("Delay 2: %i\n", second_delay);
145  }
146 
147  /* Open and configure serial port */
148  pfd = open(term, O_RDWR | O_NOCTTY | O_NDELAY);
149  if (pfd == -1) {
150  printf("Cannot open serial port %s!\n", term);
151  return -1;
152  }
153  fcntl(pfd, F_SETFL, FNDELAY);
154  tcgetattr(pfd, &options);
155  cfsetispeed(&options, baud);
156  options.c_cflag |= (CLOCAL | CREAD);
157  options.c_cflag &= ~PARENB;
158  options.c_cflag &= ~CSTOPB;
159  options.c_cflag &= ~CSIZE;
160  options.c_cflag |= CS8;
161  if (strcmp(rts, "rts")) {
162  options.c_cflag &= ~CRTSCTS;
163  } else {
164  options.c_cflag |= CRTSCTS;
165  }
166  options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
167  options.c_oflag &= ~OPOST;
168  tcsetattr(pfd, TCSANOW, &options);
169 
170  /* Reset the board if we can */
171  printf("Reset the board to enter bootloader (waiting for CONNECT)...\n");
172  if (command) {
173  printf("Performing reset: %s\n", command);
174  system(command);
175  }
176 
177  /* Primary bootloader wait loop */
178  i = 0;
179  while (1) {
180  /* Wait for CONNECT */
181  r = write(pfd, (const void*)"\0", 1);
182  sleep(1);
183  r = read(pfd, &buf[i], sizeof(buf)-1-i);
184  if (r > 0) {
185  buf[i+r] = '\0';
186  printf("%s", &buf[i]); fflush(stdout);
187  if (strstr(&buf[i], "CONNECT")) {
188  printf("\n");
189  break;
190  }
191  i += r;
192  if (i >= sizeof(buf)-1) {
193  i = 0;
194  }
195  } else {
196  printf("."); fflush(stdout);
197  }
198  }
199 
200  /* Send primary file */
201  if (!filename) {
202  printf("Please specify firmware file name (-f option)!\n");
203  return -1;
204  }
205  if (stat(filename, &sbuf)) {
206  printf("Cannot open firmware file %s!\n", filename);
207  return -1;
208  }
209  ffd = open(filename, O_RDONLY);
210  if (ffd == -1) {
211  printf("Cannot open firmware file %s!\n", filename);
212  return -1;
213  }
214  s = sbuf.st_size;
215  printf("Sending %s (%i bytes)...\n", filename, s);
216  r = write(pfd, (const void*)&s, 4);
217  i = 0;
218  r = read(ffd, buf, 1);
219  while (r > 0) {
220  do {
221  usleep(first_delay);
222  c = write(pfd, (const void*)buf, r);
223  } while(c < r);
224  i += r;
225  printf("Written %i\r", i); fflush(stdout);
226  r = read(ffd, buf, 1);
227  }
228  printf("\n");
229 
230  /* Secondary loader wait loop */
231  if (second || zerolen) {
232  /* Wait for ready */
233  printf("Sending secondary file (waiting for ready)...\n");
234  i = 0;
235  while (1) {
236  sleep(1);
237  r = read(pfd, &buf[i], sizeof(buf)-1-i);
238  if (r > 0) {
239  buf[i+r] = '\0';
240  printf("%s", &buf[i]); fflush(stdout);
241  if (strstr(buf, "ready")) {
242  printf("\n");
243  break;
244  }
245  i += r;
246  if (i >= sizeof(buf)-1) {
247  i = 0;
248  }
249  } else {
250  printf("."); fflush(stdout);
251  }
252  }
253 
254  /* Send secondary file */
255  if (second) {
256  if (stat(second, &sbuf)) {
257  printf("Cannot open secondary file %s!\n", second);
258  return -1;
259  }
260  sfd = open(second, O_RDONLY);
261  if (sfd == -1) {
262  printf("Cannot open secondary file %s!\n", second);
263  return -1;
264  }
265  s = sbuf.st_size;
266  printf("Sending %s (%i bytes)...\n", second, s);
267  r = write(pfd, (const void*)&s, 4);
268  i = 0;
269  r = read(sfd, buf, 1);
270  while (r > 0) {
271  do {
272  usleep(second_delay);
273  c = write(pfd, (const void*)buf, r);
274  } while(c < r);
275  i += r;
276  printf("Written %i\r", i); fflush(stdout);
277  r = read(sfd, buf, 1);
278  }
279  printf("\n");
280  } else if (zerolen) {
281  s = 0;
282  printf("Sending %i...\n", s);
283  write(pfd, (const void*)&s, 4);
284  }
285  }
286 
287  /* Send the remaining arguments */
288  if (args) {
289  printf("Sending %s\n", args);
290  r = write(pfd, (const void*)args, strlen(args));
291  r = write(pfd, (const void*)",", 1);
292  }
293 
294  /* Drop in echo mode */
295  if (!do_exit) {
296  while (1) {
297  r = read(pfd, buf, sizeof(buf));
298  if (r > 0) {
299  buf[r] = '\0';
300  printf("%s", buf); fflush(stdout);
301  }
302  }
303  }
304 }
305 
306 
307 void help(void)
308 {
309  printf("Example usage: mc1322x-load -f foo.bin -t /dev/ttyS0 -b 9600\n");
310  printf(" or : mc1322x-load -f flasher.bin -s flashme.bin 0x1e000,0x11223344,0x55667788\n");
311  printf(" or : mc1322x-load -f flasher.bin -z 0x1e000,0x11223344,0x55667788\n");
312  printf(" -f required: binary file to load\n");
313  printf(" -s optional: secondary binary file to send\n");
314  printf(" -z optional: send a zero length file as secondary\n");
315  printf(" -t, terminal default: /dev/ttyUSB0\n");
316  printf(" -u, baud rate default: 115200\n");
317  printf(" -r [none|rts] flow control default: rts\n");
318  printf(" -c command to run for autoreset: \n");
319  printf(" e.g. -c 'bbmc -l redbee-econotag -i 0 reset'\n");
320  printf(" -e exit instead of dropping to terminal display\n");
321  printf(" -a first intercharacter delay, passed to usleep\n");
322  printf(" -b second intercharacter delay, passed to usleep\n");
323  printf("\n");
324  printf("Anything on the command line is sent after all of the files.\n\n");
325 }
#define NULL
The null pointer.
int main(void)
This is main...
Definition: ethconfig.c:49