Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
R
robotis_tools
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Model registry
Operate
Environments
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
humanoides
robotis_tools
Commits
c649cd5b
Commit
c649cd5b
authored
9 years ago
by
Sergi Hernandez
Browse files
Options
Downloads
Patches
Plain Diff
Improved version of the firmware downloader tool for the robotis devices.
Improved download speed. Addes support for more devices.
parent
3c43253d
No related branches found
No related tags found
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
src/fw_downloader/CMakeLists.txt
+6
-0
6 additions, 0 deletions
src/fw_downloader/CMakeLists.txt
src/fw_downloader/fw_downloader.cpp
+122
-284
122 additions, 284 deletions
src/fw_downloader/fw_downloader.cpp
with
128 additions
and
284 deletions
src/fw_downloader/CMakeLists.txt
+
6
−
0
View file @
c649cd5b
...
...
@@ -18,3 +18,9 @@ ADD_EXECUTABLE(fw_downloader ${sources})
# link necessary libraries
TARGET_LINK_LIBRARIES
(
fw_downloader
${
iriutils_LIBRARY
}
)
TARGET_LINK_LIBRARIES
(
fw_downloader
${
comm_LIBRARY
}
)
INSTALL
(
TARGETS fw_downloader
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib/iridrivers
ARCHIVE DESTINATION lib/iridrivers
)
This diff is collapsed.
Click to expand it.
src/fw_downloader/fw_downloader.cpp
+
122
−
284
View file @
c649cd5b
...
...
@@ -10,11 +10,26 @@
#include
<iostream>
const
unsigned
char
bootloader_ping
=
'#'
;
const
unsigned
char
bootloader_ack
[]
=
"
\n
"
;
//const unsigned char bootloader_load_hex[]="l 0x08003000\n";
const
unsigned
char
bootloader_load_hex
[]
=
"l"
;
const
unsigned
char
bootloader_load_motion
[]
=
"l 0x08060000
\n
"
;
const
unsigned
char
bootloader_go
[]
=
"
\n
go
\n
"
;
const
unsigned
char
bootloader_ack
=
'\n'
;
const
unsigned
char
bootloader_load
=
'l'
;
const
unsigned
char
bootloader_go
=
'g'
;
typedef
enum
{
original_protocol
=
0
,
new_protocol
=
1
}
protocol_t
;
void
show_help
(
char
*
name
)
{
std
::
cout
<<
"Usage: "
<<
name
<<
"-d <serial device> -f <firmware file> -p <protocol> [-h]"
<<
std
::
endl
;
std
::
cout
<<
" -d serial_device Linux serial device used to communicate"
<<
std
::
endl
;
std
::
cout
<<
" -f firmware_file desired firmware file in Intel Hex format"
<<
std
::
endl
;
std
::
cout
<<
" -p protocol Communication protocol to be used (original or new)"
<<
std
::
endl
;
std
::
cout
<<
" devices supported by the original protocol:"
<<
std
::
endl
;
std
::
cout
<<
" - ax servo family"
<<
std
::
endl
;
std
::
cout
<<
" - rx servo family"
<<
std
::
endl
;
std
::
cout
<<
" devices supported by the new protocol:"
<<
std
::
endl
;
std
::
cout
<<
" - cm510"
<<
std
::
endl
;
std
::
cout
<<
" - mx servo family"
<<
std
::
endl
;
std
::
cout
<<
" -h shows this help"
<<
std
::
endl
;
}
int
main
(
int
argc
,
char
*
argv
[])
{
...
...
@@ -25,34 +40,19 @@ int main(int argc,char *argv[])
TRS232_config
serial_config
;
long
int
num_data
=
0
,
i
=
0
;
bool
end
=
false
;
// input arguments parser variables
static
struct
option
long_options
[]
=
{{
"h"
,
no_argument
,
0
,
0
},
// display help message
{
"help"
,
no_argument
,
0
,
0
},
{
"d"
,
required_argument
,
0
,
0
},
// select the desired output device
{
"device"
,
required_argument
,
0
,
0
},
{
"f"
,
required_argument
,
0
,
0
},
// select the desired firmware file
{
"firmware"
,
required_argument
,
0
,
0
},
{
"m"
,
required_argument
,
0
,
0
},
// select the desired motion file
{
"motion"
,
required_argument
,
0
,
0
},
{
"s"
,
required_argument
,
0
,
0
},
// select the desired servo model
{
"servo"
,
required_argument
,
0
,
0
},
{
0
,
0
,
0
,
0
}
};
int
opt_status
,
opt_index
;
std
::
string
opt_device
,
opt_fw_file
,
opt_motion_file
,
servo_model
;
int
option
;
std
::
string
opt_device
,
opt_fw_file
;
protocol_t
protocol
;
// binary file variables
unsigned
char
binary_file
[
MEMORY_MAXSIZE
];
long
int
downloaded_size
=
0
,
downloaded_block_size
=
0
;
long
int
downloaded_size
=
0
;
long
int
start_address
=
0
;
long
int
binary_size
=
0
;
int
block_size
=
0
,
count
=
0
,
small_block_size
=
0
;
int
block_size
=
0
,
count
=
0
;
// bootloader variables
unsigned
char
bootloader_data
[
MEMORY_MAXSIZE
];
bool
bootloader_connected
=
false
,
error
=
false
;
bool
bootloader_connected
=
false
;
unsigned
char
checksum
=
0x00
;
char
load_hex_address
[
32
];
// motion file variables
FILE
*
motion_fd
;
// configuration information for the serial device
serial_config
.
baud
=
57600
;
...
...
@@ -60,58 +60,47 @@ int main(int argc,char *argv[])
serial_config
.
parity
=
none
;
serial_config
.
stop_bits
=
1
;
for
(
i
=
0
;
i
<
MEMORY_MAXSIZE
;
i
++
)
binary_file
[
i
]
=
0xFF
;
memset
(
binary_file
,
0xFF
,
MEMORY_MAXSIZE
);
// parse the input arguments
do
{
opt_status
=
getopt_long_only
(
argc
,
argv
,
""
,
long_options
,
&
opt_index
);
if
(
opt_status
!=-
1
)
while
((
option
=
getopt
(
argc
,
argv
,
"hd:f:p:"
))
!=
-
1
)
{
switch
(
option
)
{
if
(
opt_status
==
'?'
)
// option not recognized or argument missing
{
printf
(
"Unknown option
\n
"
);
return
0
;
/* handle the error and exit */
}
else
// process the argument
{
switch
(
opt_index
)
case
'h'
:
// show help message
show_help
(
argv
[
0
]);
break
;
case
'd'
:
// select serial device
std
::
cout
<<
"Output device: "
<<
optarg
<<
std
::
endl
;
opt_device
=
std
::
string
(
optarg
);
break
;
case
'f'
:
// select firmware file
std
::
cout
<<
"Firmware file: "
<<
optarg
<<
std
::
endl
;
opt_fw_file
=
std
::
string
(
optarg
);
break
;
case
'p'
:
// select protocol
std
::
cout
<<
"Selected protocol: "
<<
optarg
<<
std
::
endl
;
if
(
std
::
string
(
optarg
)
==
"original"
)
protocol
=
original_protocol
;
else
if
(
std
::
string
(
optarg
)
==
"new"
)
protocol
=
new_protocol
;
else
{
case
0
:
case
1
:
/* display the help information and exit */
break
;
case
2
:
case
3
:
printf
(
"output device: %s
\n
"
,
optarg
);
opt_device
=
std
::
string
(
optarg
);
break
;
case
4
:
case
5
:
printf
(
"Hex file: %s
\n
"
,
optarg
);
opt_fw_file
=
std
::
string
(
optarg
);
break
;
case
6
:
case
7
:
printf
(
"Motion file: %s
\n
"
,
optarg
);
opt_motion_file
=
std
::
string
(
optarg
);
break
;
case
8
:
case
9
:
printf
(
"servo model: %s
\n
"
,
optarg
);
servo_model
=
std
::
string
(
optarg
);
break
;
std
::
cout
<<
"Unsupported protocol"
<<
std
::
endl
;
show_help
(
argv
[
0
]);
return
0
;
}
}
break
;
}
}
while
(
opt_status
!=-
1
);
}
// check that the two arguments have been entered
if
(
opt_device
.
size
()
!=
0
)
{
if
(
opt_fw_file
.
size
()
!=
0
&&
opt_motion_file
.
size
()
!=
0
)
{
printf
(
"Only one file can be download at a time.
\n
"
);
return
0
;
}
else
if
(
opt_fw_file
.
size
()
==
0
&&
opt_motion_file
.
size
()
==
0
)
if
(
opt_fw_file
.
size
()
==
0
)
{
printf
(
"At least one file have to be specified.
\n
"
);
std
::
cout
<<
"No firmware file has been specified"
<<
std
::
endl
;
show_help
(
argv
[
0
]);
return
0
;
}
else
...
...
@@ -129,77 +118,55 @@ int main(int argc,char *argv[])
if
(
hex2bin
((
char
*
)
opt_fw_file
.
c_str
(),
binary_file
,
&
start_address
,
&
binary_size
)
==
false
)
{
serial_port
.
close
();
printf
(
"Error converting the firmware hex file
.
\n
"
)
;
std
::
cout
<<
"Error converting the firmware hex file
"
<<
std
::
endl
;
return
0
;
/* throw an exception */
}
}
else
std
::
cout
<<
"Switch off device power and turn it on"
<<
std
::
endl
;
// ping the device
while
(
!
bootloader_connected
)
{
// the motion file is already a binary file
motion_fd
=
fopen
(
opt_motion_file
.
c_str
(),
"r"
);
if
(
!
motion_fd
)
{
printf
(
"Can not find file!
\n
"
);
return
0
;
}
fseek
(
motion_fd
,
0
,
SEEK_END
);
if
(
ftell
(
motion_fd
)
!=
(
long
)(
MEMORY_MAXSIZE
/
2
))
{
printf
(
"The motion file is too short or too large.
\n
"
);
return
0
;
}
rewind
(
motion_fd
);
// read the contents of the file
fread
(
binary_file
,
1
,
MEMORY_MAXSIZE
/
2
,
motion_fd
);
start_address
=
0
;
binary_size
=
MEMORY_MAXSIZE
/
2
;
// close the file
fclose
(
motion_fd
);
}
printf
(
"Press DARwIn-OP's Reset button to start...
\n
"
);
if
(
servo_model
!=
"cm9"
)
{
while
(
!
bootloader_connected
)
{
try
{
event_server
->
wait_all
(
events
,
20
);
num_data
=
serial_port
.
get_num_data
();
serial_port
.
read
((
unsigned
char
*
)
bootloader_data
,
num_data
);
bootloader_data
[
num_data
]
=
'\0'
;
printf
(
"%s"
,
bootloader_data
);
fflush
(
stdout
);
for
(
i
=
0
;
i
<
num_data
;
i
++
)
try
{
event_server
->
wait_all
(
events
,
20
);
num_data
=
serial_port
.
get_num_data
();
serial_port
.
read
((
unsigned
char
*
)
bootloader_data
,
num_data
);
bootloader_data
[
num_data
]
=
'\0'
;
printf
(
"%s"
,
bootloader_data
);
fflush
(
stdout
);
for
(
i
=
0
;
i
<
num_data
;
i
++
)
{
if
(
protocol
==
new_protocol
)
{
if
(
servo_model
==
"mx28"
)
if
(
bootloader_data
[
i
]
==
'#'
)
{
if
(
bootloader_data
[
i
]
==
'#'
)
{
count
++
;
if
(
count
==
5
)
bootloader_connected
=
true
;
}
count
++
;
if
(
count
==
5
)
bootloader_connected
=
true
;
}
else
if
(
servo_model
==
"ax12"
||
servo_model
==
"rx28"
)
}
else
{
if
(
bootloader_data
[
i
]
==
'*'
)
{
if
(
bootloader_data
[
i
]
==
'*'
)
{
count
++
;
if
(
count
==
5
)
bootloader_connected
=
true
;
}
count
++
;
if
(
count
==
5
)
bootloader_connected
=
true
;
}
}
}
catch
(
CEventTimeoutException
&
e
){
// do nothing and retry
serial_port
.
write
((
unsigned
char
*
)
&
bootloader_ping
,
1
);
}
}
catch
(
CEventTimeoutException
&
e
){
// do nothing and retry
serial_port
.
write
((
unsigned
char
*
)
&
bootloader_ping
,
1
);
}
serial_port
.
write
((
unsigned
char
*
)
bootloader_ack
,
1
);
}
if
(
protocol
==
new_protocol
)
{
/* send acknowledgment to the device*/
serial_port
.
write
((
unsigned
char
*
)
&
bootloader_ack
,
1
);
while
(
!
end
)
{
try
{
event_server
->
wait_all
(
events
,
300
0
);
event_server
->
wait_all
(
events
,
300
);
num_data
=
serial_port
.
get_num_data
();
serial_port
.
read
(
bootloader_data
,
num_data
);
bootloader_data
[
num_data
]
=
'\0'
;
...
...
@@ -210,15 +177,16 @@ int main(int argc,char *argv[])
end
=
true
;
}
}
end
=
false
;
}
sleep
(
1
);
end
=
false
;
// start the download
serial_port
.
write
((
unsigned
char
*
)
bootloader_load_hex
,
1
);
serial_port
.
write
((
unsigned
char
*
)
&
bootloader_load
,
1
);
if
(
protocol
==
new_protocol
)
serial_port
.
write
((
unsigned
char
*
)
&
bootloader_ack
,
1
);
while
(
!
end
)
{
try
{
event_server
->
wait_all
(
events
,
300
0
);
event_server
->
wait_all
(
events
,
300
);
num_data
=
serial_port
.
get_num_data
();
serial_port
.
read
(
bootloader_data
,
num_data
);
bootloader_data
[
num_data
]
=
'\0'
;
...
...
@@ -229,126 +197,6 @@ int main(int argc,char *argv[])
end
=
true
;
}
}
sleep
(
1
);
/* if(servo_model=="mx28")
{
end=false;
serial_port.write((unsigned char *)bootloader_ack, 1);
while(!end)
{
try{
event_server->wait_all(events,3000);
num_data=serial_port.get_num_data();
serial_port.read(bootloader_data,num_data);
bootloader_data[num_data]='\0';
printf("%s",bootloader_data);
fflush(stdout);
}catch(CEventTimeoutException &e){
// the flash has been properly erased
end=true;
}
}
sleep(1);
}*/
/* end=false;
while(downloaded_size < binary_size)
{
sleep(1);
end=false;
sprintf(load_hex_address,"l 0x%08x\n",(int)(0x08000000+start_address+downloaded_size));
serial_port.write((unsigned char *)load_hex_address, strlen(load_hex_address));
while(!end)
{
try{
event_server->wait_all(events,1000);
error=true;
num_data=serial_port.get_num_data();
serial_port.read(bootloader_data,num_data);
bootloader_data[num_data]='\0';
printf("%s",bootloader_data);
fflush(stdout);
}catch(CEventTimeoutException &e){
// the flash has been properly erased
if(error)
{
serial_port.close();
return 0;
}
else
end=true;
}
}
sleep(1);
if(servo_model=="mx28")
{
error=false;
end=false;
serial_port.write((unsigned char *)bootloader_ack, 1);
while(!end)
{
try{
event_server->wait_all(events,3000);
num_data=serial_port.get_num_data();
serial_port.read(bootloader_data,num_data);
bootloader_data[num_data]='\0';
printf("%s",bootloader_data);
fflush(stdout);
}catch(CEventTimeoutException &e){
// the flash has been properly erased
if(error)
{
serial_port.close();
return 0;
}
else
end=true;
}
}
sleep(1);
}
block_size=binary_size-downloaded_size;
if(block_size>64*1024)
block_size=64*1024;
// compute the binary file checksum
checksum=0;
for(i=0;i<block_size;i++)
checksum+=binary_file[start_address+downloaded_size+i];
downloaded_block_size=0;
while(downloaded_block_size < block_size)
{
usleep(1000);
small_block_size=block_size-downloaded_block_size;
if(small_block_size>64)
small_block_size=64;
serial_port.write(&binary_file[start_address+downloaded_size+downloaded_block_size],small_block_size);
downloaded_block_size+=small_block_size;
printf("\rDownloading Firmware (%ld/%ld byte)", downloaded_block_size, block_size);
}
downloaded_size+=block_size;
serial_port.write(&checksum,1);
sleep(1);
end=false;
while(!end)
{
try{
event_server->wait_all(events,3000);
// there has been an error
num_data=serial_port.get_num_data();
serial_port.read(bootloader_data,num_data);
bootloader_data[num_data]='\0';
printf("%s",bootloader_data);
}catch(CEventTimeoutException &e){
// no error to report
if(error)
{
serial_port.close();
return 0;
}
else
end=true;
}
}
}*/
// compute the binary file checksum
for
(
i
=
0
;
i
<
binary_size
;
i
++
)
checksum
+=
binary_file
[
start_address
+
i
];
...
...
@@ -356,31 +204,22 @@ int main(int argc,char *argv[])
while
(
downloaded_size
<
binary_size
)
{
usleep
(
1000
);
if
((
num_data
=
serial_port
.
get_num_data
())
!=
0
)
{
serial_port
.
read
(
bootloader_data
,
num_data
);
bootloader_data
[
num_data
]
=
'\0'
;
printf
(
"%s"
,
bootloader_data
);
return
0
;
}
block_size
=
binary_size
-
downloaded_size
;
// if(block_size>64)
// block_size=64;
block_size
=
binary_size
;
if
(
block_size
>
64
)
block_size
=
64
;
serial_port
.
write
(
&
binary_file
[
start_address
+
downloaded_size
],
block_size
);
downloaded_size
+=
block_size
;
printf
(
"
\r
Downloading Firmware (%ld/%ld byte)"
,
downloaded_size
,
binary_size
);
sync
(
);
fflush
(
stdout
);
}
// send the checksum
serial_port
.
write
(
&
checksum
,
1
);
sleep
(
1
);
printf
(
"
\n
Download complete
\n
"
);
std
::
cout
<<
std
::
endl
<<
"Download complete"
<<
std
::
endl
;
end
=
false
;
/*
while(!end)
while
(
!
end
)
{
try
{
event_server->wait_all(events,300
0
);
event_server
->
wait_all
(
events
,
300
);
// there has been an error
num_data
=
serial_port
.
get_num_data
();
serial_port
.
read
(
bootloader_data
,
num_data
);
...
...
@@ -390,37 +229,36 @@ int main(int argc,char *argv[])
// no error to report
end
=
true
;
}
}*/
return
0
;
if
(
opt_fw_file
.
size
()
!=
0
)
}
// start the loaded program
serial_port
.
write
((
unsigned
char
*
)
&
bootloader_go
,
1
);
if
(
protocol
==
new_protocol
)
serial_port
.
write
((
unsigned
char
*
)
&
bootloader_ack
,
1
);
end
=
false
;
while
(
!
end
)
{
// start the loaded program
serial_port
.
write
((
unsigned
char
*
)
bootloader_go
,
4
);
end
=
false
;
while
(
!
end
)
{
try
{
event_server
->
wait_all
(
events
,
1000
);
// there has been an error
num_data
=
serial_port
.
get_num_data
();
serial_port
.
read
(
bootloader_data
,
num_data
);
bootloader_data
[
num_data
]
=
'\0'
;
printf
(
"%s"
,
bootloader_data
);
}
catch
(
CEventTimeoutException
&
e
){
// no error to report
end
=
true
;
}
try
{
event_server
->
wait_all
(
events
,
300
);
// there has been an error
num_data
=
serial_port
.
get_num_data
();
serial_port
.
read
(
bootloader_data
,
num_data
);
bootloader_data
[
num_data
]
=
'\0'
;
printf
(
"%s"
,
bootloader_data
);
}
catch
(
CEventTimeoutException
&
e
){
// no error to report
end
=
true
;
}
}
serial_port
.
close
();
}
catch
(
CException
&
e
){
/* handle exceptions */
printf
(
"%s
\n
"
,
e
.
what
().
c_str
())
;
std
::
cout
<<
e
.
what
()
<<
std
::
endl
;
}
}
}
else
{
/* display the help information and exit */
std
::
cout
<<
"No serial device specified"
<<
std
::
endl
;
show_help
(
argv
[
0
]);
}
}
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment