# hal_procs_lib.tcl package require Hal ;# provides hal commands proc pin_exists {name} { # return 1 if pin exists if { [lindex [hal list pin "$name"] 0] == "$name"} {return 1} return 0 } ;# pin_exists proc connection_info {result_name pinname } { # return 0 if pinname not found, else 1 # result_name is associative array with details # owner type direction value separator signame upvar $result_name ay set ans [hal show pin $pinname] set lines [split $ans \n] set sig "" set sep "" set ct [scan [lindex $lines 2] "%s %s %s %s %s %s %s" \ owner type dir val name sep sig] if {$ct <0} { return 0 } set ay(owner) $owner set ay(type) $type set ay(direction) $dir set ay(value) $val set ay(separator) $sep set ay(signame) $sig return 1 } ;# connection_info proc is_connected {pinname {signame {} } } { # return is_input or is_output or is_io or not_connected # set signame to signal name if connected upvar $signame thesig set ans [hal show pin $pinname] set lines [split $ans \n] set thesig "" set sep "" set ct [scan [lindex $lines 2] "%s %s %s %s %s %s %s" \ owner type dir val name sep thesig] if {$ct <0} {return not_connected} if {"$sep" == "<=="} {return is_input} if {"$sep" == "==>"} {return is_output} if {"$sep" == "<=>"} {return is_io} return "not_connected" } ;# is_connected proc thread_info {ay_name} { # return details about threads in associative array ay_name # items for each $threadname: # ($threadname,$componentname) $threadname index for $componentname # ($threadname,fp) $threadname uses floatingpoint # ($threadname,period) $threadname period # ($threadname,index,last) $threadname last index used # # motion specific items: # (motion-command-handler,threadname) threadname # (motion-command-handler,index) index # (motion-controller,threadname) threadname # (motion-controller,index) index # other: # (threadnames) list of all threanames # # return string is $ay(motion-controller,threadname) upvar $ay_name ay set ans [hal show thread] set lines [split $ans \n] set header_len 2 set lines [lreplace $lines 0 [expr $header_len -1]] set lines [lreplace $lines end end] set remainder "" set ct 0 foreach line $lines { catch {unset f1 f2 f3 f4} scan [lindex $lines $ct] \ "%s %s %s %s" \ f1 f2 f3 f4 if ![info exists f3] { set index $f1; set compname $f2 set ay($threadname,$compname) $index set ay($threadname,index,last) $index if {"$compname" == "motion-command-handler"} { set ay(motion-command-handler,threadname) $threadname set ay(motion-command-handler,index) $index } if {"$compname" == "motion-controller"} { set ay(motion-controller,threadname) $threadname set ay(motion-controller,index) $index } } else { set period $f1; set fp $f2; set threadname $f3 lappend ay(threadnames) $threadname set ay($threadname,fp) $fp set ay($threadname,period) $period } incr ct } if [info exists ay(motion-controller,threadname)] { if [info exists ay(motion-command-handler,threadname)] { if { "$ay(motion-controller,threadname)" \ != "$ay(motion-command-handler,threadname)" \ } { return -code error "thread_info: mot funcs on separate threads" if { $ay(motion-command-handler,index) \ > $ay(motion-controller,index) \ } { return -code error "thread_info: mot funcs OUT-OF-SEQUENCE" } } return $ay(motion-controller,threadname) } else { return -code error "thread_info: motion-controller not found" } } } ;# thread_info proc get_netlist {inpins_name outpin_name iopins_name signame} { # input: signame # outputs: # inpins_name list of input pins for signame or "" # iopins_name list of io pins for signame or "" # outpin_name output pin for signame or "" upvar $inpins_name inpins upvar $iopins_name iopins upvar $outpin_name outpin set inpins "" set iopins "" set outpin "" set header_len 2 set lines [split [hal show signal $signame] \n] set lines [lreplace $lines 0 [expr $header_len -1]] set lines [lreplace $lines end end] set ct 0 foreach line $lines {set l($ct) [string trim $line];incr ct} set ct_max $ct set ct 0 for {set ct 0} {$ct < $ct_max} {incr ct} { set v0 [lindex $l($ct) 0] set v1 [lindex $l($ct) 1] set v2 [lindex $l($ct) 2] switch $v0 { float - bit - u32 - s32 {set sname $v2} ;# set on 1st non-header line "==>" {} "<==" {} "<=>" {} * {return -code error "get_netlist: Unexpected <$line">} } if {"$signame"=="$sname"} { switch $v0 { "==>" {lappend inpins $v1} "<==" {lappend outpin $v1} "<=>" {lappend iopins $v1} } } } } ;# get_netlist proc find_file_in_hallib_path {filename {inifile .}} { # find halfile using path HALLIB_PATH=.:HALLIB_DIR (see scripts/linuxcnc.in) set libtag LIB: ;# special prefix for explicit use of hallib file set halname [lindex $filename end] if {[string first "$libtag" $halname] == 0} { # explicit $libtag used set halname [string range $halname [string len $libtag] end] set usehalname [file join $::env(HALLIB_DIR) $halname] } else { if {[file pathtype $filename] == "absolute"} { set usehalname $filename } else { # relative file specifier (relative to INI file directory) set usehalname [file join [file dirname $inifile] $halname] if ![file readable $usehalname] { # use ::env(HALLIB_DIR) set usehalname [file join $::env(HALLIB_DIR) $halname] } } } if [file readable $usehalname] { return $usehalname } return -code error "find_file_in_hallib_path: cannot find: <$filename>" } ;# find_file_in_hallib_path