Gaston Rodriguez
2011-01-26 14:46:24 UTC
Hello all.
In the past days I created an almost complete binding of liburjtag to
the Tcl scripting language. For each exported function in the library I
created one Tcl command with the same name which accepts the same number
and "types" of arguments. In reality the types of the library are
coverted to and from Tcl objects.
The source code can be downloaded from here:
http://code.google.com/p/gasty-projects/downloads/list
Current version is 0.11
Some remarks:
* Tclurjtag is a C extension for Tcl. Their functions can be made
accessible with "package require Tclurjtag" in any Tcl script. The Tcl
global variable "auto_path" should be modified previously. All functions
reside in the "::urjtag" namespace
* The wrapping of liburjtag functions was automated with a tool
developed specifically for this task. For this reason the source
code should not be edited manually. Any bug found must be corrected
"touching" configuration scripts. This tool will be published in the
Tcl/Tk wiki soon...
* Pointers to data structures in the C code was casted and passed
to Tcl as integers. This is not the safest way of doing it, maybe in the
future the concept of Tcl "handles" can be used, i.e. assign an unique
string ID to each pointer. In any case the Tcl API should not change.
* Only a small part of the API was tested so far.
* Some custom functions are created for convenience:
- urj_get_driver_id cable_name: get a pointer to a cable
descriptor.
- urj_open_file filename: get a pointer to a FILE open as read.
Used by urj_svf_run
- urj_close_file: close a file open with urj_open_file
- urj_set_log_level: change the verbosity level
- urj_set_svf_callback: set the Tcl callback command
Pending issues:
* Some functions cannot be wrapped. In all cases because the
argument types are hard to convert to/from Tcl objects:
- urj_part_init_register
- urj_part_find_init
- urj_tap_parport_set_control
- urj_tap_parport_set_data
In the case of urj_tap_parport_set_* functions, if the modifier
const for data and control chars are removed the functions can be
wrapped ok.
* In the current state, additional parameters cannot be passed to
the function urj_bus_init_bus.
* SVF callback: when playing SVF files from the command line with
the progress flag enabled, a message indicating the progress was shown
in the stdout. For emulate the same behaviour and allow a more flexible
implementation of the progress callback (for instance setting the state
of a progress widget in a gui), some workaround needs to be applied. A
quick and dirty solution for this problem is:
- the original body of the function "progress_nl" in the file
"src/svf/svf_flex.l" was replaced for a call to an extern function:
static void
progress_nl (YYLTYPE *mylloc, YY_EXTRA_TYPE extra)
{
// call extern function
svf_progress_callback(mylloc->last_line, extra->num_lines);
}
- svf_progress_callback was declared as extern in svf.h:
extern void svf_progress_callback(int last_line, int num_lines);
- svf_progress_callback was defined in Tclurjtag.c. When this
function are called, a tcl command are executed, passing last_line and
num_lines as arguments.
- If the same function are defined in jtag.c, the normal
behavior of urjtag can be obtained:
void svf_progress_callback(int last_line, int num_lines)
{
int percent;
if (last_line % 10 == 0)
{
percent = ((last_line * 100) + 1) / num_lines;
if (percent<= 1)
return; // dont bother printing< 1 %
urj_log (URJ_LOG_LEVEL_DETAIL, "\r");
urj_log (URJ_LOG_LEVEL_DETAIL, _("Parsing %6d/%d (%3.0d%%)"),
last_line, num_lines, percent);
}
}
There is a better way of do this?
* Also when the SVF detect a mismatch, a message are printed in
stdout, but this stuation are not reflected in the exit status of the
function. There is no way that a Tcl script detect if the SVF play was
ok or not...
* When detecting parts using BSDL files, if any IDCODE match the
code of a bsd file, the file path are print in stdout, even with log
level in silent. The cause is that in urj_bsdl_scan_files
(src/bsdl/bsdl.c) there is a "printf" instead a log:
printf (_(" Filename: %s\n"), name);
* A big one: The BSDL detection of parts only works if the
following files are in the "current" directory of the application:
STD_1149_1_1990
STD_1149_1_1994
STD_1149_1_2001
STD_1532_2001
STD_1532_2002
This is a little impractical issue for a general purpose Tcl package...
Other minor issues:
* Some function declarations not show names for the input
arguments, for instance:
int urj_bsdl_read_file (urj_chain_t *, const char *, int, const char *);
The automated scripts use the argument names to generate a proper error
message when the number of arguments provided is different of the
expected. For example:
wrong # args: should be "urj_tap_cable_set_frequency cable frequency"
In these cases when argument names are empty, the message will look like:
wrong # args: should be "urj_bsdl_read_file arg0 arg1 arg2"
which is not so descriptive.
Demo:
A simple demo that mimics the urjtag command line app are provided.
Binary:
The binary provided is a windows dll. This version use FTD2XX
drivers for usb.
Along with the "Tclurjtag" package, a Tcl only package "Jtag" was
written. The purpose of these package is encapsulate in a TclOO class
all the low level calls to Tclurjtag commands. This package create the
class "Chain" in the namespace "::jtag". This class can be extended
using inheritance. This package is also a good reference in the usage
of Tclurjtag.
Demo: A simple script that play SVF files. This demo was tested with a
Actel's A3P250 Fpga. The log level was set to "normal" only to see the
original urjtag messages, but by default the log level should be "silent"
License:
Currently Tclurjtag use a GPL2 license for being compatible with urjtag.
I think that a less restrictive one should be more adequate for a
package/module/library...
if anyone is interested, please run the demos and provide me with any
feedback. This is a hyper-beta release, so I need some qualified testers ;)
Please forgive the long email and the poor english!
Best regards,
Gastón.
In the past days I created an almost complete binding of liburjtag to
the Tcl scripting language. For each exported function in the library I
created one Tcl command with the same name which accepts the same number
and "types" of arguments. In reality the types of the library are
coverted to and from Tcl objects.
The source code can be downloaded from here:
http://code.google.com/p/gasty-projects/downloads/list
Current version is 0.11
Some remarks:
* Tclurjtag is a C extension for Tcl. Their functions can be made
accessible with "package require Tclurjtag" in any Tcl script. The Tcl
global variable "auto_path" should be modified previously. All functions
reside in the "::urjtag" namespace
* The wrapping of liburjtag functions was automated with a tool
developed specifically for this task. For this reason the source
code should not be edited manually. Any bug found must be corrected
"touching" configuration scripts. This tool will be published in the
Tcl/Tk wiki soon...
* Pointers to data structures in the C code was casted and passed
to Tcl as integers. This is not the safest way of doing it, maybe in the
future the concept of Tcl "handles" can be used, i.e. assign an unique
string ID to each pointer. In any case the Tcl API should not change.
* Only a small part of the API was tested so far.
* Some custom functions are created for convenience:
- urj_get_driver_id cable_name: get a pointer to a cable
descriptor.
- urj_open_file filename: get a pointer to a FILE open as read.
Used by urj_svf_run
- urj_close_file: close a file open with urj_open_file
- urj_set_log_level: change the verbosity level
- urj_set_svf_callback: set the Tcl callback command
Pending issues:
* Some functions cannot be wrapped. In all cases because the
argument types are hard to convert to/from Tcl objects:
- urj_part_init_register
- urj_part_find_init
- urj_tap_parport_set_control
- urj_tap_parport_set_data
In the case of urj_tap_parport_set_* functions, if the modifier
const for data and control chars are removed the functions can be
wrapped ok.
* In the current state, additional parameters cannot be passed to
the function urj_bus_init_bus.
* SVF callback: when playing SVF files from the command line with
the progress flag enabled, a message indicating the progress was shown
in the stdout. For emulate the same behaviour and allow a more flexible
implementation of the progress callback (for instance setting the state
of a progress widget in a gui), some workaround needs to be applied. A
quick and dirty solution for this problem is:
- the original body of the function "progress_nl" in the file
"src/svf/svf_flex.l" was replaced for a call to an extern function:
static void
progress_nl (YYLTYPE *mylloc, YY_EXTRA_TYPE extra)
{
// call extern function
svf_progress_callback(mylloc->last_line, extra->num_lines);
}
- svf_progress_callback was declared as extern in svf.h:
extern void svf_progress_callback(int last_line, int num_lines);
- svf_progress_callback was defined in Tclurjtag.c. When this
function are called, a tcl command are executed, passing last_line and
num_lines as arguments.
- If the same function are defined in jtag.c, the normal
behavior of urjtag can be obtained:
void svf_progress_callback(int last_line, int num_lines)
{
int percent;
if (last_line % 10 == 0)
{
percent = ((last_line * 100) + 1) / num_lines;
if (percent<= 1)
return; // dont bother printing< 1 %
urj_log (URJ_LOG_LEVEL_DETAIL, "\r");
urj_log (URJ_LOG_LEVEL_DETAIL, _("Parsing %6d/%d (%3.0d%%)"),
last_line, num_lines, percent);
}
}
There is a better way of do this?
* Also when the SVF detect a mismatch, a message are printed in
stdout, but this stuation are not reflected in the exit status of the
function. There is no way that a Tcl script detect if the SVF play was
ok or not...
* When detecting parts using BSDL files, if any IDCODE match the
code of a bsd file, the file path are print in stdout, even with log
level in silent. The cause is that in urj_bsdl_scan_files
(src/bsdl/bsdl.c) there is a "printf" instead a log:
printf (_(" Filename: %s\n"), name);
* A big one: The BSDL detection of parts only works if the
following files are in the "current" directory of the application:
STD_1149_1_1990
STD_1149_1_1994
STD_1149_1_2001
STD_1532_2001
STD_1532_2002
This is a little impractical issue for a general purpose Tcl package...
Other minor issues:
* Some function declarations not show names for the input
arguments, for instance:
int urj_bsdl_read_file (urj_chain_t *, const char *, int, const char *);
The automated scripts use the argument names to generate a proper error
message when the number of arguments provided is different of the
expected. For example:
wrong # args: should be "urj_tap_cable_set_frequency cable frequency"
In these cases when argument names are empty, the message will look like:
wrong # args: should be "urj_bsdl_read_file arg0 arg1 arg2"
which is not so descriptive.
Demo:
A simple demo that mimics the urjtag command line app are provided.
Binary:
The binary provided is a windows dll. This version use FTD2XX
drivers for usb.
Along with the "Tclurjtag" package, a Tcl only package "Jtag" was
written. The purpose of these package is encapsulate in a TclOO class
all the low level calls to Tclurjtag commands. This package create the
class "Chain" in the namespace "::jtag". This class can be extended
using inheritance. This package is also a good reference in the usage
of Tclurjtag.
Demo: A simple script that play SVF files. This demo was tested with a
Actel's A3P250 Fpga. The log level was set to "normal" only to see the
original urjtag messages, but by default the log level should be "silent"
License:
Currently Tclurjtag use a GPL2 license for being compatible with urjtag.
I think that a less restrictive one should be more adequate for a
package/module/library...
if anyone is interested, please run the demos and provide me with any
feedback. This is a hyper-beta release, so I need some qualified testers ;)
Please forgive the long email and the poor english!
Best regards,
Gastón.