iCub-main
Loading...
Searching...
No Matches
main.cpp
Go to the documentation of this file.
1// -*- mode:C++; tab-width:4; c-basic-offset:4; indent-tabs-mode:nil -*-
2
3/*
4 * Copyright (C) 2008 RobotCub Consortium
5 * Author: Marco Maggiali, Marco Randazzo, Alessandro Scalzo, Marco Accame
6 * CopyPolicy: Released under the terms of the GNU GPL v2.0.
7 *
8 */
9
132#include "downloader.h"
133#include "driver.h"
134#include <yarp/os/Time.h>
135#include <yarp/os/Log.h>
136#include <yarp/dev/Drivers.h>
137
138#include <string> //stl string
139#include <string.h> //memcpy ...
140#include <stdlib.h>
141
142#include <stdio.h>
143#include <fcntl.h>
144
145#include <iCubCanProtocol.h>
146#include <iCubCanProto_types.h>
147
149
150//can_parameters_type params;
152int canID=1;
153unsigned int localAddr=0;
154unsigned int remoteAddr=0;
155const int maxNetworks=10; //max number of can networks
156std::string networkType;
158bool prompt_version=false;
159
160//enum
161//{
162// COLUMN_SELECTED,
163// COLUMN_ID,
164// COLUMN_TYPE,
165// COLUMN_VERSION,
166// COLUMN_RELEASE,
167// COLUMN_BUILD,
168// COLUMN_SERIAL,
169// COLUMN_STATUS,
170// COLUMN_ADD_INFO,
171// COLUMN_EEPROM,
172// NUM_COLUMNS
173//};
174
175#define ALL_OK 0
176#define INVALID_CMD_STRING -1
177#define INVALID_PARAM_CANTYPE -2
178#define INVALID_PARAM_CANNUM -3
179#define INVALID_PARAM_BOARDID -4
180#define INVALID_PARAM_FILE -5
181#define ERR_NO_BOARDS_FOUND -10
182#define ERR_BOARD_ID_NOT_FOUND -11
183#define ERR_UNKNOWN -12
184#define ERR_NO_NETWORK_INTERFACE -13
185#define DOWNLOADERR_NOT_CONNECTED -20
186#define DOWNLOADERR_BOARD_NOT_SEL -21
187#define DOWNLOADERR_FILE_NOT_SEL -22
188#define DOWNLOADERR_FILE_NOT_OPEN -23
189#define DOWNLOADERR_BOARD_NOT_START -24
190#define DOWNLOADERR_TRANSFER_ERROR -25
191
192
193
194
195//*********************************************************************************
196
197
198static bool compile_ip_addresses(const char* addr)
199{
200 ACE_UINT32 ip1,ip2,ip3,ip4;
201 sscanf(addr,"%d.%d.%d.%d",&ip1,&ip2,&ip3,&ip4);
202 remoteAddr=(ip1<<24)|(ip2<<16)|(ip3<<8)|ip4;
203
204 size_t count=0;
205 ACE_INET_Addr* addr_array=NULL;
206 int ret=ACE::get_ip_interfaces(count,addr_array);
207
208 if (ret || count<=0)
209 {
210 return false;
211 }
212
213 localAddr=addr_array[0].get_ip_address();
214
215 for (unsigned int a=1; a<count; ++a)
216 {
217 if ((remoteAddr & 0xFFFF0000)==(addr_array[a].get_ip_address() & 0xFFFF0000))
218 {
219 localAddr=addr_array[a].get_ip_address();
220 break;
221 }
222 }
223
224 return true;
225}
226
227
228static void start_end_click ()
229{
230 int ret = 0;
231
232 if (downloader.connected==false)
233 {
234 yarp::os::Property params;
235 params.put("device", networkType.c_str());
236
237 if (networkType=="ETH")
238 {
239 yError() << "ETH not supported yet" ;
240 }
241 else
242 {
243 params.put("canDeviceNum", networkId);
244 params.put("canTxQueue", 64);
245 params.put("canRxQueue", 64);
246 params.put("canTxTimeout", 2000);
247 params.put("canRxTimeout", 2000);
248 }
249
250 //try to connect to the driver
251 ret = downloader.initdriver(params);
252
253 if (ret == -1)
254 {
255 yError() << "Init driver failed" << "Hardware busy or not connected?!";
256 return;
257 }
258
259 //drv_sleep (2000);
260 //get the infos from the board
261 ret = downloader.initschede();
262
263 if (ret == -1)
264 {
265 yError() << "Communication error" << "No answers received (no boards found).";
267 return;
268 }
269
270 //enable select/deselect all buttons
271 yInfo() << "Driver Connected";
272 }
273 else
274 {
276 yInfo() << "Driver Stopped";
277 }
278}
279
280//*********************************************************************************
281static int download_click (std::string* user_data)
282{
283 double timer_start =0;
284 double timer_end =0;
285 // check if can driver is running
286 if (downloader.connected == false)
287 {
288 yError() << "Driver not running " << " Use 'Connect' button to start the driver";
290 }
291
292 //check if at least one board was selected
293 bool at_least_one_board_selected = false;
294 int i = 0;
295
296 for (i=0; i<downloader.board_list_size; i++)
297 {
300 at_least_one_board_selected = true;
301 }
302
303 if (!at_least_one_board_selected)
304 {
305 yError() << "No Boards selected! " << "Select one or more boards to download the firmware";
307 }
308
309 // Open the selected file
310 char* buffer=NULL;
311
312 if (user_data==NULL)
313 {
314 yError() << "No files selected! " << "Select the file You want to download, first";
316 }
317 else
318 {
319 std::string* p = (std::string*)user_data;
320 buffer = new char[255];
321 strcpy(buffer,(p->c_str()));
322 }
323 if (downloader.open_file(buffer)!=0)
324 {
325 yError() << "Error opening the selected file!";
327 }
328
329 // Get an identification of the firmware fot the file that you have selected
330 int firmware_board_type=0;
331 int firmware_version=0;
332 int firmware_revision=0;
333
334 //indentify download type from the type of the selected boards
335 int download_type = icubCanProto_boardType__unknown;
336 bool download_eeprom =false;
337 for (i=0; i<downloader.board_list_size; i++)
338 {
339 if (downloader.board_list[i].selected==true)
340 {
341 download_type = downloader.board_list[i].type;
342 download_eeprom = downloader.board_list[i].eeprom;
343 }
344
345 }
346
347 // Start the download for the selected boards
348 for (i=0; i<downloader.board_list_size; i++)
349 {
352 {
354 {
355 yError() << "Unable to start the board" << "Unable to send message 'start' or no answer received";
357 }
358 else
359 {
361 }
362 }
363 }
364
365 int ret = 0;
366 int finished = 0;
367
368 timer_start= yarp::os::Time::now();
369
370 bool print00 = false, print25 = false, print50 = false, print75 = false, print99 = false;
371 // Start the download for the selected boards
372 do
373 {
374 ret = downloader.download_file(CanPacket::everyCANbus, 0x0F, download_type, download_eeprom);
375 if (float(downloader.progress)/downloader.file_length >0.0 && print00==false) {yInfo ("downloading %s, 1%% done\n",buffer); print00=true;}
376 if (float(downloader.progress) / downloader.file_length >0.25 && print25 == false) { yInfo("downloading %s, 25%% done\n", buffer); print25 = true; }
377 if (float(downloader.progress) / downloader.file_length >0.50 && print50 == false) { yInfo("downloading %s, 50%% done\n", buffer); print50 = true; }
378 if (float(downloader.progress) / downloader.file_length >0.75 && print75 == false) { yInfo("downloading %s, 75%% done\n", buffer); print75 = true; }
379 if (float(downloader.progress) / downloader.file_length >0.99 && print99 == false) { yInfo("downloading %s, finished!\n", buffer); print99 = true; }
380
381 if (ret==1)
382 {
383 //Continuing the download
384 }
385 if (ret==-1)
386 {
387 //Fatal Error during download, terminate
388 finished = 1;
389 }
390 if (ret==0)
391 {
392 //Download terminated
393 finished = 1;
394 }
395
396 }
397 while (finished!=1);
398 timer_end= yarp::os::Time::now();
399
400 // End the download for the selected boards
401 int errors =0;
403
404 //Display result message
405 if (errors==0)
406 {
407 char time_text [50];
408 double download_time = (timer_end-timer_start) ;
409 sprintf (time_text, "All Board OK\nDownload Time (s): %.2f", download_time);
410 return ALL_OK;
411 }
412 else
413 {
415 }
416
417}
418
419//*********************************************************************************
420bool validate_selection (int wanted_type)
421{
422 int first_type = icubCanProto_boardType__unknown;
423 bool something_selected=false;
424 int i=0;
425 for (i=0; i<downloader.board_list_size; i++)
426 {
427 if (downloader.board_list[i].selected==true)
428 {
429 something_selected=true;
430 first_type = downloader.board_list[i].type;
431 }
432 }
433 //check if there is at least one board selected
434 if (something_selected == false)
435 {
436 //if not, this is sthe first board you're going to select,
437 //so it's ok, you can select it
438 return true;
439 }
440
441 //check the compatibility of the board that you selected now, with
442 //the previous selected ones. all the boards must be of the same type.
443 if (wanted_type != first_type)
444 {
445 return false;
446 }
447 else
448 {
449 return true;
450 }
451 /*
452 switch (wanted_type)
453 {
454 case BOARD_TYPE_DSP:
455 case BOARD_TYPE_2DC:
456 case BOARD_TYPE_4DC:
457 case BOARD_TYPE_BLL:
458 if (first_type == BOARD_TYPE_DSP ||
459 first_type == BOARD_TYPE_2DC ||
460 first_type == BOARD_TYPE_4DC ||
461 first_type == BOARD_TYPE_BLL )
462 return true;
463 else return false;
464 break;
465 case BOARD_TYPE_PIC :
466 case BOARD_TYPE_SKIN :
467 case BOARD_TYPE_STRAIN :
468 case BOARD_TYPE_MAIS :
469 if (first_type == BOARD_TYPE_PIC ||
470 first_type == BOARD_TYPE_STRAIN ||
471 first_type == BOARD_TYPE_MAIS ||
472 first_type == BOARD_TYPE_SKIN )
473 return true;
474 else return false;
475 default:
476 case BOARD_UNKNOWN:
477 return false;
478 break;
479 }
480 */
481 return false;
482}
483
484
485void fatal_error(int err)
486{
487 switch (err)
488 {
490 yError("Unable to parse the command line. The correct format is:\n");
491 yError("canLoader --canDeviceType t --canDeviceNum x --boardId y --firmware myFirmware.out.S\n");
492 yError("canLoader --canDeviceType ETH --canDeviceNum 1|2 --boardId y --firmware myFirmware.out.S --boardIPAddr aaa.aaa.aaa.aaa\n");
493 ::exit(err);
494 break;
496 yError("invalid --canDeviceType parameter \n");
497 yError("must be 'ecan' or 'pcan' or 'cfw2' or 'socketcan'\n");
498 ::exit(err);
499 break;
501 yError("invalid --canDeviceNum parameter \n");
502 yError("must be between 0 and 3\n");
503 ::exit(err);
504 break;
506 yError("invalid --boardId parameter \n");
507 yError("must be between 0 and 15\n");
508 ::exit(err);
509 break;
511 yError("invalid --firmware parameter \n");
512 yError("file not found\n");
513 ::exit(err);
514 break;
516 yError("no boards found \n");
517 yError("check canbus cable, power supply connection etc.\n");
518 ::exit(err);
519 break;
521 yError("the specified board is not available \n");
522 ::exit(err);
523 break;
525 yError("could not find network interface\n");
526 ::exit(err);
527 case ERR_UNKNOWN:
528 default:
529 yError("Unknown error\n");
530 ::exit(ERR_UNKNOWN);
531 break;
532
533 }
534
535}
536
537//*********************************************************************************
538// Entry point for the application
539int myMain( int argc, char *argv[] )
540{
541 networkType="empty";
542
543 #ifdef USE_ICUB_MOD
544 yarp::dev::DriverCollection dev;
545 #endif
546
547 if (argc==2 && strcmp(argv[1],"--calib")==0)
548 {
550 }
551 //yDebug("argc = %d\n",argc);
552 else if (argc!=1)
553 {
554 prompt_version=true;
555 yInfo("Initializing prompt version of canLoader...\n");
556 if (argc==2 && strcmp(argv[1],"--help")==0)
557 {
558 yInfo("CANLOADER APPLICATION V2.9\n");
559 yInfo("Syntax:\n");
560 yInfo("to execute the command line version of the canLoader:\n");
561 yInfo("./canLoader --canDeviceType <t> --canDeviceNum <x> --discover\n");
562 yInfo("./canLoader --canDeviceType <t> --canDeviceNum <x> --boardId <y> --firmware myFirmware.out.S\n");
563 yInfo("./canLoader --canDeviceType ETH --canDeviceNum 1|2 --boardId <y> --firmware myFirmware.out.S --boardIPAddr <aaa.aaa.aaa.aaa>\n");
564 yInfo("parameter <t> is the name of the CAN bus driver. It can be 'ecan' or 'pcan' or 'cfw2can' or 'socketcan'\n");
565 yInfo("parameter <x> is the number of the CAN bus (0-9)\n");
566 yInfo("parameter <y> is the CAN address of the board (0-14)\n");
567 yInfo("parameter <aaa.aaa.aaa.aaa> IP address of the board (ETH boards only)\n");
568 ::exit(0);
569 }
570
571 //param1
572 if (strcmp(argv[1], "--canDeviceType") != 0) fatal_error(INVALID_CMD_STRING);
573
574 //param 2
575 if (strcmp(argv[2], "ecan") != 0 &&
576 strcmp(argv[2], "pcan") != 0 &&
577 strcmp(argv[2], "cfw2can") != 0 &&
578 strcmp(argv[2], "socketcan") != 0 &&
579 strcmp(argv[2], "ETH") != 0)
580 {
582 }
583 else
584 {
585 networkType = argv[2];
586 }
587
588 //param3
589 if (strcmp(argv[3], "--canDeviceNum") != 0) fatal_error(INVALID_CMD_STRING);
590
591 if (argc == 6)
592 {
593 if (strcmp(argv[5], "--discover") == 0)
594 {
596 ::exit(0);
597 }
598 }
599 if (argc==9 || argc==11)
600 {
601 //yInfo("canLoader --canDeviceType t --canDeviceNum x --boardId y --firmware myFirmware.out.S\n");
602
603 if (strcmp(argv[5],"--boardId")!=0 &&
604 strcmp(argv[5],"--discover")!=0) fatal_error(INVALID_CMD_STRING);
605
606 if (strcmp(argv[7],"--firmware")!=0 &&
607 strcmp(argv[7],"--calibration")!=0 &&
608 strcmp(argv[7],"--firmwareANDeeprom")!=0) fatal_error(INVALID_CMD_STRING);
609
610 int param_board_id=0;
611 std::string param_filename = "empty";
612 int temp_val=-1;
613
614 if (networkType=="ETH")
615 {
616 if (argc!=11 || strcmp(argv[9],"--boardIPAddr")) fatal_error(INVALID_CMD_STRING);
617
618 if (!compile_ip_addresses(argv[10]))
619 {
621 }
622 }
623
624 temp_val=atoi(argv[4]);
625 if (temp_val<0 || temp_val>9)
626 {
628 }
629 else
630 {
631 canID=networkId=temp_val;
632 }
633
634 temp_val=atoi(argv[6]);
635 if (temp_val<0 || temp_val>15)
636 {
638 }
639 else
640 {
641 param_board_id=temp_val;
642 }
643
644 param_filename=argv[8];
645 std::fstream filestr;
646 filestr.open ( param_filename.c_str(), std::fstream::in);
647 if (!filestr.is_open())
648 {
649 //file not exists
651 }
652 else
653 {
654 filestr.close();
655 }
656 yInfo("Selecting canDeviceType %s canDeviceNum %d, boardId %d, firmware %s\n", networkType.c_str(), networkId, param_board_id, param_filename.c_str());
657
658 //eeprom check
659 bool use_eeprom=false;
660 if (strcmp(argv[7],"--firmwareANDeeprom")==0)
661 {
662 yInfo("EEprom flag is active");
663 use_eeprom=true;
664 }
665
668 {
670 }
671
672 int i;
673 bool one_selected=false;
674 for (i = 0; i < downloader.board_list_size; i++)
675 {
676 if (downloader.board_list[i].pid==param_board_id)
677 {
679 one_selected=true;
680 if (use_eeprom==true) downloader.board_list[i].eeprom=true;
681 }
682 }
683 if (one_selected==false)
684 {
686 }
687
688 int ret=download_click(&param_filename);
689 if (ret==ALL_OK)
690 yInfo("Program terminated successfully!");
691 else
692 yError("Program terminated, DOWNLOAD FAILED!");
693 ::exit(ret);
694 }
695 if (argc!=9)
696 {
697 // fatal_error(INVALID_CMD_STRING);
698 }
699 }
700 else
701 {
702 yInfo("CANLOADER APPLICATION V2.9\n");
703 yInfo("Syntax:\n");
704 yInfo("to execute the command line version of the canLoader:\n");
705 yInfo("./canLoader --canDeviceType <t> --canDeviceNum <x> --discover\n");
706 yInfo("./canLoader --canDeviceType <t> --canDeviceNum <x> --boardId <y> --firmware myFirmware.out.S\n");
707 yInfo("./canLoader --canDeviceType ETH --canDeviceNum 1|2 --boardId <y> --firmware myFirmware.out.S --boardIPAddr <aaa.aaa.aaa.aaa>\n");
708 yInfo("parameter <t> is the name of the CAN bus driver. It can be 'ecan' or 'pcan' or 'cfw2can' or 'socketcan'\n");
709 yInfo("parameter <x> is the number of the CAN bus (0-9)\n");
710 yInfo("parameter <y> is the CAN address of the board (0-14)\n");
711 yInfo("parameter <aaa.aaa.aaa.aaa> IP address of the board (ETH ethernet boards only)\n");
712 ::exit(0);
713 }
714
715 return 0;
716}
717
718int main(int argc, char* argv[])
719{
720 return myMain(argc, argv);
721}
722
@ fatal_error
@ everyCANbus
Definition driver.h:51
int open_file(std::string file)
int startscheda(int bus, int board_pid, bool board_eeprom, int download_type)
int stopscheda(int bus, int board_pid)
int initdriver(yarp::os::Searchable &config, bool verbose=true)
sBoard * board_list
Definition downloader.h:150
int board_list_size
Definition downloader.h:151
int download_file(int bus, int board_pid, int download_type, bool eeprom)
#define BOARD_RUNNING
Definition downloader.h:45
#define BOARD_WAITING
Definition downloader.h:46
#define INVALID_PARAM_FILE
Definition main.cpp:180
int canID
Definition main.cpp:152
static int download_click(std::string *user_data)
Definition main.cpp:281
#define ERR_BOARD_ID_NOT_FOUND
Definition main.cpp:182
#define INVALID_CMD_STRING
Definition main.cpp:176
bool calibration_enabled
Definition main.cpp:157
#define ERR_NO_BOARDS_FOUND
Definition main.cpp:181
const int maxNetworks
Definition main.cpp:155
#define DOWNLOADERR_NOT_CONNECTED
Definition main.cpp:185
#define INVALID_PARAM_CANNUM
Definition main.cpp:178
#define ERR_UNKNOWN
Definition main.cpp:183
int myMain(int argc, char *argv[])
Definition main.cpp:539
#define DOWNLOADERR_BOARD_NOT_START
Definition main.cpp:189
#define DOWNLOADERR_FILE_NOT_OPEN
Definition main.cpp:188
#define INVALID_PARAM_BOARDID
Definition main.cpp:179
#define INVALID_PARAM_CANTYPE
Definition main.cpp:177
cDownloader downloader
Definition main.cpp:148
std::string networkType
Definition main.cpp:156
unsigned int remoteAddr
Definition main.cpp:154
bool prompt_version
Definition main.cpp:158
static void start_end_click()
Definition main.cpp:228
#define ERR_NO_NETWORK_INTERFACE
Definition main.cpp:184
#define DOWNLOADERR_TRANSFER_ERROR
Definition main.cpp:190
unsigned int localAddr
Definition main.cpp:153
int networkId
Definition main.cpp:151
#define ALL_OK
Definition main.cpp:175
#define DOWNLOADERR_BOARD_NOT_SEL
Definition main.cpp:186
bool validate_selection(int wanted_type)
Definition main.cpp:420
#define DOWNLOADERR_FILE_NOT_SEL
Definition main.cpp:187
static bool compile_ip_addresses(const char *addr)
Definition main.cpp:198
int main()
Definition main.cpp:67
bool eeprom
Definition downloader.h:39
int bus
Definition downloader.h:25
int type
Definition downloader.h:27
int pid
Definition downloader.h:26
int status
Definition downloader.h:37
bool selected
Definition downloader.h:38