Tcl on VxWorks(出自Tcl.tk的wiki)
发布:much | 发布时间: 2010年1月18日文章为转载,出处为tcl官方网站的wiki
This file is far from being a readily mergeable patch -- see some of the ugly technical details below -- but it should get someone started who is desperate to run Tcl on VxWorks.These instructions will result in a Tcl DKM (downloadable kernel module) that can be run and interacted with on the console. Running as a VxWorks RTP (real-time process) mode is not supported, although that should be a comparatively small step.
Building Tcl for VxWorks
These instructions are for a cross-build from
to, for reference, the "SIMNTgnu" target (which is the Windows-based VxWorks simulator that comes with Workbench) from the
command line. For other targets, update the tools and their parameters accordingly (e.g., use the
ccppc
compiler instead of
ccpentium
for PowerPC targets).
Apply VxWorks Patch
Download the Tcl 8.5.2 source code.Download the patch:
http://sourceforge.net/tracker/download.php?group_id=10894&atid=360894&file_id=276425&aid=1955146
(this is a plain-text file).Apply the patch to the Tcl 8.5.2 source code using the "patch" program.
Configure for SIMNTgnu
Some of these settings must be adjusted based on your target.
export WIND_BASE="c:\\WindRiver\\vxworks-6.3" export CC="ccpentium" export CPPFLAGS="-D_WRS_KERNEL -DCPU=SIMNT -DTOOL_FAMILY=gnu -DTOOL=gnu -Ic:/WindRiver/vxworks-6.3/target/h -Ic:/WindRiver/vxworks-6.3/target/h/wrn/coreip -DUSE_FIONBIO" export CFLAGS="-mtune=i486 -march=i486 -ansi" export LDFLAGS="-r -nostdlib" export EXTRA_TCLSH_LIBS="-Wl,-X -T `cygpath --mixed ${WIND_BASE}/target/h/tool/gnu/ldscripts/link.OUT`" export DL_OBJS="tclLoadVxWorks.o" export SHLIB_SUFFIX=".out" export SHLIB_LD="ccpentium -r -nostdlib" export SHLIB_LD_LIBS="-Wl,-X -T `cygpath --mixed ${WIND_BASE}/target/h/tool/gnu/ldscripts/link.OUT`" export AR="arpentium" export ac_cv_c_bigendian=noGeneric Configuration
These settings are to convince the
configure
script of the existence of various VxWorks functionality, rather than determining the host's functionality.
export ac_cv_func_memcmp_clean=yes export ac_cv_func_strtoll=no export ac_cv_func_strtoull=no export ac_cv_func_strncasecmp=no export ac_cv_func_realpath=no export ac_cv_func_uname=no export ac_cv_func_gethostbyname_r=no export ac_cv_func_gethostbyaddr_r=no export tcl_cv_strstr_unbroken=ok export tcl_cv_strtoul_unbroken=ok export tcl_cv_strtod_unbroken=ok export tcl_cv_strtod_buggy=ok export tcl_cv_timezone_long=no export tcl_cv_timezone_time=no export tcl_cv_putenv_copy=yes export ac_cv_lib_pthread_pthread_mutex_init=yes export no_pipe=yes
Run Configure
Now run the autoconf script:
./configure --enable-threads --disable-shared --enable-symbols --host=vxworksdkm
Fix Makefiles for Cygwin
When building on Windows using Cygwin, the Makefile needs to be hacked so that
make
sees cygwin-style paths while the compiler sees Windows-style paths:
sed -e 's/\$(CC)\(.*\)\(\$[A-Za-z0-9_./()]*\)$/$(CC)\1\`cygpath --windows \2\`/' < Makefile > Makefile.1 sed -e 's/-I\(\${[A-Z_]*}\)/-I\`cygpath --windows \1\`/g' < Makefile.1 > Makefile.2 sed -e 's%-L/cygdrive/\(.\)\(/[A-Za-z0-9._/]*\)%-L\1:\2%g' < Makefile.2 > Makefile.3 sed -e 's%\t\t\(\$(GENERIC_DIR)/tclPkgConfig.c\)%\t\t\`cygpath --windows \1\`%' < Makefile.3 > Makefile.4 sed -e 's%\t\t\(\$(UNIX_DIR)/tclUnixInit.c\)%\t\t\`cygpath --windows \1\`%' < Makefile.4 > Makefile.5This shouldn't be necessary for a cross-build from Unix.
Build
After all of the above, Tcl should build fine. On Windows, use the hacked
Makefile.5
(see above).This should result in the loadable module
tclsh.out
.
Using Tcl
In the VxWorks
interpreter, load the Tcl DKM built above -- assumed to be in the
/tcl
directory, adjust as necessary -- using
ld < /tcl/tclsh.out
Before starting Tcl, the
pre-init
script must be set to configure Tcl's library path, e.g., by running the following command in the VxWorks C interpreter:
TclSetPreInitScript ("set ::tclDefaultLibrary /tcl/library");Note: if this step omitted, then Tcl will fail, complaining that it can not find the
init.tcl
file. Then it will crash.The Tcl module provides two entry points that can be called from the C interpreter:
- tcl
- Enters an interactive Tcl shell session. Line editing and history follows the usual VxWorks rules. Use shellConfigSet INTERPRETER=C to return to the C interpreter. Tcl interpreter state is preserved when switching in and out of the interactive session. Ctrl-C can be used to restart the interpreter (at which point state is lost).
- tclsh file
- This executes the contents of file in a new Tcl interpreter (no state is shared with other sessions).
Tcl Extensions
The following VxWorks-specific commands are available:
shellConfigSet
Usage:
shellConfigSet config
This calls
shellConfigSet (CURRENT_SHELL_SESSION, config)
.The primary purpose of this command is to switch back from an interactive Tcl session to the C interpreter using
shellConfigSet INTERPRETER=C
. See the
shellLib
documentation for more information.
shellEvaluate
Usage:
shellEvaluate cmd ?interpreter?
This evaluates
cmd
in
interpreter
and returns the result. If omitted,
interpreter
defaults to
C
.See the documentation for
shellInterpEvaluate()
for more information.Only integer-type return values are supported. While
shellInterpEvaluate()
appears to return the polymorphic type
SHELL_EVAL_VALUE
, it is not documented, and I have not seen its
type
field be anything else than
SHELL_INT
.
shellExec
Usage:
shellExec cmd ?interpreter?
This evaluates
cmd
in
interpreter
and returns the output, similar to capturing a process' standard output. If omitted,
interpreter
defaults to
C
.The shell echoes commands as they are interpreted, so
cmd
is included in the output. The C shell also prints the value that each individual command evaluates to. So some post-processing of the returned value is necessary.A new interpreter session is created, which has its working directory initialized to some default, rather than inheriting Tcl's working directory.
cmd
should use absolute file names or change to the desired directory before accessing any files.This command may hang if
cmd
attempts to read from the console.
exit
The
exit
command is replaced to delete the current interpreter rather than exiting from the process -- the latter would make Tcl unusable. If this happens at an inopportune time, the error "eval called on a deleted interpreter" may occur. This is harmless, but Tcl should be modified to avoid this error.If
exit
is used in an interactive session, the current Tcl interpreter is deleted, and the session is returned to the C interpreter. When
tcl
is called again, a new Tcl interpreter session is started.
BSP Features
For reference, I needed to enable the following features in the kernel configurator beyond the "default":
- INCLUDE_GETADDRINFO
- INCLUDE_GETIFADDRS
- INCLUDE_GETNAMEINFO
- INCLUDE_GETNAMEINFO_SYSCTL
- INCLUDE_GETSERVBYNAME
- INCLUDE_STRICMP
Tcl Features
Loadable Tcl modules must be built as DKMs, and should be stub-enabled.Sorry, no threads yet.No pipes or
.
The Gory Details
Here are some implementation details of the VxWorks port:
- For better or worse, the patch modifies Tcl's unix port rather than creating a separate vxworks port. That kept the patch smaller, but makes it impossible to merge.
- The patch does not make use of some the POSIX APIs that were added in more recent versions of VxWorks, but instead uses the legacy APIs.
- When TclpObjAccess() is called with an R_OK (is the file readable?) parameter, it is replaced with a check for F_OK (does the file exist?). VxWorks' access(...,R_OK) erroneously returned false for files on NFS-mounted volumes even though they were readable. This means that file readable may now return a false positive in some cases.
- The probably greatest hack is the use of the event-based rather than the threaded notifier. The major reason is that VxWorks does not have anonymous pipes (the pipe() system call) that the threaded notifier uses. VxWorks does have named pipes which could be used instead, but I did not get around to implementing that. So far, the event-based notifier seems to hold up well even when multiple threads are running. However, given that I don't understand all the details, I can't guarantee that this won't cause issues in more complex applications.
- In VxWorks DKM mode, everything runs as tasks (threads) in the kernel "process". Calling exit() is therefore not possible. Tcl_Exit() calls Tcl_Finalize(), which renders the Tcl state unusable for other threads. Tcl_SetExitProc() was not an option since it is expected to not return. Therefore the patch overload's Tcl's exit command to delete the current interpreter instead. That seems to work for the most part, except for a few places where Tcl kept calling Tcl_Eval() without checking for interpreter deletion first -- so I added the appropriate checks in the places that I came across.
- VxWorks has no timezone, user id, group id, or /etc/passwd, so those features are commented out. Note that many VxWorks systems do not have real-time clocks, so unless the time is explicitly set (e.g., using Network Time Protocol - NTP), the clock starts at zero.
- I shied away from implementing threads so far, because they depend on pthread_exit(). Its equivalent in the VxWorks legacy API, taskDelete(), does not clean up resources that the thread was using, and might thus cause memory leaks and other issues.
- 相关文章:
发表评论
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。





