halcompile: more names= items for realtime comps

Users using twopass processing request increased number of
named component instances (typically for simple logic elements
like and2,or2,...).   This commit removes the maximum
limit of 16 for names= items for realtime components.

Notes:
  1) For realtime components (loadrt), the maxium number of
     names= items is not limited by halcompile.
  2) For userspace components (loadusr), the maximum number
     of names= remains fixed at: MAX_USERSPACE_NAMES=16
  3) The maxium number of personalities is by default:
     MAX_PERSONALITIES=16
  4) A command line option can set the maximum number of
     personalities: -P|--personalities
  5) Behavior for count= directives is unchanged.
  6) Current MAX_CMD_LENGTH=1024 in src/hal/halcmd.h may
     need increasing if using many very long names= names.
  7) For normal usage, all names= items (comma-separated)
     must (still) be on a single loadrt line.  Using twopass
     processing allows multiple loadrt lines for the same
     component type.
  8) Formerly, a loadrt directive that specified no count= parameter
     and an empty names= parameter resulted in an error and no
     component was loaded. With this commit, such a directive
     loads a single instance (like and2.0)

Updated tests/:
  a) module-loading/or2/17-names ---- remove, no longer applicable
  b) module-loading/or2/0-names  ---- adapt per Note 8 above
  c) module-loading/pid/17-names ---- no change (pid.c    hardcoded for 16)
  d) module-loading/siggen/17-names - no change (siggen.c hardcoded for 16)
  e) halcompile/personalities_mod --- new tests for personalites that are
                                      modulo the compiled-in personalities
                                      using the --personalities= option
This commit is contained in:
Dewey Garrett 2019-02-05 11:35:02 -07:00
parent 133d6f8a1a
commit f56515517e
19 changed files with 358 additions and 46 deletions

View file

@ -43,10 +43,17 @@ halcompile \- Build, compile and install LinuxCNC HAL components
\fIsudo\fR \fBhalcompile\fR \fB\-\-install\fR \fB\-\-userspace\fR pyfile...
.PP
By default, the maximum number of 'names' items is 16. To alter this limit,
use the \fB--names=\fR option with halcompile. For example, to allow
20 'names' items:
[sudo] \fBhalcompile --names=20\fR --install ...
When personalities are used in a comp file, hal instances are exported
sequentially (typically by the mutually exclusive count= or names= parameters).
If the number of exports excedes the maximum number of personalities,
subsequent personalities are assigned modulo the maximum number of
personalities allowed.
By default, the maximum number of personalities is 16. To alter this
limit, use the \fB--personalities=\fR option with halcompile. For example,
to set the maximum of personality items to 4:
[sudo] \fBhalcompile --personalities=4\fR --install ...
.PD
.SH DESCRIPTION

View file

@ -591,6 +591,16 @@ Note: In prior versions of LinuxCNC (before joints_axes updates), the
== Hal Changes (Other)
=== halcompile
The number of names= instances was formerly limited to 16. Now,
for realtime components (loadrt) the instances are assigned
dynamically with no built-in limit. The limit of 16 still
applies to names= items for userspace (loadusr) components.
For components using 'personality', the maximum number is now
settable by a command line option -P|--personalities.
=== Parameter to Pin changes
The following hal output pins were changed from parameters to pins

View file

@ -767,3 +767,16 @@ which creates the following pins:
logic.2.in-01, logic.2.in-02
== Command Line Usage
The halcompile man page gives details for invoking halcompile.
----
$ man halcompile
----
A brief summary of halcompile usage is given by:
----
$ halcompile --help
----

View file

@ -21,8 +21,15 @@ import os, sys, tempfile, shutil, getopt, time
BASE = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), ".."))
sys.path.insert(0, os.path.join(BASE, "lib", "python"))
MAX_NAMES = 16
MAX_PERSONALITIES = MAX_NAMES
MAX_USERSPACE_NAMES = 16 # for userspace (loadusr) components
# NOTE: names are assigned dynamically for realtime components (loadrt)
# Components that use 'personality' features statically allocate
# memory based on MAX_PERSONALITIES (RTAPI_MP_ARRAY_INT)
# The number can be set with the cmdline option -P|--personalities
# Smaller values may be useful since the index of the personality
# exported is computed modulo MAX_PERSONALITIES
MAX_PERSONALITIES = 16
%%
parser Hal:
@ -493,11 +500,12 @@ static int comp_id;
if not options.get("singleton") and not options.get("count_function") :
print("static int default_count=%s, count=0;" \
% options.get("default_count", 1), file=f)
print("char *names[%d] = {0,};"%(MAX_NAMES), file=f)
if not options.get("userspace"):
if options.get("userspace"):
print("char *names[%d] = {0,};"%(MAX_USERSPACE_NAMES), file=f)
else:
print("RTAPI_MP_INT(count, \"number of %s\");" % comp_name, file=f)
print("RTAPI_MP_ARRAY_STRING(names, %d, \"names of %s\");" %(MAX_NAMES,comp_name), file=f)
print("char *names = \"\"; // comma separated names", file=f)
print("RTAPI_MP_STRING(names, \"names of %s\");" % comp_name, file=f)
if has_personality:
init1 = str(int(options.get('default_personality', 0)))
init = ",".join([init1] * MAX_PERSONALITIES)
@ -551,20 +559,44 @@ static int comp_id;
print(" if(r != 0) break;", file=f)
print(" }", file=f)
print(" } else {", file=f)
print(" int max_names = sizeof(names)/sizeof(names[0]);", file=f)
print(" for(i=0; (i < max_names) && names[i]; i++) {", file=f)
print(" if (strlen(names[i]) < 1) {", file=f)
print(" rtapi_print_msg(RTAPI_MSG_ERR, \"names[%d] is invalid (empty string)\\n\", i);", file=f)
print(" r = -EINVAL;", file=f)
print(" break;", file=f)
print(" }", file=f)
if has_personality:
print(" r = export(names[i], i, personality[i%%%d]);"%MAX_PERSONALITIES, file=f)
if options.get("userspace"):
print(" int max_names = sizeof(names)/sizeof(names[0]);", file=f)
print(" for(i=0; (i < max_names) && names[i]; i++) {", file=f)
print(" if (strlen(names[i]) < 1) {", file=f)
print(" rtapi_print_msg(RTAPI_MSG_ERR, \"names[%d] is invalid (empty string)\\n\", i);", file=f)
print(" r = -EINVAL;", file=f)
print(" break;", file=f)
print(" }", file=f)
if has_personality:
print(" r = export(names[i], i, personality[i%%%d]);"%MAX_PERSONALITIES, file=f)
else:
print(" r = export(names[i], i);", file=f)
print(" if(r != 0) break;", file=f)
print(" }", file=f)
print(" }", file=f)
else:
print(" r = export(names[i], i);", file=f)
print(" if(r != 0) break;", file=f)
print(" }", file=f)
print(" }", file=f)
print(" int j,idx;", file=f)
print(" char *ptr;", file=f)
print(" char buf[HAL_NAME_LEN+1];", file=f)
print(" ptr = names;", file=f)
print(" idx = 0;", file=f)
print(" for (i=0,j=0; i <= strlen(names); i++) {", file=f)
print(" buf[j] = *(ptr+i);", file=f)
print(" if ( (*(ptr+i) == ',') || (*(ptr+i) == 0) ) {", file=f)
print(" buf[j] = 0;", file=f)
if has_personality:
print(" r = export(buf, idx, personality[idx%%%d]);"%MAX_PERSONALITIES, file=f)
else:
print(" r = export(buf, idx);", file=f)
print(" if (*(ptr+i+1) == 0) {break;}", file=f)
print(" idx++;", file=f)
print(" if(r != 0) {break;}", file=f)
print(" j=0;", file=f)
print(" } else {", file=f)
print(" j++;", file=f)
print(" }", file=f)
print(" }", file=f)
print(" }", file=f)
if options.get("constructable") and not options.get("singleton"):
print(" hal_set_constructor(comp_id, export_1);", file=f)
@ -634,7 +666,7 @@ int __comp_parse_names(int *argc, char **argv) {
}
return 0;
}
"""%MAX_NAMES, file=f)
"""%MAX_USERSPACE_NAMES, file=f)
print("int argc=0; char **argv=0;", file=f)
print("int main(int argc_, char **argv_) {" , file=f)
print(" argc = argc_; argv = argv_;", file=f)
@ -1029,14 +1061,15 @@ Usage:
[sudo] %(name)s --install --userspace pyfile...
%(name)s --print-modinc
Option to set maximum 'names' items:
--names=integer_value (default is %(dflt)d)
""" % {'name': os.path.basename(sys.argv[0]),'dflt':MAX_NAMES})
Option to set maximum 'personalities' items:
--personalities=integer_value (default is %(dflt)d)
""" % {'name': os.path.basename(sys.argv[0]),'dflt':MAX_PERSONALITIES})
raise SystemExit(exitval)
def main():
global require_license
global MAX_NAMES,MAX_PERSONALITIES
global MAX_USERSPACE_NAMES
global MAX_PERSONALITIES
require_license = True
global require_unix_line_endings
require_unix_line_endings = False
@ -1044,11 +1077,11 @@ def main():
outfile = None
userspace = False
try:
opts, args = getopt.getopt(sys.argv[1:], "Uluijcpdo:h?n:",
opts, args = getopt.getopt(sys.argv[1:], "Uluijcpdo:h?P:",
['unix', 'install', 'compile', 'preprocess', 'outfile=',
'document', 'help', 'userspace', 'install-doc',
'view-doc', 'require-license', 'print-modinc',
'names='])
'personalities='])
except getopt.GetoptError:
usage(1)
@ -1077,13 +1110,12 @@ def main():
if len(args) != 1:
raise SystemExit("Cannot specify -o with multiple input files")
outfile = v
if k in ("-n", "--names"):
try:
MAX_NAMES = int(v)
MAX_PERSONALITIES = MAX_NAMES
print("MAX_NAMES=%d,MAX_PERSONALITIES=%d"%(MAX_NAMES,MAX_PERSONALITIES))
if k in ("-P", "--personalities"):
try:
MAX_PERSONALITIES = int(v)
print("MAX_PERSONALITIES=%d"%(MAX_PERSONALITIES))
except Exception, detail:
raise SystemExit("Bad value for -n (--names)=",v,"\n",detail)
raise SystemExit("Bad value for -P (--personalities)=",v,"\n",detail)
if k in ("-?", "-h", "--help"):
usage(0)

View file

@ -0,0 +1,100 @@
bitslice u32 IN 0 bitslice.0.in
bitslice bit OUT FALSE bitslice.0.out-00
bitslice bit OUT FALSE bitslice.0.out-01
bitslice s32 OUT 0 bitslice.0.time
bitslice u32 IN 0 bitslice.1.in
bitslice bit OUT FALSE bitslice.1.out-00
bitslice bit OUT FALSE bitslice.1.out-01
bitslice bit OUT FALSE bitslice.1.out-02
bitslice s32 OUT 0 bitslice.1.time
bitslice u32 IN 0 bitslice.2.in
bitslice bit OUT FALSE bitslice.2.out-00
bitslice bit OUT FALSE bitslice.2.out-01
bitslice s32 OUT 0 bitslice.2.time
bitslice u32 IN 0 bitslice.3.in
bitslice bit OUT FALSE bitslice.3.out-00
bitslice bit OUT FALSE bitslice.3.out-01
bitslice bit OUT FALSE bitslice.3.out-02
bitslice s32 OUT 0 bitslice.3.time
lincurve float IN 0 lincurve.0.in
lincurve float OUT 0 lincurve.0.out
lincurve float I/O 0 lincurve.0.out-io
lincurve s32 OUT 0 lincurve.0.time
lincurve float IN 0 lincurve.1.in
lincurve float OUT 0 lincurve.1.out
lincurve float I/O 0 lincurve.1.out-io
lincurve s32 OUT 0 lincurve.1.time
lincurve float IN 0 lincurve.2.in
lincurve float OUT 0 lincurve.2.out
lincurve float I/O 0 lincurve.2.out-io
lincurve s32 OUT 0 lincurve.2.time
lincurve float IN 0 lincurve.3.in
lincurve float OUT 0 lincurve.3.out
lincurve float I/O 0 lincurve.3.out-io
lincurve s32 OUT 0 lincurve.3.time
logic bit OUT FALSE logic.0.and
logic bit IN FALSE logic.0.in-00
logic bit IN FALSE logic.0.in-01
logic s32 OUT 0 logic.0.time
logic bit IN FALSE logic.1.in-00
logic bit IN FALSE logic.1.in-01
logic bit IN FALSE logic.1.in-02
logic bit IN FALSE logic.1.in-03
logic bit OUT FALSE logic.1.or
logic s32 OUT 0 logic.1.time
logic bit OUT FALSE logic.2.and
logic bit IN FALSE logic.2.in-00
logic bit IN FALSE logic.2.in-01
logic s32 OUT 0 logic.2.time
logic bit IN FALSE logic.3.in-00
logic bit IN FALSE logic.3.in-01
logic bit IN FALSE logic.3.in-02
logic bit IN FALSE logic.3.in-03
logic bit OUT FALSE logic.3.or
logic s32 OUT 0 logic.3.time
bitslice s32 RW 0 bitslice.0.tmax
bitslice bit RO FALSE bitslice.0.tmax-increased
bitslice s32 RW 0 bitslice.1.tmax
bitslice bit RO FALSE bitslice.1.tmax-increased
bitslice s32 RW 0 bitslice.2.tmax
bitslice bit RO FALSE bitslice.2.tmax-increased
bitslice s32 RW 0 bitslice.3.tmax
bitslice bit RO FALSE bitslice.3.tmax-increased
lincurve s32 RW 0 lincurve.0.tmax
lincurve bit RO FALSE lincurve.0.tmax-increased
lincurve float RW 0 lincurve.0.x-val-00
lincurve float RW 0 lincurve.0.x-val-01
lincurve float RW 0 lincurve.0.y-val-00
lincurve float RW 0 lincurve.0.y-val-01
lincurve s32 RW 0 lincurve.1.tmax
lincurve bit RO FALSE lincurve.1.tmax-increased
lincurve float RW 0 lincurve.1.x-val-00
lincurve float RW 0 lincurve.1.x-val-01
lincurve float RW 0 lincurve.1.x-val-02
lincurve float RW 0 lincurve.1.y-val-00
lincurve float RW 0 lincurve.1.y-val-01
lincurve float RW 0 lincurve.1.y-val-02
lincurve s32 RW 0 lincurve.2.tmax
lincurve bit RO FALSE lincurve.2.tmax-increased
lincurve float RW 0 lincurve.2.x-val-00
lincurve float RW 0 lincurve.2.x-val-01
lincurve float RW 0 lincurve.2.y-val-00
lincurve float RW 0 lincurve.2.y-val-01
lincurve s32 RW 0 lincurve.3.tmax
lincurve bit RO FALSE lincurve.3.tmax-increased
lincurve float RW 0 lincurve.3.x-val-00
lincurve float RW 0 lincurve.3.x-val-01
lincurve float RW 0 lincurve.3.x-val-02
lincurve float RW 0 lincurve.3.y-val-00
lincurve float RW 0 lincurve.3.y-val-01
lincurve float RW 0 lincurve.3.y-val-02
logic s32 RW 0 logic.0.tmax
logic bit RO FALSE logic.0.tmax-increased
logic s32 RW 0 logic.1.tmax
logic bit RO FALSE logic.1.tmax-increased
logic s32 RW 0 logic.2.tmax
logic bit RO FALSE logic.2.tmax-increased
logic s32 RW 0 logic.3.tmax
logic bit RO FALSE logic.3.tmax-increased

View file

@ -0,0 +1,10 @@
# personalities are used modulo the number of
# halcompiled personalities
# 4 count, 2 personalities
loadrt logic count=4 personality=0x102,0x204
loadrt lincurve count=4 personality=2,3
loadrt bitslice count=4 personality=2,3
show pin
show parameter

View file

@ -0,0 +1,100 @@
bitslice u32 IN 0 bs1.in
bitslice bit OUT FALSE bs1.out-00
bitslice bit OUT FALSE bs1.out-01
bitslice s32 OUT 0 bs1.time
bitslice u32 IN 0 bs2.in
bitslice bit OUT FALSE bs2.out-00
bitslice bit OUT FALSE bs2.out-01
bitslice bit OUT FALSE bs2.out-02
bitslice s32 OUT 0 bs2.time
bitslice u32 IN 0 bs3.in
bitslice bit OUT FALSE bs3.out-00
bitslice bit OUT FALSE bs3.out-01
bitslice s32 OUT 0 bs3.time
bitslice u32 IN 0 bs4.in
bitslice bit OUT FALSE bs4.out-00
bitslice bit OUT FALSE bs4.out-01
bitslice bit OUT FALSE bs4.out-02
bitslice s32 OUT 0 bs4.time
lincurve float IN 0 lc1.in
lincurve float OUT 0 lc1.out
lincurve float I/O 0 lc1.out-io
lincurve s32 OUT 0 lc1.time
lincurve float IN 0 lc2.in
lincurve float OUT 0 lc2.out
lincurve float I/O 0 lc2.out-io
lincurve s32 OUT 0 lc2.time
lincurve float IN 0 lc3.in
lincurve float OUT 0 lc3.out
lincurve float I/O 0 lc3.out-io
lincurve s32 OUT 0 lc3.time
lincurve float IN 0 lc4.in
lincurve float OUT 0 lc4.out
lincurve float I/O 0 lc4.out-io
lincurve s32 OUT 0 lc4.time
logic bit OUT FALSE lg1.and
logic bit IN FALSE lg1.in-00
logic bit IN FALSE lg1.in-01
logic s32 OUT 0 lg1.time
logic bit IN FALSE lg2.in-00
logic bit IN FALSE lg2.in-01
logic bit IN FALSE lg2.in-02
logic bit IN FALSE lg2.in-03
logic bit OUT FALSE lg2.or
logic s32 OUT 0 lg2.time
logic bit OUT FALSE lg3.and
logic bit IN FALSE lg3.in-00
logic bit IN FALSE lg3.in-01
logic s32 OUT 0 lg3.time
logic bit IN FALSE lg4.in-00
logic bit IN FALSE lg4.in-01
logic bit IN FALSE lg4.in-02
logic bit IN FALSE lg4.in-03
logic bit OUT FALSE lg4.or
logic s32 OUT 0 lg4.time
bitslice s32 RW 0 bs1.tmax
bitslice bit RO FALSE bs1.tmax-increased
bitslice s32 RW 0 bs2.tmax
bitslice bit RO FALSE bs2.tmax-increased
bitslice s32 RW 0 bs3.tmax
bitslice bit RO FALSE bs3.tmax-increased
bitslice s32 RW 0 bs4.tmax
bitslice bit RO FALSE bs4.tmax-increased
lincurve s32 RW 0 lc1.tmax
lincurve bit RO FALSE lc1.tmax-increased
lincurve float RW 0 lc1.x-val-00
lincurve float RW 0 lc1.x-val-01
lincurve float RW 0 lc1.y-val-00
lincurve float RW 0 lc1.y-val-01
lincurve s32 RW 0 lc2.tmax
lincurve bit RO FALSE lc2.tmax-increased
lincurve float RW 0 lc2.x-val-00
lincurve float RW 0 lc2.x-val-01
lincurve float RW 0 lc2.x-val-02
lincurve float RW 0 lc2.y-val-00
lincurve float RW 0 lc2.y-val-01
lincurve float RW 0 lc2.y-val-02
lincurve s32 RW 0 lc3.tmax
lincurve bit RO FALSE lc3.tmax-increased
lincurve float RW 0 lc3.x-val-00
lincurve float RW 0 lc3.x-val-01
lincurve float RW 0 lc3.y-val-00
lincurve float RW 0 lc3.y-val-01
lincurve s32 RW 0 lc4.tmax
lincurve bit RO FALSE lc4.tmax-increased
lincurve float RW 0 lc4.x-val-00
lincurve float RW 0 lc4.x-val-01
lincurve float RW 0 lc4.x-val-02
lincurve float RW 0 lc4.y-val-00
lincurve float RW 0 lc4.y-val-01
lincurve float RW 0 lc4.y-val-02
logic s32 RW 0 lg1.tmax
logic bit RO FALSE lg1.tmax-increased
logic s32 RW 0 lg2.tmax
logic bit RO FALSE lg2.tmax-increased
logic s32 RW 0 lg3.tmax
logic bit RO FALSE lg3.tmax-increased
logic s32 RW 0 lg4.tmax
logic bit RO FALSE lg4.tmax-increased

View file

@ -0,0 +1,10 @@
# personalities are used modulo the number of
# halcompiled personalities
# 4 names, 2 personalities
loadrt logic names=lg1,lg2,lg3,lg4 personality=0x102,0x204
loadrt lincurve names=lc1,lc2,lc3,lc4 personality=2,3
loadrt bitslice names=bs1,bs2,bs3,bs4 personality=2,3
show pin
show parameter

View file

@ -0,0 +1,8 @@
Verify that personalities are used modulo 2 when
using halcompile --personalities=2
Test in-tree components:
lincurve
logic
bitslice

View file

@ -0,0 +1,13 @@
#!/bin/bash
cd $(dirname $1)
RETVAL=0
for EXPECTED in *.expected ; do
BASE=$(basename $EXPECTED .expected)
RESULT=$BASE.result
diff -u $EXPECTED $RESULT
if [ $? -ne 0 ]; then
RETVAL=1
fi
done
exit $RETVAL

View file

@ -0,0 +1,17 @@
#!/bin/sh
DIR=../../../src/hal/components ;# use in-tree components
halcompile --personalities=2 --install $DIR/lincurve.comp
halcompile --personalities=2 --install $DIR/logic.comp
halcompile --personalities=2 --install $DIR/bitslice.comp
for HAL in *.hal; do
echo "testing $HAL"
BASE=$(basename $HAL .hal)
# use -s to avoid different user assignments in show output
halrun -s $HAL >| $BASE.result
done
# restore using default to avoid interfering with other tests
halcompile --install $DIR/lincurve.comp
halcompile --install $DIR/logic.comp
halcompile --install $DIR/bitslice.comp

View file

@ -1 +1 @@
0
1

View file

@ -1 +1 @@
1
0

View file

@ -1 +0,0 @@
0

View file

@ -1 +0,0 @@
or2\.[0-9]+\.out$

View file

@ -1 +0,0 @@
1

View file

@ -1,4 +0,0 @@
loadrt or2 names=or2.0,or2.1,or2.2,or2.3,or2.4,or2.5,or2.6,or2.7,or2.8,or2.9,or2.10,or2.11,or2.12,or2.13,or2.14,or2.15,or2.16
show pin

View file

@ -1 +0,0 @@
../../shared-test.sh