How to get Tcl under eCos Content Foreword i. Build the eCos tree ii. Build tclsh for eCos iii. Test your Tcl under eCos iv. Extend it vi. Is that tclsh much sucks? No, it isn't! Foreword A Tcl porting for eCos is a honorable task. We hear about Java, Python ... on the embedded systems, but why not Tcl? Why do it? I think it's cool, let make Tcl to toggle a led on your board: % while {1} {foreach {state} {0 1} {led $state; after 1000}} If speak seriously, Tcl is a good tool for any test purposes. For example, a tclsh is built in Cisco CLI (it's known as IOS). Tcl can be a universal glue for eCos applications too. The eCos is a RTOS. But it is an application only in same time. It hasn't *nix fork, exec. And what's about Tcl 'source' command instead exec sys-call or a recompile/load practice? I think can introduce some stuffs like a 'suspend/resume "that thread"' in Tcl, for example. It is a idea, isn't? Well, but lets to do the Tcl for eCos firstly. No configtool, bash only. i. Build the eCos tree $ export TARGET=yours $ mkdir -p /tmp/tclsh+ecos ; cd /tmp/tclsh+ecos $ ecosconfig new $TARGET default $ ecosconfig add posix $ ecosconfig fileio romfs ramfs # it's optional $ ecosconfig resolve Note: to reduce a lib size fix a compiler CFLAGS (replace '-g -O2' on '-Os' in the ecos.ecc) I use RAM startup to test 'tclsh' under RedBoot. I have one serial on my target board, so I need in a bit fix ecos.ecc (you can pass a import below) $ cat >import.ecm<<__eof cdl_component CYGDBG_HAL_DIAG_TO_DEBUG_CHAN {user_value 0}; cdl_option CYGSEM_HAL_DIAG_MANGLER {user_value None}; cdl_option CYGSEM_HAL_VIRTUAL_VECTOR_INHERIT_CONSOLE {user_value 1}; __eof $ ecosconfig import import.ecm $ ecosconfig resolve now make the eCos libraries $ ecosconfig tree $ make ii. Build tclsh for eCos We will be use one of the Tcl flavors for embedded. There is a Jim interpreter in Internet (http://jim.berlios.de). It is ultra small thing, lib size is ~70-80 kb only! There is no Tcl sockets, I/O channels in the Jim. But it is Tcl! It isn't 7.X, but 8.5! Jim is faster than Tcl 7.6 but slower than Tcl 8.4. And more, the Jim licensed under the Apache License, Version 2.0. (it likes an eCos license). Why is no real Tcl port here? Just I have small memory foot print system (1M RAM only). What's more? Jim is just 2 files only: jim.h, jim.c! If you have the more power board, you can try to build a native Tcl for eCos. Welcome! It is the honorable efforts! So, lets download the jim-hourly.tar.gz file from that site. And build your Tcl for eCos. $ tar xzvf /tmp/jim-hourly.tar.gz $ cd jim $ export PREFIX=arm-elf- # it is my case $ ${PREFIX}gcc -I../install/include -DJIM_ANSIC -nostartfiles -nostdlib \ -L../install/lib -Ttarget.ld -Os -o tclsh jim.c jimsh.c What's about a library size? In my case with the arm-elf-gcc 3.2 compiler I got: $ arm-elf-size jim.o text data bss dec hex filename 97344 1604 0 98948 18284 jim.o For the native (Linux build) it's ~80k only! $ cc -DJIM_ANSIC -Os -o jim jim.c jimsh.c $ size jim text data bss dec hex filename 82644 2080 448 85172 14cb4 jim iii. Test your Tcl under eCos Load and create a FIS entry for tclsh: RedBoot> lo -m xmodem RedBoot> fis create tclsh RedBoot> fis load tclsh RedBoot> go ... Play with Tcl now! iv. Extend it You can add the eCos mount commands before run a interpreter in the jimsh.c: main. I add a mounting of the romfs/ramfs file systems usually. A bit hacking let you to add any extensions. There is jim-aio.c in the jim package. You get a light file i/o functions with it. I just merged this with jim.c (the Tcl's 'load', 'package' commands aren't useful in our case, can cut it). I needed in the Tcl 'glob' and 'file' commands and a funny 'led' command absolutely! Last days I added these stuffs for myself (and I like native tclsh prompt too :). v. Sample of my Tcl session under eCos + RedBoot(tm) bootstrap and debug environment [ROM] Non-certified release, version 1.1 - built 21:22:10, Jun 6 2006 ... RAM: 0x81000000-0x81100000, [0x81006f00-0x810ed000] available FLASH: 0x80000000 - 0x80400000, 64 blocks of 0x00010000 bytes each. == Executing boot script in 10.000 seconds - enter ^C to abort RedBoot> fis load tclsh RedBoot> go % # Let's try some things ... % glob /lib/* /lib/hello.tcl /lib/init.tcl /lib/panic.tcl % source /lib/hello.tcl hello, world! % cat /lib/hello.tcl puts "hello, world!" % lsort [info commands] * + - / aopen append break cat catch clear collect concat continue debug dict env error eval exit expr finalize for foreach format getref glob global if incr info join lambda lambdaFinalizer lappend led lindex linsert list llength lmap lrange lreverse lset lsort proc puts rand range ref rename repeat return scan set setref source split string subst switch tailcall testmalloc time unset uplevel upvar while % exit vi. Is that tclsh much sucks? No, it isn't! RedBoot> fis list Name FLASH addr Mem addr Length Entry point RedBoot 0x80000000 0x81008000 0x00020000 0x81008040 romfs 0x80020000 0x81007000 0x00010000 0x81007000 tclsh 0x80030000 0x81008000 0x00040000 0x81008040 FIS directory 0x803F0000 0x803F0000 0x0000F000 0x00000000 RedBoot config 0x803FF000 0x803FF000 0x00001000 0x00000000 I wrote a Tcl 'testmalloc' command to do a out of memory panic. How I spoken, my board has 1M RAM only. There are RedBoot stuffs (~32k), tclsh (~220k) and startup scripts in the RAM, and output of a test script was % source /lib/panic.tcl free(malloc(1024)) [1 kb passed] free(malloc(2048)) [2 kb passed] free(malloc(3072)) [3 kb passed] free(malloc(4096)) [4 kb passed] ... free(malloc(765952)) [748 kb passed] free(malloc(766976)) [749 kb passed] free(malloc(768000)) [750 kb passed] free(malloc(769024)) [751 kb passed] TCL INTERPRETER PANIC: Out of memory --- Thanks for your time, any suggestion welcome! Regards, Sergei Gavrikov