X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Fhelper%2Fstartup.tcl;h=0ac1ebd71d4f776173b8ff3e44166a0a89e3d432;hp=4e12e30baae091824d06ce374c6a3ab84b06d725;hb=c2120ba28a7f3c473c05403e6015c95bec406336;hpb=6c0553c8c504d4c6da20857abeec80648d841b72 diff --git a/src/helper/startup.tcl b/src/helper/startup.tcl index 4e12e30baa..0ac1ebd71d 100644 --- a/src/helper/startup.tcl +++ b/src/helper/startup.tcl @@ -93,20 +93,6 @@ proc help {args} { add_help_text help "Tcl implementation of help command" -#a bit of backwards compatibility -proc ocd_throw {cmd} { - set ocd_output "" - eval $cmd - return $ocd_output -} - -#a bit of backwards compatibility -proc openocd {cmd} { - set ocd_output "" - eval $cmd - return $ocd_output -} - # If a fn is unknown to Tcl, we try to execute it as an OpenOCD command # # We also support two level commands. "flash banks" is translated to @@ -123,31 +109,55 @@ proc unknown {args} { return -code error "Unknown command: $args" } +proc new_target_name { } { + return [target number [expr [target count] - 1 ]] +} + proc target_script {target_num eventname scriptname} { - if {[string compare $eventname reset]==0} { - set eventname post_reset - } - # This is the script we invoke - proc "target_[set eventname]_[set target_num]" {} "script $scriptname" + set tname [target number $target_num] + if { 0 == [string compare $eventname "reset"] } { + $tname configure -event reset-init "script $scriptname" + return + } + + if { 0 == [string compare $eventname "post_reset"] } { + $tname configure -event reset-init "script $scriptname" + return + } + + if { 0 == [string compare $eventname "pre_reset"] } { + $tname configure -event reset-start "script $scriptname" + return + } + + if { 0 == [string compare $eventname "gdb_program_config"] } { + $tname configure -event old-gdb_program_config "script $scriptname" + return + } + + return -code error "Unknown target (old) event: $eventname (try $tname configure -event NAME)" + } +add_help_text target_script "DEPRECATED please see the new TARGETNAME configure -event interface" + # Try flipping / and \ to find file if the filename does not # match the precise spelling proc find {filename} { if {[catch {ocd_find $filename} t]==0} { return $t - } + } if {[catch {ocd_find [string map {\ /} $filename} t]==0} { return $t - } + } if {[catch {ocd_find [string map {/ \\} $filename} t]==0} { return $t - } + } # make sure error message matches original input string - return [ocd_find $filename] + return -code error "Can't find $filename" } add_help_text find " - print full path to file according to OpenOCD search rules" @@ -162,5 +172,147 @@ proc script {filename} { add_help_text script " - filename of OpenOCD script (tcl) to run" -add_help_text target_script " " +# Handle GDB 'R' packet. Can be overriden by configuration script, +# but it's not something one would expect target scripts to do +# normally +proc ocd_gdb_restart {target_num} { + # Fix!!! we're resetting all targets here! Really we should reset only + # one target + reset halt +} + +# If RCLK is not supported, use fallback_speed_khz +proc jtag_rclk {fallback_speed_khz} { + if {[catch {jtag_khz 0}]!=0} { + jtag_khz $fallback_speed_khz + } +} + +add_help_text jtag_rclk "fallback_speed_khz - set JTAG speed to RCLK or use fallback speed" + +proc ocd_process_reset { MODE } { + + # If this target must be halted... + set halt -1 + if { 0 == [string compare $MODE halt] } { + set halt 1 + } + if { 0 == [string compare $MODE init] } { + set halt 1; + } + if { 0 == [string compare $MODE run ] } { + set halt 0; + } + if { $halt < 0 } { + return -error "Invalid mode: $MODE, must be one of: halt, init, or run"; + } + + foreach t [ target names ] { + # New event script. + $t invoke-event reset-start + } + + # Init the tap controller. + jtag arp_init-reset + # Examine all targets. + foreach t [ target names ] { + $t arp_examine + } + + # Let the C code know we are asserting reset. + foreach t [ target names ] { + $t invoke-event reset-assert-pre + # C code needs to know if we expect to 'halt' + $t arp_reset assert $halt + $t invoke-event reset-assert-post + } + + # Now de-assert reset. + foreach t [ target names ] { + $t invoke-event reset-deassert-pre + # Again, de-assert code needs to know.. + $t arp_reset deassert $halt + $t invoke-event reset-deassert-post + } + + # Pass 1 - Now try to halt. + if { $halt } { + foreach t [target names] { + + # Wait upto 1 second for target to halt. Why 1sec? Cause + # the JTAG tap reset signal might be hooked to a slow + # resistor/capacitor circuit - and it might take a while + # to charge + + # Catch, but ignore any errors. + catch { $t arp_waitstate halted 1000 } + + # Did we succeed? + set s [$t curstate] + + if { 0 != [string compare $s "halted" ] } { + return -error [format "TARGET: %s - Not halted" $t] + } + } + } + + #Pass 2 - if needed "init" + if { 0 == [string compare init $MODE] } { + foreach t [target names] { + set err [catch "$t arp_waitstate halted 5000"] + # Did it halt? + if { $err == 0 } { + $t invoke-event reset-init + } + } + } + + foreach t [ target names ] { + $t invoke-event reset-end + } +} + +# stubs for targets scripts that do not have production procedure +proc production_info {} { + return "Imagine an explanation here..." +} +add_help_text production_info "Displays information on production procedure for target script" + +proc production {firmwarefile serialnumber} { + puts "Imagine production procedure running successfully. Programmed $firmwarefile with serial number $serialnumber" +} + +add_help_text production "Runs production procedure. Throws exception if procedure failed. Prints progress messages." + +proc production_test {} { + puts "Imagine nifty test procedure having run to completion here." +} +add_help_text production "Runs test procedure. Throws exception if procedure failed. Prints progress messages." + +proc load {args} { + return [eval "load_image $args"] +} +add_help_text load "synonym to load_image" + +proc verify {args} { + return [eval "verify_image $args"] +} + +add_help_text verify "synonym to verify_image" + + +add_help_text telnet_async " - enable/disable async messages. Default 0." + +global telnet_async_state +set telnet_async_state 0 +proc telnet_async {state} { + global telnet_async_state + if {[string compare $state enable]==0} { + set telnet_async_state 1 + } elseif {[string compare $state disable]==0} { + set telnet_async_state 0 + } else { + return -code error "Illegal option $state" + } +} \ No newline at end of file