1. Introducción
This section introduces to the compilation HAL components, i.e. the addition of some machinists' knowledge on how to deal with the machine. It should be noted that such components do not necessarily deal with the hardware directly. They often do, but not necessarily, e.g. there could be a component to convert between imperial and metric scales, so this section does not require to dive into the interaction with hardware.
Writing a HAL component can be a tedious process, most of it in setup calls to rtapi_ and hal_ functions and associated error checking. halcompile will write all this code for you, automatically. Compiling a HAL component is also much easier when using halcompile, whether the component is part of the LinuxCNC source tree, or outside it.
For instance, when coded in C, a simple component such as "ddt" is around 80 lines of code. The equivalent component is very short when written using the halcompile preprocessor:
component ddt "Compute the derivative of the input function";
pin in float in;
pin out float out;
variable double old;
option period no;
function _;
license "GPL"; // indicates GPL v2 or later
;;
float tmp = in;
out = (tmp - old) / fperiod;
old = tmp;
2. Installing
Para compilar un componente, si está trabajando con una versión instalada de LinuxCNC, necesitará instalar los paquetes de desarrollo ya sea usando Synaptic desde el menú principal System -> Administration -> Synaptic package manager o ejecutando en una ventana de terminal uno de los comandos siguientes:
sudo apt install linuxcnc-dev
# or
sudo apt install linuxcnc-uspace-dev
Another method is using the Synaptic package manager, from the Applications menu, to install the linuxcnc-dev or linuxcnc-uspace-dev packages.
3. Compiling
3.1. Inside the source tree
Place the .comp file in the source directory linuxcnc/src/hal/components and re-run make. Comp files are automatically detected by the build system.
If a .comp file is a driver for hardware, it may be placed in linuxcnc/src/hal/drivers and will be built unless LinuxCNC is configured as a non-realtime simulator.
3.2. Realtime components outside the source tree
halcompile can process, compile, and install a realtime component in a single step, placing rtexample.ko in the LinuxCNC realtime module directory:
[sudo] halcompile --install rtexample.comp
|
Nota
|
sudo (for root permission) is needed when using LinuxCNC from a deb package install. When using a Run-In-Place (RIP) build, root privileges should not be needed. |
Or, it can process and compile in one step, leaving example.ko (or example.so for the simulator) in the current directory:
halcompile --compile rtexample.comp
Or it can simply process, leaving example.c in the current directory:
halcompile rtexample.comp
halcompile can also compile and install a component written in C, using the --install and --compile options shown above:
[sudo] halcompile --install rtexample2.c
man-format documentation can also be created from the information in the declaration section:
halcompile --document -o example.9 rtexample.comp
The resulting manpage, example.9 can be viewed with
man ./example.9
or copied to a standard location for manual pages.
3.3. Non-realtime components outside the source tree
halcompile can process, compile, install, and document non-realtime components:
halcompile non-rt-example.comp
halcompile --compile non-rt-example.comp
[sudo] halcompile --install non-rt-example.comp
halcompile --document non-rt-example.comp
For some libraries (for example modbus) it might be necessary to add extra compiler and linker arguments to enable the compiler to find and link the libraries. In the case of .comp files this can be done via "option" statements in the .comp file. For .c files this is not possible so the --extra-compile-args and --extra-link-args parameters can be used instead. As an example, this command line can be used to compile the vfdb_vfd.c component out-of-tree.
halcompile --userspace --install --extra-compile-args="-I/usr/include/modbus" --extra-link-args="-lm -lmodbus -llinuxcncini" vfdb_vfd.c
|
Nota
|
The effect of using both command-line and in-file extra-args is undefined. |
4. Using a Component
Components need to be loaded and added to a thread before it can be employed. The provided functionality can then be invoked directly and repeatedly by one of the threads or it is called by other components that have their own respective triggers.
loadrt threads name1=servo-thread period1=1000000
loadrt ddt
addf ddt.0 servo-thread
More information on loadrt and addf can be found in the HAL Basics.
To test your component you can follow the examples in the HAL Tutorial.
5. Definitions
-
component - A component is a single real-time module, which is loaded with
Halcmd loadrt. One.compfile specifies one component. The component name and file name must match. -
instance - A component can have zero or more instances. Each instance of a component is created equal (they all have the same pins, parameters, functions, and data) but behave independently when their pins, parameters, and data have different values.
-
singleton - It is possible for a component to be a "singleton", in which case exactly one instance is created. It seldom makes sense to write a singleton component, unless there can literally only be a single object of that kind in the system (for instance, a component whose purpose is to provide a pin with the current UNIX time, or a hardware driver for the internal PC speaker).
6. Instance creation
For a singleton, the one instance is created when the component is loaded.
For a non-singleton, the count module parameter determines how many numbered instances are created. If count is not specified, the names module parameter determines how many named instances are created. If neither count nor names is specified, a single numbered instance is created.
7. Implicit Parameters
Functions are implicitly passed the period parameter which is the time in nanoseconds of the last period to execute the component. Functions which use floating-point can also refer to fperiod which is the floating-point time in seconds, or (period*1e-9). This can be useful in components that need the timing information. See also option period below.
8. Syntax
A .comp file consists of a number of declarations, followed by ;; on a line of its own, followed by C code implementing the module’s functions.
Declarations include:
-
component HALNAME (DOC);
-
pin PINDIRECTION TYPE HALNAME ([SIZE]|[MAXSIZE: CONDSIZE]) (if CONDITION) (= STARTVALUE) (DOC) ;
-
param PARAMDIRECTION TYPE HALNAME ([SIZE]|[MAXSIZE: CONDSIZE]) (if CONDITION) (= STARTVALUE) (DOC) ;
-
function HALNAME (fp | nofp) (DOC);
-
option OPT (VALUE);
-
variable CTYPE STARREDNAME ([SIZE]);
-
description DOC;
-
examples DOC;
-
notes DOC;
-
see_also DOC;
-
license LICENSE;
-
author AUTHOR;
-
include HEADERFILE;
Parentheses indicate optional items. A vertical bar indicates alternatives. Words in CAPITALS indicate variable text, as follows:
-
NAME - A standard C identifier
-
STARREDNAME - A C identifier with zero or more * before it. This syntax can be used to declare instance variables that are pointers. Note that because of the grammar, there may not be whitespace between the * and the variable name.
-
HALNAME - An extended identifier. When used to create a HAL identifier, any underscores are replaced with dashes, and any trailing dash or period is removed, so that "this_name_" will be turned into "this-name", and if the name is "_", then a trailing period is removed as well, so that "function _" gives a HAL function name like "component.<num>" instead of "component.<num>."
If present, the prefix hal_ is removed from the beginning of the component name when creating pins, parameters and functions.
In the HAL identifier for a pin or parameter, # denotes an array item, and must be used in conjunction with a [SIZE] declaration. The hash marks are replaced with a 0-padded number with the same length as the number of # characters.
When used to create a C identifier, the following changes are applied to the HALNAME:
-
Any "#" characters, and any ".", "_" or "-" characters immediately before them, are removed.
-
Any remaining "." and "-" characters are replaced with "_".
-
Repeated "_" characters are changed to a single "\_" character.
A trailing "_" is retained, so that HAL identifiers which would otherwise collide with reserved names or keywords (e.g., min) can be used.
| HALNAME | C Identifier | HAL Identifier |
|---|---|---|
x_y_z |
x_y_z |
x-y-z |
x-y.z |
x_y_z |
x-y.z |
x_y_z_ |
x_y_z_ |
x-y-z |
x.##.y |
x_y(MM) |
x.MM.z |
x.## |
x(MM) |
x.MM |
-
if CONDITION - An expression involving the variable personality which is nonzero when the pin or parameter should be created.
-
SIZE - A number that gives the size of an array. The array items are numbered from 0 to SIZE-1.
-
MAXSIZE : CONDSIZE - A number that gives the maximum size of the array, followed by an expression involving the variable personality and which always evaluates to less than MAXSIZE. When the array is created its size will be CONDSIZE.
-
DOC - A string that documents the item. String can be a C-style "double quoted" string, like:
"Selects the desired edge: TRUE means falling, FALSE means rising"or a Python-style "triple quoted" string, which may include embedded newlines and quote characters, such as:
"""The effect of this parameter, also known as "the orb of zot", will require at least two paragraphs to explain. Hopefully these paragraphs have allowed you to understand "zot" better."""Or a string may be preceded by the literal character r, in which case the string is interpreted like a Python raw-string.
The documentation string is in "groff -man" format. For more information on this markup format, see groff_man(7). Remember that halcompile interprets backslash escapes in strings, so for instance to set the italic font for the word example, write:
"\\fIexample\\fB"In this case, r-strings are particularly useful, because the backslashes in an r-string need not be doubled:
r"\fIexample\fB" -
TYPE - One of the HAL types: bit, s32, u32, s64, u64 or float. The names signed and unsigned may also be used for s32 and u32 but s32 and u32 are preferred.
-
PINDIRECTION - One of the following: in, out, or io. A component sets a value for an out pin, it reads a value from an in pin, and it may read or set the value of an io pin.
-
PARAMDIRECTION - One of the following: r or rw. A component sets a value for a r parameter, and it may read or set the value of a rw parameter.
-
STARTVALUE - Specifies the initial value of a pin or parameter. If it is not specified, then the default is 0 or FALSE, depending on the type of the item.
-
HEADERFILE - The name of a header file, either in double-quotes (
include "myfile.h";) or in angle brackets (include <systemfile.h>;). The header file will be included (using C’s #include) at the top of the file, before pin and parameter declarations.
8.1. HAL functions
-
fp - Indicates that the function performs floating-point calculations.
-
nofp - Indicates that it only performs integer calculations. If neither is specified, fp is assumed. Neither halcompile nor gcc can detect the use of floating-point calculations in functions that are tagged nofp, but the use of such operations results in undefined behavior.
8.2. Options
The currently defined options are:
-
option singleton yes - (valor predeterminado: no)
No crear el parámetro de módulo count, y siempre crear una sola instancia. Con singleton, los elementos se denominan nombre-componente.nombre-elemento y sin singleton, los elementos, para las instancias numeradas, se nombran nombre-componente.<número>.nombre-del-elemento. -
option default_count number - (valor predeterminado: 1)
Normalmente, el parámetro de módulo count se establece de manera predeterminada en 1. Si se especifica, count cambiará a este valor por defecto. -
option count_function yes - (predeterminado: no)
Normalmente, el número de instancias a crear se especifica en el parámetro del módulo count; si se especifica count_function, se usa en su lugar el valor devuelto por la función int get_count(void) , y el parámetro del módulo count no se define. -
option rtapi_app no - (predeterminado: yes)
Normalmente, las funcionesrtapi_app_main()yrtapi_app_exit()son definidas automáticamente. Con option rtapi_app no, no lo son, y debe ser provistas en código C. Use los siguientes prototipos:
`int rtapi_app_main(void);` `void rtapi_app_exit(void);`When implementing your own
rtapi_app_main(), call the functionint export(char *prefix, long extra_arg)to register the pins, parameters, and functions forprefix. -
option data TYPE - (predeterminado: ninguno) obsoleto
Si se especifica, cada instancia del componente tendrá asociado un bloque de datos de tipo TYPE (que puede ser un tipo simple como float o el nombre de un tipo creado con typedef). En los componentes nuevos, se debe usar variable en su lugar. -
option extra_setup yes - (predeterminado: no)
Si se especifica, llama a la función definida por EXTRA_SETUP en cada instancia. Si usa rtapi_app_main definido automáticamente, extra_arg es el número de esta instancia. -
option extra_cleanup yes - (predeterminado: no)
Si se especifica, llama a la función definida por EXTRA_CLEANUP desde rtapi_app_exit definido automáticamente, o si se detecta un error en rtapi_app_main definido automáticamente. -
option userspace yes - (predeterminado: no)
Si se especifica, este archivo describe un componente de espacio de usuario (es decir, no en tiempo real), en lugar de uno regular (es decir, en tiempo real). Un componente de espacio de usuario puede no tener funciones definidas por la directiva function. En cambio, después de que todas las instancias se construyan, se llama a la función Cvoid user_mainloop(void);. Cuando esta función retorna, el componente sale. Normalmente, user_mainloop() usará FOR_ALL_INSTS() para realizar la acción de actualización para cada instancia, luego se detiene un tiempo corto. Otra acción común en user_mainloop() puede ser llamar al bucle del controlador de eventos de un toolkit de GUI. -
option userinit yes - (predeterminado: no)
Esta opción se ignora si la opción userspace (ver arriba) está configurada en no. Si se especifica userinit, la función userinit(argc, argv) se llama antes que rtapi_app_main() (y por lo tanto antes de la llamada a hal_init()). Esta función puede procesar los argumentos de la línea de comando o tomar otras acciones. Su tipo de retorno es void; puede llamar a exit() si desea terminar en lugar de crear un componente HAL (p. ej., porque los argumentos de línea de comando no eran válidos). -
option extra_link_args "…" - (default: "")
This option is ignored if the option userspace (see above) is set to no. When linking a non-realtime component, the arguments given are inserted in the link line. Note that because compilation takes place in a temporary directory, "-L." refers to the temporary directory and not the directory where the .comp source file resides. This option can be set in the halcompile command-line with -extra-link-args="-L…..". This alternative provides a way to set extra flags in cases where the input file is a .c file rather than a .comp file. -
option extra_compile_args "…" - (default: "")
This option is ignored if the option userspace (see above) is set to no. When compiling a non-realtime component, the arguments given are inserted in the compiler command line. If the input file is a .c file this option can be set in the halcompile command-line with --extra-compile-args="-I…..". This alternative provides a way to set extra flags in cases where the input file is a .c file rather than a .comp file. -
option homemod yes - (predeterminado: no)
Es un módulo personalizado de homing que se carga usando[EMCMOT]HOMEMOD=nombre-de-módulo. -
option tpmod yes - (predeterminado: no)
Es un módulo de planeación de trayectoria personalizado cargado con[TRAJ]TPMOD=nombre-del-módulo . -
option period no - (default: yes)
Control the implicit period parameter of the function(s) defined in the component. A standard function has an implicit parameter period. Many components do no use the period parameter and would cause a "unused parameter" compiler warning. Setting option period no creates a function declaration omitting the period parameter preventing the warning. Setting this option will also prevent fperiod from being defined, as it depends on period.
Si el VALOR de una opción no está especificado, entonces es equivalente a especificar option … yes.
El resultado de asignar un valor inapropiado a una opción no está definido.
El resultado de usar cualquier otra opción no está definido.
8.3. License and Authorship
-
LICENSE- Especifica la licencia del módulo para la documentación y para la declaración del módulo MODULE_LICENSE(). Por ejemplo, para especificar que la licencia del módulo es GPL v2 o posterior:`license "GPL"; // indicates GPL v2 or later`For additional information on the meaning of MODULE_LICENSE() and additional license identifiers, see <linux/module.h> or the manual page rtapi_module_param(3).
This declaration is required.
-
AUTHOR- Specify the author of the module for the documentation.
8.4. Per-instance data storage
-
variable CTYPE STARREDNAME; + variable CTYPE STARREDNAME[SIZE]; + variable CTYPE STARREDNAME = DEFAULT; + variable CTYPE STARREDNAME[SIZE] = DEFAULT;Declare a per-instance variable STARREDNAME of type CTYPE, optionally as an array of SIZE items, and optionally with a default value DEFAULT. Items with no DEFAULT are initialized to all-bits-zero. CTYPE is a simple one-word C type, such as
float,u32,s32,int, etc. Access to array variables uses square brackets.
If a variable is to be of a pointer type, there may not be any space between the "*" and the variable name. Therefore, the following is acceptable:
variable int *example;
But the following are not:
variable int* badexample;
variable int * badexample;
8.5. Comments
C++-style one-line comments (//...) and C-style multi-line comments (/* ... */) are both supported in the declaration section.
9. Restrictions
Though HAL permits a pin, a parameter, and a function to have the same name, halcompile does not.
Variable and function names that can not be used or are likely to cause problems include:
-
Anything beginning with _comp.
-
comp_id
-
fperiod
-
rtapi_app_main
-
rtapi_app_exit
-
extra_setup
-
extra_cleanup
10. Convenience Macros
Based on the items in the declaration section, halcompile creates a C structure called struct __comp_state. However, instead of referring to the members of this structure (e.g., *(inst->name)), they will generally be referred to using the macros below. The details of struct __comp_state and these macros may change from one version of halcompile to the next.
-
FUNCTION(`__name__)` - Use this macro to begin the definition of a realtime function, which was previously declared with function NAME. The function includes a parameter period which is the integer number of nanoseconds between calls to the function. See also option period above. -
EXTRA_SETUP()- Use this macro to begin the definition of the function called to perform extra setup of this instance. 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. -
EXTRA_CLEANUP()- Use this macro to begin the definition of the function called to perform extra cleanup of the component. Note that this function must clean up all instances of the component, not just one. The "pin_name", "parameter_name", and "data" macros may not be used here. -
pin_name or parameter_name - For each pin pin_name or param parameter_name there is a macro which allows the name to be used on its own to refer to the pin or parameter. When pin_name or parameter_name is an array, the macro is of the form pin_name(idx) or param_name(idx), where idx is the index into the pin array. When the array is a variable-sized array, it is only legal to refer to items up to its condsize.
When the item is a conditional item, it is only legal to refer to it when its condition evaluated to a nonzero value.
-
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. When variable_name is an array, the normal C-style subscript is used: variable_name[idx].
-
data - If "option data" is specified, this macro allows access to the instance data.
-
fperiod - The floating-point number of seconds between calls to this realtime function. See also option period above.
-
FOR_ALL_INSTS() {…}- For non-realtime components. This macro iterates over all the defined instances. Inside the body of the loop, the pin_name, parameter_name, and data macros work as they do in realtime functions.
11. Components with one function
Si un componente tiene solo una función y la cadena "FUNCTION" no aparece después de ;;, el resto sera tomado como el cuerpo de una función única del componente. Ver Simple Comp como ejemplo.
12. Component Personality
If a component has any pins or parameters with an "if condition" or "[maxsize : condsize]", it is called a component with personality. The personality of each instance is specified when the module is loaded. Personality can be used to create pins only when needed. For instance, personality is used in the logic component, to allow for a variable number of input pins to each logic gate and to allow for a selection of any of the basic boolean logic functions and, or, and xor.
The default number of allowed personality items is a compile-time setting (64). The default applies to numerous components included in the distribution that are built using halcompile.
To alter the allowed number of personality items for user-built components, use the --personalities option with halcompile. For example, to allow up to 128 personality times:
[sudo] halcompile --personalities=128 --install ...
When using components with personality, normal usage is to specify a personality item for each specified component instance. Example for 3 instances of the logic component:
loadrt logic names=and4,or3,nand5, personality=0x104,0x203,0x805
|
Nota
|
If a loadrt line specifies more instances than personalities, the instances with unspecified personalities are assigned a personality of 0. If the requested number of instances exceeds the number of allowed personalities, personalities are assigned by indexing modulo the number of allowed personalities. A message is printed denoting such assignments. |
13. Examples
13.1. constant
Note that the declaration "function _" creates functions named "constant.0", etc. The file name must match the component name.
component constant; pin out float out; param r float value = 1.0; option period no; function _; license "GPL"; // indicates GPL v2 or later ;; FUNCTION(_) { out = value; }
13.2. sincos
This component computes the sine and cosine of an input angle in radians. It has different capabilities than the "sine" and "cosine" outputs of siggen, because the input is an angle, rather than running freely based on a "frequency" parameter.
The pins are declared with the names sin_ and cos_ in the source code so that they do not interfere with the functions sin() and cos(). The HAL pins are still called sincos.<num>.sin.
component sincos; pin out float sin_; pin out float cos_; pin in float theta; option period no; function _; license "GPL"; // indicates GPL v2 or later ;; #include <rtapi_math.h> FUNCTION(_) { sin_ = sin(theta); cos_ = cos(theta); }
13.3. out8
Este componente es un controlador para una tarjeta ficticia llamada "out8", que tiene 8 pines de salida digital que son tratado como un solo valor de 8 bits. Puede haber un número variable de tales tarjetas en el sistema, y pueden estar en varias direcciones. El pin es llamado out_ porque out es un identificador utilizado en <asm/io.h>. Eso ilustra el uso de EXTRA_SETUP y EXTRA_CLEANUP para solicitar una región de E/S y luego liberarla en caso de error o cuando el módulo sea descargado.
component out8; pin out unsigned out_ "Output value; only low 8 bits are used"; param r unsigned ioaddr; function _; option period no; option count_function; option extra_setup; option extra_cleanup; option constructable no; license "GPL"; // indicates GPL v2 or later ;; #include <asm/io.h> #define MAX 8 int io[MAX] = {0,}; RTAPI_MP_ARRAY_INT(io, MAX, "I/O addresses of out8 boards"); int get_count(void) { int i = 0; for(i=0; i<MAX && io[i]; i++) { /* Nothing */ } return i; } EXTRA_SETUP() { if(!rtapi_request_region(io[extra_arg], 1, "out8")) { // set this I/O port to 0 so that EXTRA_CLEANUP does not release the IO // ports that were never requested. io[extra_arg] = 0; return -EBUSY; } ioaddr = io[extra_arg]; return 0; } EXTRA_CLEANUP() { int i; for(i=0; i < MAX && io[i]; i++) { rtapi_release_region(io[i], 1); } } FUNCTION(_) { outb(out_, ioaddr); }
13.4. hal_loop
component hal_loop; pin out float example;
Este fragmento de componente ilustra el uso del prefijo hal_ en el nombre de un componente.
loop is a common name, and the hal_ prefix avoids potential name collisions with other unrelated software. For example, on RTAI realtime systems realtime code runs in the kernel, so if the component were named just loop it could easily conflict with the standard loop kernel module.
When loaded, halcmd show comp will show a component called hal_loop. However, the pin shown by halcmd show pin will be loop.0.example, not hal-loop.0.example.
13.5. arraydemo
This realtime component illustrates use of fixed-size arrays:
component arraydemo "4-bit Shift register"; pin in bit in; pin out bit out-# [4]; option period no; function _ nofp; license "GPL"; // indicates GPL v2 or later ;; int i; for(i=3; i>0; i--) out(i) = out(i-1); out(0) = in;
13.6. rand
This non-realtime component changes the value on its output pin to a new random value in the range (0,1) about once every 1 ms.
component rand; option userspace; pin out float out; license "GPL"; // indicates GPL v2 or later ;; #include <unistd.h> void user_mainloop(void) { while(1) { usleep(1000); FOR_ALL_INSTS() out = drand48(); } }
13.7. logic (using personality)
This realtime component shows how to use "personality" to create variable-size arrays and optional pins.
component logic "LinuxCNC HAL component providing experimental logic functions"; pin in bit in-##[16 : personality & 0xff]; pin out bit and if personality & 0x100; pin out bit or if personality & 0x200; pin out bit xor if personality & 0x400; option period no; function _ nofp; description """ Experimental general 'logic function' component. Can perform 'and', 'or' and 'xor' of up to 16 inputs. Determine the proper value for 'personality' by adding: .IP \\(bu 4 The number of input pins, usually from 2 to 16 .IP \\(bu 256 (0x100) if the 'and' output is desired .IP \\(bu 512 (0x200) if the 'or' output is desired .IP \\(bu 1024 (0x400) if the 'xor' (exclusive or) output is desired"""; license "GPL"; // indicates GPL v2 or later ;; FUNCTION(_) { int i, a=1, o=0, x=0; for(i=0; i < (personality & 0xff); i++) { if(in(i)) { o = 1; x = !x; } else { a = 0; } } if(personality & 0x100) and = a; if(personality & 0x200) or = o; if(personality & 0x400) xor = x; }
A typical load line for this component might be
loadrt logic count=3 personality=0x102,0x305,0x503
which creates the following pins:
-
A 2-input AND gate:
logic.0.and,logic.0.in-00,logic.0.in-01 -
5-input AND and OR gates:
logic.1.and,logic.1.or,logic.1.in-00,logic.1.in-01,logic.1.in-02,logic.1.in-03,logic.1.in-04, -
3-input AND and XOR gates:
logic.2.and,logic.2.xor,logic.2.in-00,logic.2.in-01,logic.2.in-02
13.8. General Functions
This example shows how to call functions from the main function. It also shows how to pass reference of HAL pins to those functions.
component example; pin in s32 in; pin out bit out1; pin out bit out2; option period no; function _; license "GPL"; ;; // general pin set true function void set(hal_bit_t *p){ *p = 1; } // general pin set false function void unset(hal_bit_t *p){ *p = 0; } //main function FUNCTION(_) { if (in < 0){ set(&out1); unset(&out2); }else if (in >0){ unset(&out2); set(&out2); }else{ unset(&out1); unset(&out2); } }
This component uses two general function to manipulate a HAL bit pin referenced to it.
14. 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