Skip to content

Commit bd2c432

Browse files
committed
New option 'period' in halcompile to control period parameter to functions.
Update documentation to describe new option behavior.
1 parent b4b0934 commit bd2c432

2 files changed

Lines changed: 57 additions & 19 deletions

File tree

docs/src/hal/comp.adoc

Lines changed: 36 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ component ddt "Compute the derivative of the input function";
3131
pin in float in;
3232
pin out float out;
3333
variable double old;
34+
option period no;
3435
function _;
3536
license "GPL"; // indicates GPL v2 or later
3637
;;
@@ -173,7 +174,7 @@ If neither 'count' nor 'names' is specified, a single numbered instance is creat
173174

174175
Functions are implicitly passed the 'period' parameter which is the time in nanoseconds of the last period to execute the component.
175176
Functions which use floating-point can also refer to 'fperiod' which is the floating-point time in seconds, or (period*1e-9).
176-
This can be useful in components that need the timing information.
177+
This can be useful in components that need the timing information. See also 'option period' below.
177178

178179
== Syntax
179180

@@ -292,18 +293,24 @@ r"\fIexample\fB"
292293

293294
The currently defined options are:
294295

295-
* 'option singleton yes' - (default: no)
296-
Do not create a 'count' module parameter, and always create a single instance.
297-
With 'singleton', items are named 'component-name.item-name' and without 'singleton', items for numbered instances are named 'component-name.<num>.item-name'.
298-
* 'option default_count number' - (default: 1)
299-
Normally, the module parameter 'count' defaults to 1. If specified, the 'count' will default to this value instead.
300-
* 'option count_function yes' - (default: no)
301-
Normally, the number of instances to create is specified in the module parameter 'count';
302-
if 'count_function' is specified, the value returned by the function 'int get_count(void)' is used instead, and the 'count' module parameter is not defined.
303-
* 'option rtapi_app no' - (default: yes)
296+
* 'option singleton yes' - (default: no) +
297+
Do not create a 'count' module parameter, and always create a single instance. With
298+
'singleton', items are named 'component-name.item-name' and without 'singleton', items for
299+
numbered instances are named 'component-name.<num>.item-name'.
300+
301+
* 'option default_count number' - (default: 1) +
302+
Normally, the module parameter 'count' defaults to 1. If specified, the 'count' will default
303+
to this value instead.
304+
305+
* 'option count_function yes' - (default: no) +
306+
Normally, the number of instances to create is specified in the module parameter 'count'; if
307+
'count_function' is specified, the value returned by the function 'int get_count(void)' is
308+
used instead, and the 'count' module parameter is not defined.
309+
310+
* 'option rtapi_app no' - (default: yes) +
304311
Normally, the functions `rtapi_app_main()` and `rtapi_app_exit()` are automatically defined.
305312
With 'option rtapi_app no', they are not, and must be provided in the C code.
306-
Use the following prototypes:
313+
Use the following prototypes: +
307314
+
308315
----
309316
`int rtapi_app_main(void);`
@@ -339,15 +346,15 @@ When implementing your own `rtapi_app_main()`, call the function `int export(cha
339346
This function may process the commandline arguments or take other actions.
340347
Its return type is 'void'; it may call 'exit()' if it wishes to terminate rather than create a HAL component (e.g., because the commandline arguments were invalid).
341348

342-
* 'option extra_link_args "..."' - (default: "")
349+
* 'option extra_link_args "..."' - (default: "") +
343350
This option is ignored if the option 'userspace' (see above) is set to 'no'.
344351
When linking a non-realtime component, the arguments given are inserted in the link line.
345352
Note that because compilation takes place in a temporary directory,
346353
"-L." refers to the temporary directory and not the directory where the .comp source file resides.
347354
This option can be set in the halcompile command-line with -extra-link-args="-L.....".
348355
This alternative provides a way to set extra flags in cases where the input file is a .c file rather than a .comp file.
349356

350-
* 'option extra_compile_args "..."' - (default: "")
357+
* 'option extra_compile_args "..."' - (default: "") +
351358
This option is ignored if the option 'userspace' (see above) is set to 'no'.
352359
When compiling a non-realtime component, the arguments given are inserted in the compiler command line.
353360
If the input file is a .c file this option can be set in the halcompile command-line with --extra-compile-args="-I.....".
@@ -359,6 +366,14 @@ When implementing your own `rtapi_app_main()`, call the function `int export(cha
359366
* 'option tpmod yes' - (default: no) +
360367
Module is a custom Trajectory Planning (tp) module loaded using `[TRAJ]TPMOD=`__modulename__ .
361368

369+
* 'option period no' - (default: yes) +
370+
Control the implicit 'period' parameter of the function(s) defined in the component. A
371+
standard function has an implicit parameter 'period'. Many components do no use the 'period'
372+
parameter and would cause a "unused parameter" compiler warning. Setting 'option period no'
373+
creates a function declaration omitting the 'period' parameter preventing the warning.
374+
Setting this option will also prevent 'fperiod' from being defined, as it depends on
375+
'period'.
376+
362377
If an option's VALUE is not specified, then it is equivalent to specifying 'option … yes'. +
363378
The result of assigning an inappropriate value to an option is undefined. +
364379
The result of using any other option is undefined. +
@@ -432,7 +447,7 @@ they will generally be referred to using the macros below.
432447
The details of `struct __comp_state` and these macros may change from one version of 'halcompile' to the next.
433448

434449
* `FUNCTION(`__name__`)` - Use this macro to begin the definition of a realtime function, which was previously declared with 'function NAME'.
435-
The function includes a parameter 'period' which is the integer number of nanoseconds between calls to the function.
450+
The function includes a parameter 'period' which is the integer number of nanoseconds between calls to the function. See also 'option period' above.
436451
* `EXTRA_SETUP()` - Use this macro to begin the definition of the function called to perform extra setup of this instance.
437452
Return a negative UNIX 'errno' value to indicate failure (e.g., 'return -EBUSY' on failure to reserve an I/O port), or 0 to indicate success.
438453
* `EXTRA_CLEANUP()` - Use this macro to begin the definition of the function called to perform extra cleanup of the component.
@@ -450,7 +465,7 @@ When the item is a conditional item, it is only legal to refer to it when its 'c
450465
* 'variable_name' - For each variable 'variable_name' there is a macro which allows the name to be used on its own to refer to the variable.
451466
When 'variable_name' is an array, the normal C-style subscript is used: 'variable_name[idx]'.
452467
* 'data' - If "option data" is specified, this macro allows access to the instance data.
453-
* 'fperiod' - The floating-point number of seconds between calls to this realtime function.
468+
* 'fperiod' - The floating-point number of seconds between calls to this realtime function. See also 'option period' above.
454469
* `FOR_ALL_INSTS() {`...`}` - For non-realtime components.
455470
This macro iterates over all the defined instances.
456471
Inside the body of the loop, the 'pin_name', 'parameter_name', and 'data' macros work as they do in realtime functions.
@@ -505,6 +520,7 @@ The file name must match the component name.
505520
component constant;
506521
pin out float out;
507522
param r float value = 1.0;
523+
option period no;
508524
function _;
509525
license "GPL"; // indicates GPL v2 or later
510526
;;
@@ -526,6 +542,7 @@ component sincos;
526542
pin out float sin_;
527543
pin out float cos_;
528544
pin in float theta;
545+
option period no;
529546
function _;
530547
license "GPL"; // indicates GPL v2 or later
531548
;;
@@ -548,6 +565,7 @@ param r unsigned ioaddr;
548565
549566
function _;
550567
568+
option period no;
551569
option count_function;
552570
option extra_setup;
553571
option extra_cleanup;
@@ -613,6 +631,7 @@ This realtime component illustrates use of fixed-size arrays:
613631
component arraydemo "4-bit Shift register";
614632
pin in bit in;
615633
pin out bit out-# [4];
634+
option period no;
616635
function _ nofp;
617636
license "GPL"; // indicates GPL v2 or later
618637
;;
@@ -654,6 +673,7 @@ pin in bit in-##[16 : personality & 0xff];
654673
pin out bit and if personality & 0x100;
655674
pin out bit or if personality & 0x200;
656675
pin out bit xor if personality & 0x400;
676+
option period no;
657677
function _ nofp;
658678
description """
659679
Experimental general 'logic function' component. Can perform 'and', 'or'
@@ -706,6 +726,7 @@ pin in s32 in;
706726
pin out bit out1;
707727
pin out bit out2;
708728
729+
option period no;
709730
function _;
710731
license "GPL";
711732
;;

src/hal/utils/halcompile.g

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,10 @@ def parse(filename):
142142
if require_license:
143143
if not finddoc('license'):
144144
raise SystemExit("%s:0: License not specified" % filename)
145+
146+
if not "period" in options:
147+
options["period"] = 1 # Option period defaults to on
148+
145149
return a, b
146150

147151
dirmap = {'r': 'HAL_RO', 'rw': 'HAL_RW', 'in': 'HAL_IN', 'out': 'HAL_OUT', 'io': 'HAL_IO' }
@@ -366,7 +370,15 @@ static int comp_id;
366370
for name, fp in functions:
367371
if name in names:
368372
Error("Duplicate item name: %s" % name)
369-
print("static void %s(struct __comp_state *__comp_inst, long period);" % to_c(name), file=f)
373+
if options.get("period"):
374+
print("static void %s(struct __comp_state *__comp_inst, long period);" % to_c(name), file=f)
375+
else:
376+
print("static void __no_period_%s(struct __comp_state *__comp_inst);" % to_c(name), file=f)
377+
# Define a tail-call function that the compiler can eliminate. It
378+
# hides the period parameter from the user function. Worst case it
379+
# becomes a jump instruction.
380+
print("static void %s(struct __comp_state *__comp_inst, long period)" % to_c(name), file=f)
381+
print("{ (void)period; __no_period_%s(__comp_inst); }" % to_c(name), file=f)
370382
names[name] = 1
371383

372384
print("static int __comp_get_data_size(void);", file=f)
@@ -719,13 +731,17 @@ int __comp_parse_names(int *argc, char **argv) {
719731
print("", file=f)
720732
if not options.get("no_convenience_defines"):
721733
print("#undef FUNCTION", file=f)
722-
print("#define FUNCTION(name) static void name(struct __comp_state *__comp_inst, long period)", file=f)
734+
if options.get("period"):
735+
print("#define FUNCTION(name) static void name(struct __comp_state *__comp_inst, long period)", file=f)
736+
else:
737+
print("#define FUNCTION(name) static void __no_period_##name(struct __comp_state *__comp_inst)", file=f)
723738
print("#undef EXTRA_SETUP", file=f)
724739
print("#define EXTRA_SETUP() static int extra_setup(struct __comp_state *__comp_inst, char *prefix, long extra_arg)", file=f)
725740
print("#undef EXTRA_CLEANUP", file=f)
726741
print("#define EXTRA_CLEANUP() static void extra_cleanup(void)", file=f)
727-
print("#undef fperiod", file=f)
728-
print("#define fperiod (period * 1e-9)", file=f)
742+
if options.get("period"):
743+
print("#undef fperiod", file=f)
744+
print("#define fperiod (period * 1e-9)", file=f)
729745
for name, type, array, dir, value, personality in pins:
730746
print("#undef %s" % to_c(name), file=f)
731747
print("#undef %s_ptr" % to_c(name), file=f)
@@ -1071,6 +1087,7 @@ def process(filename, mode, outfilename):
10711087

10721088
if options.get("homemod"): options["singleton"] = 1
10731089
if options.get("tpmod"): options["singleton"] = 1
1090+
if options.get("no_convenience_defines"): options["period"] = 1
10741091

10751092
if options.get("userinit") and not options.get("userspace"):
10761093
print("Warning: comp '%s' sets 'userinit' without 'userspace', ignoring" % filename, file=sys.stderr)

0 commit comments

Comments
 (0)