1 |
10 |
wfjm |
#! /usr/bin/env tclsh
|
2 |
|
|
# -*- tcl -*-
|
3 |
12 |
wfjm |
# $Id: ti_rri 386 2011-07-01 17:31:03Z mueller $
|
4 |
10 |
wfjm |
#
|
5 |
|
|
# Copyright 2011- by Walter F.J. Mueller
|
6 |
|
|
#
|
7 |
|
|
# This program is free software; you may redistribute and/or modify it under
|
8 |
|
|
# the terms of the GNU General Public License as published by the Free
|
9 |
|
|
# Software Foundation, either version 2, or at your option any later version.
|
10 |
|
|
#
|
11 |
|
|
# This program is distributed in the hope that it will be useful, but
|
12 |
|
|
# WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY
|
13 |
|
|
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
14 |
|
|
# for complete details.
|
15 |
|
|
#
|
16 |
|
|
# Revision History:
|
17 |
|
|
# Date Rev Version Comment
|
18 |
12 |
wfjm |
# 2011-04-22 379 1.0.1 check for RETROBASE; proper exit handling; help text
|
19 |
11 |
wfjm |
# 2011-04-17 376 1.0 Initial version
|
20 |
10 |
wfjm |
# 2011-03-19 371 0.1 First draft
|
21 |
|
|
#
|
22 |
|
|
#
|
23 |
|
|
# --fifo[=name,keep]
|
24 |
11 |
wfjm |
# --term[=name,baud,break]
|
25 |
10 |
wfjm |
# --run=command
|
26 |
|
|
# --log=filename ; default "-"
|
27 |
|
|
# --logl=n ; default 2
|
28 |
|
|
# --dmpl=n ; default 0
|
29 |
|
|
# --tiol=n ; default 0
|
30 |
|
|
# --int
|
31 |
|
|
# --help
|
32 |
|
|
# --
|
33 |
|
|
# tcl cmds
|
34 |
|
|
# @...tcl
|
35 |
|
|
#
|
36 |
|
|
|
37 |
|
|
array set opts {
|
38 |
|
|
fifo 0
|
39 |
|
|
fifo_ ""
|
40 |
|
|
term 0
|
41 |
|
|
term_ ""
|
42 |
|
|
run_ ""
|
43 |
|
|
log_ "-"
|
44 |
|
|
logl_ 2
|
45 |
|
|
dmpl_ 0
|
46 |
|
|
tiol_ 0
|
47 |
|
|
int 0
|
48 |
|
|
help 0
|
49 |
|
|
}
|
50 |
|
|
|
51 |
|
|
set clist {}
|
52 |
|
|
set optsendseen 0
|
53 |
12 |
wfjm |
set runpid {}
|
54 |
10 |
wfjm |
|
55 |
12 |
wfjm |
#
|
56 |
|
|
# cleanup handler
|
57 |
|
|
# must be in a proc so that it can be called from tclreadline
|
58 |
|
|
# must be defined before ::tclreadline::Loop called (all after ignored...)
|
59 |
|
|
#
|
60 |
|
|
proc exit_cleanup {} {
|
61 |
|
|
global opts
|
62 |
|
|
global runpid
|
63 |
|
|
|
64 |
|
|
# now close rlink connection
|
65 |
|
|
if { $opts(fifo) || $opts(term) } {
|
66 |
|
|
rlc close
|
67 |
|
|
}
|
68 |
|
|
|
69 |
|
|
# FIXME_code: should sync here with -run process run-down
|
70 |
|
|
# but no wait available in tcl (grr...)
|
71 |
|
|
if { "$runpid" ne "" } {
|
72 |
|
|
after 100; # currently just wait 100ms
|
73 |
|
|
}
|
74 |
|
|
return
|
75 |
|
|
}
|
76 |
|
|
|
77 |
10 |
wfjm |
foreach arg $argv {
|
78 |
|
|
if { $optsendseen } {
|
79 |
|
|
lappend clist $arg
|
80 |
|
|
continue
|
81 |
|
|
}
|
82 |
|
|
switch -regexp -- $arg {
|
83 |
|
|
^--?fifo=?.*$ { set opts(fifo) 1; regexp -- {=(.*)} $arg dummy opts(fifo_) }
|
84 |
|
|
^--?term=?.*$ { set opts(term) 1; regexp -- {=(.*)} $arg dummy opts(term_) }
|
85 |
|
|
^--?run=.+$ { regexp -- {=(.*)} $arg dummy opts(run_) }
|
86 |
|
|
^--?log=.+$ { regexp -- {=(.*)} $arg dummy opts(log_) }
|
87 |
|
|
^--?logl=.+$ { regexp -- {=(.*)} $arg dummy opts(logl_) }
|
88 |
|
|
^--?dmpl=.+$ { regexp -- {=(.*)} $arg dummy opts(dmpl_) }
|
89 |
|
|
^--?tiol=.+$ { regexp -- {=(.*)} $arg dummy opts(tiol_) }
|
90 |
|
|
^--?int$ { set opts(int) 1 }
|
91 |
|
|
^--?help$ { set opts(help) 1 }
|
92 |
|
|
^--$ { set optsendseen 1 }
|
93 |
|
|
^--.+$ { puts "-E: bad option $arg, see --help for proper usage"
|
94 |
|
|
return 1
|
95 |
|
|
}
|
96 |
|
|
default { lappend clist $arg }
|
97 |
|
|
}
|
98 |
|
|
}
|
99 |
|
|
|
100 |
|
|
if { $opts(help) } {
|
101 |
12 |
wfjm |
# use {} as defimiter here to avoid that escaping of all []
|
102 |
|
|
puts {usage: ti_rri [OPTION]... [COMMAND]...}
|
103 |
|
|
puts {}
|
104 |
|
|
puts {Options:}
|
105 |
|
|
puts { --run=CMD exec's CMD as subprocess before the rlink port opened}
|
106 |
|
|
puts { useful to start test benches, usually via 'tbw'}
|
107 |
|
|
puts { --fifo[=ARGS] open fifo type rlink port. Optional arguments are:}
|
108 |
|
|
puts { --fifo=[NAME[,KEEP]]}
|
109 |
|
|
puts { NAME fifo name prefix, default 'rlink_cext_fifo'}
|
110 |
|
|
puts { KEEP if non-empty the fifo is kept open on exit}
|
111 |
|
|
puts { --term[=ARGS] open term type rlink port. Optional arguments are:}
|
112 |
|
|
puts { --term=[NAME,[BAUD,[BREAK]]]}
|
113 |
|
|
puts { NAME tty device name, default 'USB0'}
|
114 |
|
|
puts { if not starting with '/' the name is}
|
115 |
|
|
puts { prefixed with '/dev/tty'}
|
116 |
|
|
puts { BAUD serial port baud rate, default '115k'}
|
117 |
|
|
puts { allowed baud rate settings are:}
|
118 |
|
|
puts { 9600, 19200, 19k, 38400, 38k, 57600, 57k}
|
119 |
|
|
puts { 115200, 115k, 230400, 230k, 460800, 460k}
|
120 |
|
|
puts { 500000, 500k, 921600, 921k, 1000000, 1M}
|
121 |
|
|
puts { 2000000, 2M, 3000000, 3M}
|
122 |
|
|
puts { --log=FILE set log file name. Default is to write to stdout.}
|
123 |
|
|
puts { --logl=LVL set log level, default is '2' allowed values:}
|
124 |
|
|
puts { 0 no logging}
|
125 |
|
|
puts { 1 log rlink commands with communication errors}
|
126 |
|
|
puts { 2 log rlink commands with failed checks}
|
127 |
|
|
puts { 3 log all rlink commands}
|
128 |
|
|
puts { --dmpl=LVL set dump level, default is '0', values like logl}
|
129 |
|
|
puts { --tiol=LVL set i/o trace level, default is '0', allowed values:}
|
130 |
|
|
puts { 0 no i/o trace}
|
131 |
|
|
puts { 1 trace buffer activities}
|
132 |
|
|
puts { 2 trace character activities}
|
133 |
|
|
puts { --int enter interactive mode even when commands given}
|
134 |
|
|
puts { --help display this help and exit}
|
135 |
|
|
puts { -- all following arguments are treated as tcl commands}
|
136 |
|
|
puts {}
|
137 |
|
|
puts {Command handling:}
|
138 |
|
|
puts { For arguments of the form '@.tcl' the respective file is}
|
139 |
|
|
puts { sourced. All other arguments are treated as Tcl commands and executed}
|
140 |
|
|
puts { with eval.}
|
141 |
|
|
puts {}
|
142 |
|
|
puts {For further details consults the ti_rri man page.}
|
143 |
10 |
wfjm |
return 0
|
144 |
|
|
}
|
145 |
|
|
|
146 |
12 |
wfjm |
if {![info exists env(RETROBASE)]} {
|
147 |
|
|
puts "-E: RETROBASE environment variable not defined"
|
148 |
|
|
return 1
|
149 |
|
|
}
|
150 |
|
|
|
151 |
10 |
wfjm |
if { $opts(fifo) && $opts(term) } {
|
152 |
|
|
puts "-E: both --fifo and --term given, only one allowed"
|
153 |
|
|
return 1
|
154 |
|
|
}
|
155 |
|
|
|
156 |
|
|
lappend auto_path [file join $env(RETROBASE) tools tcl]
|
157 |
|
|
lappend auto_path [file join $env(RETROBASE) tools lib]
|
158 |
|
|
|
159 |
|
|
package require rlink
|
160 |
|
|
package require rutiltpp
|
161 |
|
|
package require rlinktpp
|
162 |
|
|
|
163 |
|
|
rlinkconnect rlc
|
164 |
|
|
|
165 |
|
|
# setup logging
|
166 |
|
|
if { $opts(log_) ne "-" } {
|
167 |
|
|
rlc config -logfile $opts(log_)
|
168 |
|
|
}
|
169 |
|
|
rlc config -logprintlevel $opts(logl_)
|
170 |
|
|
rlc config -logdumplevel $opts(dmpl_)
|
171 |
|
|
rlc config -logtracelevel $opts(tiol_)
|
172 |
|
|
|
173 |
12 |
wfjm |
# first start, if specified with --run, the test bench
|
174 |
10 |
wfjm |
if { $opts(run_) ne "" } {
|
175 |
|
|
if { [catch {eval "exec $opts(run_) &" } runpid] } {
|
176 |
|
|
puts "-E: failed to execute \"$opts(run_)\" with error message\n $runpid"
|
177 |
|
|
puts "aborting..."
|
178 |
|
|
return 1
|
179 |
|
|
}
|
180 |
|
|
}
|
181 |
|
|
|
182 |
|
|
# than open the rlink connection
|
183 |
|
|
# handle --fifo
|
184 |
|
|
if { $opts(fifo) } {
|
185 |
|
|
set nlist [split $opts(fifo_) ","]
|
186 |
|
|
set path [lindex $nlist 0]
|
187 |
|
|
set keep [lindex $nlist 1]
|
188 |
|
|
if {$path eq ""} {set path "rlink_cext_fifo"}
|
189 |
|
|
set url "fifo:$path"
|
190 |
|
|
if {$keep ne ""} {append url "?keep"}
|
191 |
|
|
rlc open $url
|
192 |
|
|
}
|
193 |
|
|
|
194 |
|
|
# handle --term
|
195 |
|
|
if { $opts(term) } {
|
196 |
|
|
set nlist [split $opts(term_) ","]
|
197 |
|
|
set dev [lindex $nlist 0]
|
198 |
|
|
set baud [lindex $nlist 1]
|
199 |
|
|
set brk [lindex $nlist 2]
|
200 |
11 |
wfjm |
if {$dev eq ""} {set dev "USB0"}
|
201 |
10 |
wfjm |
if {$baud eq ""} {set baud "115k"}
|
202 |
12 |
wfjm |
if {! [regexp -- {^/} $dev]} {
|
203 |
11 |
wfjm |
set dev "/dev/tty$dev"
|
204 |
|
|
}
|
205 |
10 |
wfjm |
set url "term:$dev?baud=$baud"
|
206 |
|
|
if {$brk ne ""} {append url ";break"}
|
207 |
|
|
rlc open $url
|
208 |
|
|
}
|
209 |
|
|
|
210 |
|
|
# setup simulation mode default
|
211 |
|
|
set rlink::sim_mode [rlink::isfifo]
|
212 |
|
|
|
213 |
|
|
foreach cmd $clist {
|
214 |
|
|
# handle @filename commands
|
215 |
|
|
if { [regexp {^@(.+)} $cmd dummy filename] } {
|
216 |
|
|
# handle @file.tcl --> source tcl file
|
217 |
|
|
if { [regexp {\.tcl$} $filename] } {
|
218 |
|
|
if { [catch {source $filename} errmsg] } {
|
219 |
|
|
puts "-E: failed to source file \"$filename\" with error message:"
|
220 |
|
|
if {[info exists errorInfo]} {puts $errorInfo} else {puts $errmsg}
|
221 |
|
|
puts "aborting..."
|
222 |
|
|
break
|
223 |
|
|
}
|
224 |
|
|
# handle @file.dat ect --> not yet supported
|
225 |
|
|
} else {
|
226 |
|
|
puts "-E: only tcl supported but $filename found"
|
227 |
|
|
puts "aborting..."
|
228 |
|
|
break
|
229 |
|
|
}
|
230 |
|
|
|
231 |
|
|
# handle normal tcl commands --> eval them
|
232 |
|
|
} else {
|
233 |
|
|
if { [catch {eval $cmd} errmsg] } {
|
234 |
|
|
puts "-E: eval of \"$cmd\" failed with error message:"
|
235 |
|
|
if {[info exists errorInfo]} {puts $errorInfo} else {puts $errmsg}
|
236 |
|
|
puts "aborting..."
|
237 |
|
|
break
|
238 |
|
|
}
|
239 |
|
|
}
|
240 |
|
|
}
|
241 |
|
|
|
242 |
|
|
# if tclsh runs a script given on the command line or is invoked
|
243 |
|
|
# like here via a shebang the tcl_interactive is always set to 0
|
244 |
|
|
# so we have to check whether stdin/stdout is a terminal and set
|
245 |
|
|
# tcl_interactive accordingly
|
246 |
|
|
|
247 |
|
|
# FIXME_code: fstat not available (grr...), currently just assume istty
|
248 |
|
|
set tcl_interactive 1
|
249 |
|
|
|
250 |
|
|
if { $opts(int) || [llength $clist] == 0 } {
|
251 |
|
|
if {$tcl_interactive} {
|
252 |
|
|
package require tclreadline
|
253 |
|
|
namespace eval tclreadline {
|
254 |
|
|
proc prompt1 {} {
|
255 |
|
|
set version [info tclversion]
|
256 |
|
|
return "ti_rri > "
|
257 |
|
|
}
|
258 |
|
|
}
|
259 |
12 |
wfjm |
::tclreadline::readline eofchar {::exit_cleanup; puts {}; exit}
|
260 |
10 |
wfjm |
::tclreadline::Loop
|
261 |
|
|
}
|
262 |
12 |
wfjm |
} else {
|
263 |
|
|
exit_cleanup
|
264 |
10 |
wfjm |
}
|
265 |
|
|
|
266 |
|
|
return 0
|