openmsp430-loader
This simple program allows the user to load the openMSP430 program memory with an executable file (ELF or Intel-HEX format) provided as argument.
It is typically used in conjunction with 'make' in order to automatically load the program after the compile step (see 'Makefile' from software examples provided with the project's FPGA implementation).
openmsp430-loader.tcl
1 #!/usr/bin/tclsh 2 #------------------------------------------------------------------------------ 3 # File Name: openmsp430-loader.tcl 4 #------------------------------------------------------------------------------ 5 6 global omsp_conf 7 global omsp_info 8 9 ############################################################################### 10 # SOURCE LIBRARIES # 11 ############################################################################### 12 13 # Get library path 14 set current_file [info script] 15 if {[file type $current_file]=="link"} { 16 set current_file [file readlink $current_file] 17 } 18 set lib_path [file dirname $current_file]/../lib/tcl-lib 19 20 # Source library 21 source $lib_path/dbg_functions.tcl 22 source $lib_path/dbg_utils.tcl 23 25 ############################################################################### 26 # PARAMETER CHECK # 27 ############################################################################### 28 #proc GetAllowedSpeeds 29 30 proc help {} { 31 puts "" 32 puts "USAGE : openmsp430-loader.tcl \[-device <communication port>\]" 33 puts " \[-adaptor <adaptor type>\]" 34 puts " \[-speed <communication speed>\]" 35 puts " \[-i2c_addr <cpu address>\] <elf/ihex-file>" 36 puts "" 37 puts "DEFAULT : <communication port> = /dev/ttyUSB0" 38 puts " <adaptor type> = uart_generic" 39 puts " <communication speed> = 115200 (for UART) / I2C_S_100KHZ (for I2C)" 40 puts " <core address> = 42" 41 puts "" 42 puts "EXAMPLES: openmsp430-loader.tcl -device /dev/ttyUSB0 -adaptor uart_generic -speed 9600 leds.elf" 43 puts " openmsp430-loader.tcl -device COM2: -adaptor i2c_usb-iss -speed I2C_S_100KHZ -i2c_addr 75 ta_uart.ihex" 44 puts "" 45 } 46 47 # Default values 48 set omsp_conf(interface) uart_generic 49 set omsp_conf(device) /dev/ttyUSB0 50 set omsp_conf(baudrate) [lindex [GetAllowedSpeeds] 1] 51 set omsp_conf(0,cpuaddr) 42 52 set elf_file -1 53 set bin_file "[clock clicks].bin" 54 55 # Parse arguments 56 for {set i 0} {$i < $argc} {incr i} { 57 switch -exact -- [lindex $argv $i] { 58 -device {set omsp_conf(device) [lindex $argv [expr $i+1]]; incr i} 59 -adaptor {set omsp_conf(interface) [lindex $argv [expr $i+1]]; incr i} 60 -speed {set omsp_conf(baudrate) [lindex $argv [expr $i+1]]; incr i} 61 -i2c_addr {set omsp_conf(0,cpuaddr) [lindex $argv [expr $i+1]]; incr i} 62 default {set elf_file [lindex $argv $i]} 63 } 64 } 65 66 # Make sure arugments were specified 67 if {[string eq $elf_file -1]} { 68 puts "\nERROR: ELF/IHEX file isn't specified" 69 help 70 exit 1 71 } 72 73 # Make sure the elf file exists 74 if {![file exists $elf_file]} { 75 puts "\nERROR: Specified ELF/IHEX file doesn't exist" 76 help 77 exit 1 78 } 79 80 # Make sure the selected adptor is valid 81 if {![string eq $omsp_conf(interface) "uart_generic"] & 82 ![string eq $omsp_conf(interface) "i2c_usb-iss"]} { 83 puts "\nERROR: Specified adaptor is not valid (should be \"uart_generic\" or \"i2c_usb-iss\")" 84 help 85 exit 1 86 } 87 88 # Make sure the I2C address is an integer 89 if {![string is integer $omsp_conf(0,cpuaddr)]} { 90 puts "\nERROR: Specified I2C address is not an integer" 91 help 92 exit 1 93 } 94 95 # Make sure the I2C address is valid 96 if {($omsp_conf(0,cpuaddr)<8) | ($omsp_conf(0,cpuaddr)>119)} { 97 puts "\nERROR: Specified I2C address should lay between 7 and 120" 98 help 99 exit 1 100 } 101 102 # If the selected interface is a UART, make sure the selected speed is an integer 103 if {[string eq $omsp_conf(interface) "uart_generic"]} { 104 if {![string is integer $omsp_conf(baudrate)]} { 105 puts "\nERROR: Specified UART communication speed is not an integer" 106 help 107 exit 1 108 } 109 } elseif {[string eq $omsp_conf(interface) "i2c_usb-iss"]} { 110 if {[lsearch [lindex [GetAllowedSpeeds] 2] $omsp_conf(baudrate)]==-1} { 111 puts "\nERROR: Specified I2C communication speed is not valid." 112 puts " Allowed values are:" 113 foreach allowedVal [lindex [GetAllowedSpeeds] 2] { 114 puts " - $allowedVal" 115 } 116 puts "" 117 exit 1 118 } 119 } 120 122 ############################################################################### 123 # CREATE AND READ BINARY EXECUTABLE FILE # 124 ############################################################################### 125 126 # Detect the file format depending on the fil extention 127 set fileType [file extension $elf_file] 128 set fileType [string tolower $fileType] 129 regsub {\.} $fileType {} fileType 130 if {![string eq $fileType "ihex"] & ![string eq $fileType "hex"] & ![string eq $fileType "elf"]} { 131 puts "\nERROR: [string toupper $fileType] file format not supported" 132 return 0 133 } 134 if {[string eq $fileType "hex"]} { 135 set fileType "ihex" 136 } 137 if {[string eq $fileType "elf"]} { 138 set fileType "elf32-msp430" 139 } 140 141 # Generate binary file 142 if {[catch {exec msp430-objcopy -I $fileType -O binary $elf_file $bin_file} errMsg]} { 143 puts $errMsg 144 exit 1 145 } 146 147 # Wait until bin file is present on the filesystem 148 set timeout 100 149 for {set i 0} {$i <= $timeout} {incr i} { 150 after 500 151 if {[file exists $bin_file]} { 152 break 153 } 154 } 155 if {$i>=$timeout} { 156 puts "\nTimeout: ELF to BIN file conversion problem with \"msp430-objcopy\" executable" 157 puts "$errMsg" 158 exit 1 159 } 160 161 # Read file 162 set fp [open $bin_file r] 163 fconfigure $fp -translation binary 164 binary scan [read $fp] H* hex_data yop 165 close $fp 166 167 # Cleanup 168 file delete $bin_file 169 170 # Get program size 171 set hex_size [string length $hex_data] 172 set byte_size [expr $hex_size/2] 173 set word_size [expr $byte_size/2] 174 175 # Format data 176 for {set i 0} {$i < $hex_size} {set i [expr $i+4]} { 177 set hex_msb "[string index $hex_data [expr $i+2]][string index $hex_data [expr $i+3]]" 178 set hex_lsb "[string index $hex_data [expr $i+0]][string index $hex_data [expr $i+1]]" 179 lappend DataArray "0x$hex_msb$hex_lsb" 180 } 181 183 ############################################################################### 184 # LOAD PROGRAM TO OPENMSP430 TARGET # 185 ############################################################################### 186 187 # Connect to target and stop CPU 188 puts "" 189 puts -nonewline "Connecting with the openMSP430 ($omsp_conf(device), $omsp_conf(baudrate)\ bps)... " 190 flush stdout 191 if {![GetDevice 0]} { 192 puts "failed" 193 puts "Could not open $omsp_conf(device)" 194 puts "Available serial ports are:" 195 foreach port [utils::uart_port_list] { 196 puts " - $port" 197 } 198 if {[string eq $omsp_conf(interface) "i2c_usb-iss"]} { 199 puts "\nMake sure the specified I2C device address is correct: $omsp_conf(0,cpuaddr)\n" 200 } 201 exit 1 202 } 203 ExecutePOR_Halt 0 204 puts "done" 205 set sizes [GetCPU_ID_SIZE 0] 206 207 if {$omsp_info(0,alias)!=""} { 208 puts "Connected: target device identified as $omsp_info(0,alias)." 209 } 210 puts "Connected: target device has [lindex $sizes 0]B Program Memory and [lindex $sizes 1]B Data Memory" 211 puts "" 212 213 # Make sure ELF program size is the same as the available program memory 214 if {[lindex $sizes 0] != [expr $hex_size/2]} { 215 puts "ERROR: ELF program size ($byte_size B) is different than the available program memory ([lindex $sizes 0] B)" 216 exit 1 217 } 218 219 # Load Program Memory 220 set StartAddr [format "0x%04x" [expr 0x10000-$byte_size]] 221 puts -nonewline "Load Program Memory... " 222 flush stdout 223 WriteMemQuick 0 $StartAddr $DataArray 224 after 500 225 puts "done" 226 227 # Check Data 228 puts -nonewline "Verify Program Memory... " 229 flush stdout 230 if {[VerifyMem 0 $StartAddr $DataArray 1]} { 231 puts "done" 232 } else { 233 puts "ERROR" 234 exit 1 235 } 236 237 # Release device 238 ReleaseDevice 0 0xfffe