I have developed software for teaching and for research.
Here are some of them.
This package has been developed to facilitate the operator/controller dialog.
The operator interacts with a Tcl-Tk panel that runs as a Linux process.
The controller is a real-time program, written in C, running at the kernel level, as a module.The package provides a semi-automated generation of programs that communicate through RT-FIFOs (real-time FIFOs).
Architecture of the Application
The controller consists of several tasks. A typical arcitecture is given in the figure below.
Real-time FIFOs allow the user to exchange information between the real-time part (the controller) and the standard Linux process part (the dialog Tcl-Tk panel).
The architecture chosen for the controller is not compulsory, but is highly encouraged and well-suited to our package. The illustrative example given below is directly inspired from the one given in the RTAI documentation.
monitor is a task in charge of dispatching commands (e.g., Go, Suspend, Resume, Stop, ...) sent by the operator through the MON_SND RT-FIFO. Acknowledgments are returned through the MON_RCV RT-FIFO.
collector is a task that receives new values for parameters (typed values) and forwards them to the right task. Values of parameters are specified in entries of the Tcl-Tk panel and then encoded into a binary format before transmission.
Other tasks are specific to the application. In the test example, they perform PWM (Pulse Width Modulation) control. They can send values of distinguished variables into the TRACE RT-FIFO. These values are displayed on the Tcl-Tk panel.
Principle of the implementation
Assume that the application is named `foo'
The controller (the real-time program) is written in C (file foo.c). This program calls RTLinux's primitives and uses
a few macros. The real-time Linux implementation that I used, is actually RTAI.
The customized panel is described in the foo.tcl file.Files foo.c and foo.tcl are, of course, application-dependent. They should be provided by the user. They can be adapted from demonstration files (in directory src/tcl/).
A special parsing of the foo.c source code extracts information needed for building a dialog panel and managing communication. Two application-dependent files are generated: fooCfg.h and fooCfg.tcl.
The rtftclx package provides application-independent Tcl procs.A Makefile is available to make it easy to compile a new application.
Requirements
You must have root's privileges for some parts of the installation.
The package must be tailored to your own environment
Portage to NMT-RTLinux
or to newer versions of RTAI seems to be easy.
Because of new commands added to Tcl-Tk, you should
use version 8.2 or higher.
C's Macros expand to C code and provide Tcl-Tk with pertinent information about the exchanged variables.We set apart two types of exchanged information:
A side-effect of the macros is to assign a unique token to each exchanged variable and to memorize the format of the variable. This information must be kept consistent in the C and the Tcl-Tk program.
- command and response: whose type is Byte. They are used for quick exchanges. Commands flow from Linux to RTLinux, while responses flow from RTLinux to Linux.
- ordinary (typed) variable: they are transmitted in two steps: first transmit the associated token (type : int); then transmit the binary representation of this value (type-dependent)
Meanings of arguments:
rtfId ::= identifier for a RT-FIFO num ::= number of the RT-FIFO (implementation-dependent; usually 0..63) dir ::= direction: r (read: Linux-> RTLinux); w (write: RTLinux -> Linux) hdl ::= identifier of a Tcl proc that handles the communication on rtfId, on the Tcl-side Syntax:
rtf_dcl rtfId,num,dir,hdldeclares a RF-FIFOput_To rtfId func var typewrites the value of var defined in the C's function func, and whose type is type, into the RT-FIFO rtfId.caseDataFrom rtfId func var typethis instruction is a guard that opens when a value of the variable var, defined in context func, whose type is type, is received on RT-FIFO rtfId.monitorGet cmdgets a command cmd from the RT-FIFO dedicated to command transmission from Linux to RTLinux
monitorPutresp
puts a response resp into the RT-FIFO dedicated to command transmission from RTLinux to LinuxRemark:
func::var should refer to a variable of the C program, without any ambiguity. var is the actual name of the variable. func resolves the conflict in the case of several variables with the same identifier. Taking the name of the enclosing C function is often sufficient, but it is not a necessity. Any well-formed C identifier will do. Note that, for global variables, you should use an empty string "".
Commands and procs added to the standard Tcl-Tk can be used by any Tcl-Tk program. You have only to insert the following Tcl statements:set RTFTCL $env(RTFTCL)
set LIBDIR $RTFTCL/lib
lappend auto_path $LIBDIR [file dirname [info script]] ;# add your own libraries, if anypackage require Rtftclx
See the test file $RTFTCL/src/tcl/testRtf.tcl for details.
In order to avoid conflicts with your application identifiers, the library uses a namespace named Rtf. The source files (rtftclx.c for the commands and rtftclx.tcl for the namespace and the new procs) are in directory $RTFTCL/lib.
The problem with RT-FIFOs and Tcl is that RT-FIFOs are special Unix devices (/dev/rtf0, /dev/rtf1, ... , /dev/rtf63). They are not directly recognized to Tcl. A solution might have been to write dedicated device handlers. I chose a simpler solution: since C programs can access to RT-FIFOs, I wrote new Tcl commands using C accesses.
Arguments of commands and procs
- Boolean-exp ::= Tcl expression that returns 0 or 1
- rtf-num ::= number of the RT-FIFO (installation-dependent; 0..63 usually)
- rtf-id ::= name of a RT-FIFO device ( rtf0, rtf1, ..., rtf63)
- access ::= a char ( r for read or w for write)
- nb-of-bytes ::= integer, number of bytes to read or write
- byte-buffer ::= a ByteArray (a type supported by the Tcl library)
- handler ::= a Tcl's proc
- fifo-id ::= name given by Tcl to a file when opening it
New Tcl Commands
rtf_debug Boolean-exp pass 1 to have trace of creations, 0 (default): silent rtf_open rtf-num access RT-FIFO opening rtf_close rtf-id RT-FIFO closing rtf_read rtf-num nb-of-bytes read nb-of-bytes bytes from RT-FIFO rtf-num rtf_write rtf-num byte-buffer write the content of byte-buffer to RT-FIFO rtf-num
Avoid to use these low-level commands, they are used by higher-level exported procs.
New Tcl Procs
Not all procs are exported. If you want to export other defined procs, you have to insert
namespace export a-proc another-proc ...
in $RTFTCL/lib/rtftclx.tcl and rebuild the pkgIndex.tcl file by executing:Rtf::Init cfg-file call this proc before any other. cfg-file is fooCfg.tcl for application foo>make tcl
Rtf::buildVarPanel parent construction of the Tk panel. parent is the path of the widget
Rtf::traceReader handler for value sent by RTLinux to the panel
Rtf::paramWriter file-id token fn handler for transmitting value from the panel to RTLinux.; token is the token associated with the variable, fn is the full name of the variable.
Rtf::MonWriter handler that sends commands to RTLinux
Rtf::MonReader handler that gets responses from RTLinux
Rtf::sendCmd cmd proc that sends a command cmd. It calls Rtf::MonWriter
Rtf::Quit proc that sends a special command. procedure to shut down your application.
We take testRtf as the illustrative example.
Most of your applications can be written by adaptation of the two files $RTFTCL/src/tcl/testRtf.c and $RTFTCL/src/tcl/testRtf.tcl, the two files that the user has to provide.Before proceeding, be sure that the environment variable RTFTCL is correctly set and that $RTFTCL/bin is in your PATH.
Assume that foo is the name of your application (i.e., foo is testRtf). foo.c and foo.tcl must be in the current directory.
- rt_install // installs basic real-time modules
- buildRtf foo // special parsing of foo.c and generation of auxiliary files: fooCfg.h and fooCfg.tcl
- foo.tcl // run the real-time controller and its control panel
- loop to 2 if you want to run foo again, or any other else application
- rt_uninstall // to remove the basic real-time modules from the kernel
Running foo.tcl
After internal initializations, foo.tcl displays a "selection panel"
In the selection panel all the exchanged variables are listed. The default status for a signal is "visible" (Show). In the figure above, we chose to hide pwm::refreshed.
When selection is done, click on button Accept.Now, foo.tcl displays the "dialog panel":
Values received from RTLinux are displayed next to the (full) name of the variable. They are continuously updated by the (background) Linux process (i.e., foo.tcl).
Values to be sent to RTLinux are set by the user in the sunken entries and sent by a "carriage return". In the example above, only the global variable data can be set.Buttons Go, Stop, Freeze, Resume are specific to the application. The behavior is described by the statechart below:
testRtf::ss counts seconds; testRtf::ts counts tenths of second. To let the user see evolutions, the clock has been slowed down. Because of the real-time kernel, the occurrences of ts could be "real" tenths of second. See and change the code.
The PWM output is pwm::temp. d0 and d1 are respectively the duration of 0 and the duration of 1 (PWM). These durations are controlled by ::data. The pulse width is proportional to data with the enocoding: data = -128 => pulse width = 0%; data = 0 => pulse width = 50%; data = 127 => pulse width = 100%.
When you change data, you can see change in temp display.
Of course, displaying the output of a PWM on a Tcl-Tk panel is not especially useful. The PWM output must be observed with a scope, on the parallel port (adapt the pwm function in testRtf.c if you want).
For practical uses, consider that tenths of the second is the lower bound for the panel refresh.
Note that button Quit is disabled (grey label). It turns to enabled when the Stop button is pressed.
Below is the look of the dialog panel, after pressing the Stop button.
Illegal format, or pressing a button when not expected, causes a warning message on the console.
Pressing Quit terminates the application. RT-FIFOs are closed and auxiliary processes (cat) are killed.
Of course, real-timer programmer SHOULD be most reliable programmers. Since your application is directly loaded into the kernel, you must be especially cautious with your C code. It is well-known that usual C functions like printf, scanf, ... are not to be used. Errors in pointers, access beyond array index range, ... can cause serious crashes. This package can't prevent you from unsafe programming. Read the disclaimer below, ... and real-time programming manuals.They are several causes of slighter errors. Some may come from misunderstanding of the exact semantics of the provided C macros and Tcl procs, others may be due to different environments, others may result from hidden bugs (highly likely).
In this case, try to kill the foo.tcl process (by the x button of the widget, or by a kill from another xterm).
This is generally a sufficient action.
Execute lsmod to check if foo is effectively unloaded from the kernel. If not, execute rt_unload foo.If you don't succeed in unloading the foo module or if modules rt_fifos and rt_schedare still active in the kernel, check the running processes:
With >ps , see if you have active cat processes. If any, then kill them by a kill -9 pid, they are used by my implementation of the RT-FIFOs from RTLinux to the panel.Upto now, I always avoid "reboot" with these simple cures.
This package is available "as is".
It adheres to the the GNU General Public License.NO WARRANTY
BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.Charles André - I3S Laboratory - UNSA/CNRS
1.3
June 30, 2000
Tel:
(33) 4 92 94 27 40
Fax: (33) 4 92 94 28 96
web: www.i3s.unice.fr/~andre
E-mail: andre@unice.fr
Purpose: Educational. Initiation to low-level programming and CPU principles. Explore various architectures of CPU through their programming and their step-by-step execution. Deliberate limitation: it supports elementary programs only.
Realization: Pure Tcl-Tk implementation. Requires Tcl-Tk, version 8.4 or better, and the BWidget ToolKit, version 1.7 or better. Tested on Window2000, Windows XP and Linux.
Contact: Written by Charles ANDRÉ, Electrical Engineering Department, Faculty of Sciences, University of NICE-SOPHIA ANTIPOLIS. andre@unice.fr
Caveats: The look and Feel of the widgets is dependent on the operating system. The pictures given in the documentation are screen copies captured under Windows 2000, and have been generated by version 2.0 of the software.
Latest
version: v2.5 (July 2005)
Be sure that Tcl-Tk, version 8.4 or higher, and BWidget, version 1.7 or higher are installed.
1. If the environment variable SOFTDIR is defined, go to 5
2. Create a directory in which all software from C. André will be installed
3. Set the environment variable SOFTDIR to the path of this directory
4. Prepend your PATH environment variable with $SOFTDIR/bin (or %SOFTDIR%\bin for Windows)
5. Copy the distribution file archi.2.x.tgz in $SOFTDIR (replace x by the current minor version number)
6. Execute: cd $SOFTDIR
7. Execute: gunzip
-c archi.2.x.tgz | tar xvfp - (overwrite existing files, if any)
It creates (or updates) Directory tree:
$SOFTDIR
$SOFTDIR/bin
$SOFTDIR/ARCHI
$SOFTDIR/ARCHI/bin
$SOFTDIR/ARCHI/TCL
$SOFTDIR/ARCHI/doc
$SOFTDIR/ARCHI/EXAMPLES
8. For the first installation only:
execute: cd $SOFTDIR/bin
execute: platform.tcl
This copies configuration files in your home directory depending on your OS
9) optional: in $SOFTDIR/bin make
a symbolic link:
CPUSimulator to ../ARCHI/bin/CPUSimulator.tcl
10) That's All Folks!
See the attached PDF file (244kB)
Last update : October 19, 2005
Mail remarks and suggestions to andre@unice.fr