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
Branches containing commit
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})
...
@@ -18,3 +18,9 @@ ADD_EXECUTABLE(fw_downloader ${sources})
# link necessary libraries
# link necessary libraries
TARGET_LINK_LIBRARIES
(
fw_downloader
${
iriutils_LIBRARY
}
)
TARGET_LINK_LIBRARIES
(
fw_downloader
${
iriutils_LIBRARY
}
)
TARGET_LINK_LIBRARIES
(
fw_downloader
${
comm_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 @@
...
@@ -10,11 +10,26 @@
#include
<iostream>
#include
<iostream>
const
unsigned
char
bootloader_ping
=
'#'
;
const
unsigned
char
bootloader_ping
=
'#'
;
const
unsigned
char
bootloader_ack
[]
=
"
\n
"
;
const
unsigned
char
bootloader_ack
=
'\n'
;
//const unsigned char bootloader_load_hex[]="l 0x08003000\n";
const
unsigned
char
bootloader_load
=
'l'
;
const
unsigned
char
bootloader_load_hex
[]
=
"l"
;
const
unsigned
char
bootloader_go
=
'g'
;
const
unsigned
char
bootloader_load_motion
[]
=
"l 0x08060000
\n
"
;
const
unsigned
char
bootloader_go
[]
=
"
\n
go
\n
"
;
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
[])
int
main
(
int
argc
,
char
*
argv
[])
{
{
...
@@ -25,34 +40,19 @@ int main(int argc,char *argv[])
...
@@ -25,34 +40,19 @@ int main(int argc,char *argv[])
TRS232_config
serial_config
;
TRS232_config
serial_config
;
long
int
num_data
=
0
,
i
=
0
;
long
int
num_data
=
0
,
i
=
0
;
bool
end
=
false
;
bool
end
=
false
;
// input arguments parser variables
int
option
;
static
struct
option
long_options
[]
=
{{
"h"
,
no_argument
,
0
,
0
},
// display help message
std
::
string
opt_device
,
opt_fw_file
;
{
"help"
,
no_argument
,
0
,
0
},
protocol_t
protocol
;
{
"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
;
// binary file variables
// binary file variables
unsigned
char
binary_file
[
MEMORY_MAXSIZE
];
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
start_address
=
0
;
long
int
binary_size
=
0
;
long
int
binary_size
=
0
;
int
block_size
=
0
,
count
=
0
,
small_block_size
=
0
;
int
block_size
=
0
,
count
=
0
;
// bootloader variables
// bootloader variables
unsigned
char
bootloader_data
[
MEMORY_MAXSIZE
];
unsigned
char
bootloader_data
[
MEMORY_MAXSIZE
];
bool
bootloader_connected
=
false
,
error
=
false
;
bool
bootloader_connected
=
false
;
unsigned
char
checksum
=
0x00
;
unsigned
char
checksum
=
0x00
;
char
load_hex_address
[
32
];
// motion file variables
FILE
*
motion_fd
;
// configuration information for the serial device
// configuration information for the serial device
serial_config
.
baud
=
57600
;
serial_config
.
baud
=
57600
;
...
@@ -60,58 +60,47 @@ int main(int argc,char *argv[])
...
@@ -60,58 +60,47 @@ int main(int argc,char *argv[])
serial_config
.
parity
=
none
;
serial_config
.
parity
=
none
;
serial_config
.
stop_bits
=
1
;
serial_config
.
stop_bits
=
1
;
for
(
i
=
0
;
i
<
MEMORY_MAXSIZE
;
i
++
)
memset
(
binary_file
,
0xFF
,
MEMORY_MAXSIZE
);
binary_file
[
i
]
=
0xFF
;
// parse the input arguments
// parse the input arguments
do
{
while
((
option
=
getopt
(
argc
,
argv
,
"hd:f:p:"
))
!=
-
1
)
opt_status
=
getopt_long_only
(
argc
,
argv
,
""
,
long_options
,
&
opt_index
);
{
if
(
opt_status
!=-
1
)
switch
(
option
)
{
{
if
(
opt_status
==
'?'
)
// option not recognized or argument missing
case
'h'
:
// show help message
{
show_help
(
argv
[
0
]);
printf
(
"Unknown option
\n
"
);
break
;
return
0
;
case
'd'
:
// select serial device
/* handle the error and exit */
std
::
cout
<<
"Output device: "
<<
optarg
<<
std
::
endl
;
}
opt_device
=
std
::
string
(
optarg
);
else
// process the argument
break
;
{
case
'f'
:
// select firmware file
switch
(
opt_index
)
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
:
std
::
cout
<<
"Unsupported protocol"
<<
std
::
endl
;
case
1
:
/* display the help information and exit */
show_help
(
argv
[
0
]);
break
;
return
0
;
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
;
}
}
}
break
;
}
}
}
while
(
opt_status
!=-
1
);
}
// check that the two arguments have been entered
// check that the two arguments have been entered
if
(
opt_device
.
size
()
!=
0
)
if
(
opt_device
.
size
()
!=
0
)
{
{
if
(
opt_fw_file
.
size
()
!=
0
&&
opt_motion_file
.
size
()
!=
0
)
if
(
opt_fw_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
)
{
{
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
;
return
0
;
}
}
else
else
...
@@ -129,77 +118,55 @@ int main(int argc,char *argv[])
...
@@ -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
)
if
(
hex2bin
((
char
*
)
opt_fw_file
.
c_str
(),
binary_file
,
&
start_address
,
&
binary_size
)
==
false
)
{
{
serial_port
.
close
();
serial_port
.
close
();
printf
(
"Error converting the firmware hex file
.
\n
"
)
;
std
::
cout
<<
"Error converting the firmware hex file
"
<<
std
::
endl
;
return
0
;
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
try
{
motion_fd
=
fopen
(
opt_motion_file
.
c_str
(),
"r"
);
event_server
->
wait_all
(
events
,
20
);
if
(
!
motion_fd
)
num_data
=
serial_port
.
get_num_data
();
{
serial_port
.
read
((
unsigned
char
*
)
bootloader_data
,
num_data
);
printf
(
"Can not find file!
\n
"
);
bootloader_data
[
num_data
]
=
'\0'
;
return
0
;
printf
(
"%s"
,
bootloader_data
);
}
fflush
(
stdout
);
fseek
(
motion_fd
,
0
,
SEEK_END
);
for
(
i
=
0
;
i
<
num_data
;
i
++
)
if
(
ftell
(
motion_fd
)
!=
(
long
)(
MEMORY_MAXSIZE
/
2
))
{
{
if
(
protocol
==
new_protocol
)
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
++
)
{
{
if
(
servo_model
==
"mx28"
)
if
(
bootloader_data
[
i
]
==
'#'
)
{
{
if
(
bootloader_data
[
i
]
==
'#'
)
count
++
;
{
if
(
count
==
5
)
count
++
;
bootloader_connected
=
true
;
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
)
count
++
;
bootloader_connected
=
true
;
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
)
while
(
!
end
)
{
{
try
{
try
{
event_server
->
wait_all
(
events
,
300
0
);
event_server
->
wait_all
(
events
,
300
);
num_data
=
serial_port
.
get_num_data
();
num_data
=
serial_port
.
get_num_data
();
serial_port
.
read
(
bootloader_data
,
num_data
);
serial_port
.
read
(
bootloader_data
,
num_data
);
bootloader_data
[
num_data
]
=
'\0'
;
bootloader_data
[
num_data
]
=
'\0'
;
...
@@ -210,15 +177,16 @@ int main(int argc,char *argv[])
...
@@ -210,15 +177,16 @@ int main(int argc,char *argv[])
end
=
true
;
end
=
true
;
}
}
}
}
end
=
false
;
}
}
sleep
(
1
);
end
=
false
;
// start the download
// 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
)
while
(
!
end
)
{
{
try
{
try
{
event_server
->
wait_all
(
events
,
300
0
);
event_server
->
wait_all
(
events
,
300
);
num_data
=
serial_port
.
get_num_data
();
num_data
=
serial_port
.
get_num_data
();
serial_port
.
read
(
bootloader_data
,
num_data
);
serial_port
.
read
(
bootloader_data
,
num_data
);
bootloader_data
[
num_data
]
=
'\0'
;
bootloader_data
[
num_data
]
=
'\0'
;
...
@@ -229,126 +197,6 @@ int main(int argc,char *argv[])
...
@@ -229,126 +197,6 @@ int main(int argc,char *argv[])
end
=
true
;
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
// compute the binary file checksum
for
(
i
=
0
;
i
<
binary_size
;
i
++
)
for
(
i
=
0
;
i
<
binary_size
;
i
++
)
checksum
+=
binary_file
[
start_address
+
i
];
checksum
+=
binary_file
[
start_address
+
i
];
...
@@ -356,31 +204,22 @@ int main(int argc,char *argv[])
...
@@ -356,31 +204,22 @@ int main(int argc,char *argv[])
while
(
downloaded_size
<
binary_size
)
while
(
downloaded_size
<
binary_size
)
{
{
usleep
(
1000
);
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
;
block_size
=
binary_size
-
downloaded_size
;
// if(block_size>64)
if
(
block_size
>
64
)
// block_size=64;
block_size
=
64
;
block_size
=
binary_size
;
serial_port
.
write
(
&
binary_file
[
start_address
+
downloaded_size
],
block_size
);
serial_port
.
write
(
&
binary_file
[
start_address
+
downloaded_size
],
block_size
);
downloaded_size
+=
block_size
;
downloaded_size
+=
block_size
;
printf
(
"
\r
Downloading Firmware (%ld/%ld byte)"
,
downloaded_size
,
binary_size
);
printf
(
"
\r
Downloading Firmware (%ld/%ld byte)"
,
downloaded_size
,
binary_size
);
sync
(
);
fflush
(
stdout
);
}
}
// send the checksum
// send the checksum
serial_port
.
write
(
&
checksum
,
1
);
serial_port
.
write
(
&
checksum
,
1
);
sleep
(
1
);
std
::
cout
<<
std
::
endl
<<
"Download complete"
<<
std
::
endl
;
printf
(
"
\n
Download complete
\n
"
);
end
=
false
;
end
=
false
;
/*
while(!end)
while
(
!
end
)
{
{
try
{
try
{
event_server->wait_all(events,300
0
);
event_server
->
wait_all
(
events
,
300
);
// there has been an error
// there has been an error
num_data
=
serial_port
.
get_num_data
();
num_data
=
serial_port
.
get_num_data
();
serial_port
.
read
(
bootloader_data
,
num_data
);
serial_port
.
read
(
bootloader_data
,
num_data
);
...
@@ -390,37 +229,36 @@ int main(int argc,char *argv[])
...
@@ -390,37 +229,36 @@ int main(int argc,char *argv[])
// no error to report
// no error to report
end
=
true
;
end
=
true
;
}
}
}*/
}
return
0
;
// start the loaded program
if
(
opt_fw_file
.
size
()
!=
0
)
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
try
{
serial_port
.
write
((
unsigned
char
*
)
bootloader_go
,
4
);
event_server
->
wait_all
(
events
,
300
);
end
=
false
;
// there has been an error
while
(
!
end
)
num_data
=
serial_port
.
get_num_data
();
{
serial_port
.
read
(
bootloader_data
,
num_data
);
try
{
bootloader_data
[
num_data
]
=
'\0'
;
event_server
->
wait_all
(
events
,
1000
);
printf
(
"%s"
,
bootloader_data
);
// there has been an error
}
catch
(
CEventTimeoutException
&
e
){
num_data
=
serial_port
.
get_num_data
();
// no error to report
serial_port
.
read
(
bootloader_data
,
num_data
);
end
=
true
;
bootloader_data
[
num_data
]
=
'\0'
;
printf
(
"%s"
,
bootloader_data
);
}
catch
(
CEventTimeoutException
&
e
){
// no error to report
end
=
true
;
}
}
}
}
}
serial_port
.
close
();
serial_port
.
close
();
}
catch
(
CException
&
e
){
}
catch
(
CException
&
e
){
/* handle exceptions */
/* handle exceptions */
printf
(
"%s
\n
"
,
e
.
what
().
c_str
())
;
std
::
cout
<<
e
.
what
()
<<
std
::
endl
;
}
}
}
}
}
}
else
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