[][src]Crate linuxcnc_hal_sys

This crate uses bindgen to create bindings to the LinuxCNC HAL module.

The high level, safe interface at linuxcnc-hal is recommended for user code.

Binding versions

This crateLinuxCNC version
v0.1.7v2.7.15
v0.1.6v2.7.15

Examples

All functions exported from this crate are unsafe, hence each example is wrapped in a big unsafe block for clarity.

The LinuxCNC HAL requires a certain setup procedure to operate correctly. The basic program structure should be roughly as follows

  1. Call hal_init to create a new HAL component
  2. Register SIGTERM and SIGINT signals, likely with the signal_hook crate. LinuxCNC will hang if these signals are not registered.
  3. Register pins with hal_pin_float_new, hal_pin_u32_new, etc
  4. Call hal_ready to signal to LinuxCNC that the component is ready
  5. Enter an infinite loop to continuously update input/output pin values and perform component logic

These examples can be loaded into LinuxCNC using a HAL file similar to this:

loadusr -W /path/to/your/component/target/debug/comp_bin_name
net input-1 spindle.0.speed-out pins.input-1

Create an input pin

This example creates a component called pins and registers an input pin to it that accepts a floating point value using hal_pin_float_new. Each HAL pin requires some memory allocated to store its value which is performed with hal_malloc.

The example can be loaded into LinuxCNC using a HAL file similar to this:

Note that there is no error handling in this example for brevity.

use linuxcnc_hal_sys::*;
use signal_hook::iterator::Signals;
use std::ffi::CString;
use std::mem;
use std::thread;
use std::time::Duration;

unsafe {
    let id = hal_init(CString::new("pins").unwrap().as_ptr() as *const i8);

    println!("ID {}", id);

    let signals = Signals::new(&[signal_hook::SIGTERM, signal_hook::SIGINT]).unwrap();

    let storage = hal_malloc(mem::size_of::<*mut f64>() as i64) as *mut *mut f64;

    println!("Storage {:?}", storage);

    let pin_name = CString::new("pins.input-1").unwrap();

    let ret = hal_pin_float_new(
        pin_name.as_ptr() as *const i8,
        hal_pin_dir_t_HAL_IN,
        storage,
        id,
    );

    println!("Pin init {}", ret);

    let ret = hal_ready(id);

    println!("Ready {}", ret);

    while !signals.pending().any(|signal| match signal {
        signal_hook::SIGTERM | signal_hook::SIGINT | signal_hook::SIGKILL => true,
        _ => false,
    }) {
        println!("Input {:?}", **storage);

        thread::sleep(Duration::from_millis(500));
    }
}

Error handling

Errors are handled in this crate the same way as in the C code. Some consts are exported like EINVAL and EPERM to allow matching of returned error codes.

use linuxcnc_hal_sys::*;
use signal_hook::iterator::Signals;
use std::ffi::CString;
use std::mem;
use std::thread;
use std::time::Duration;

unsafe {
    let ret = hal_init(CString::new("pins").unwrap().as_ptr() as *const i8);

    // Check that component was created successfully
    let component_id = match ret {
        x if x == -(EINVAL as i32) => panic!("Failed to initialise component"),
        x if x == -(ENOMEM as i32) => panic!("Not enough memory to initialise component"),
        id if id > 0 => id,
        code => unreachable!("Hit unreachable error code {}", code),
    };

    println!("Component registered with ID {}", component_id);

    let signals = Signals::new(&[signal_hook::SIGTERM, signal_hook::SIGINT]).unwrap();

    let storage = hal_malloc(mem::size_of::<*mut f64>() as i64) as *mut *mut f64;

    if storage.is_null() {
        panic!("Failed to allocate storage");
    }

    let pin_name = CString::new("pins.input-1").unwrap();

    let ret = hal_pin_float_new(
        pin_name.as_ptr() as *const i8,
        hal_pin_dir_t_HAL_IN,
        storage,
        component_id,
    );

    // Check that pin was registered successfully
    match ret {
        0 => println!("Pin registered successfully"),
        x if x == -(EINVAL as i32) => panic!("Failed to register pin"),
        x if x == -(EPERM as i32) => {
            panic!("HAL is locked. Register pins before calling hal_ready()`")
        }
        x if x == -(ENOMEM as i32) => panic!("Failed to register pin"),
        code => unreachable!("Hit unreachable error code {}", code),
    }

    let ret = hal_ready(component_id);

    // Check that component is ready
    match ret {
        0 => println!("Component is ready"),
        x if x == -(EINVAL as i32) => panic!("HAL component was not found or is already ready"),
        code => unreachable!("Hit unreachable error code {}", code),
    }

    while !signals.pending().any(|signal| match signal {
        signal_hook::SIGTERM | signal_hook::SIGINT | signal_hook::SIGKILL => true,
        _ => false,
    }) {
        println!("Input {:?}", **storage);

        thread::sleep(Duration::from_millis(500));
    }
}

Structs

__fsid_t
__va_list_tag
cpu_set_t
imaxdiv_t
max_align_t
sched_param
timespec

Constants

E2BIG
EACCES
EADDRINUSE
EADDRNOTAVAIL
EADV
EAFNOSUPPORT
EAGAIN
EALREADY
EBADE
EBADF
EBADFD
EBADMSG
EBADR
EBADRQC
EBADSLT
EBFONT
EBUSY
ECANCELED
ECHILD
ECHRNG
ECOMM
ECONNABORTED
ECONNREFUSED
ECONNRESET
EDEADLK
EDEADLOCK
EDESTADDRREQ
EDOM
EDOTDOT
EDQUOT
EEXIST
EFAULT
EFBIG
EHOSTDOWN
EHOSTUNREACH
EHWPOISON
EIDRM
EILSEQ
EINPROGRESS
EINTR
EINVAL
EIO
EISCONN
EISDIR
EISNAM
EKEYEXPIRED
EKEYREJECTED
EKEYREVOKED
EL2NSYNC
EL2HLT
EL3HLT
EL3RST
ELIBACC
ELIBBAD
ELIBEXEC
ELIBMAX
ELIBSCN
ELNRNG
ELOOP
EMEDIUMTYPE
EMFILE
EMLINK
EMSGSIZE
EMULTIHOP
ENAMETOOLONG
ENAVAIL
ENETDOWN
ENETRESET
ENETUNREACH
ENFILE
ENOANO
ENOBUFS
ENOCSI
ENODATA
ENODEV
ENOENT
ENOEXEC
ENOKEY
ENOLCK
ENOLINK
ENOMEDIUM
ENOMEM
ENOMSG
ENONET
ENOPKG
ENOPROTOOPT
ENOSPC
ENOSR
ENOSTR
ENOSYS
ENOTBLK
ENOTCONN
ENOTDIR
ENOTEMPTY
ENOTNAM
ENOTRECOVERABLE
ENOTSOCK
ENOTSUP
ENOTTY
ENOTUNIQ
ENXIO
EOPNOTSUPP
EOVERFLOW
EOWNERDEAD
EPERM
EPFNOSUPPORT
EPIPE
EPROTO
EPROTONOSUPPORT
EPROTOTYPE
ERANGE
EREMCHG
EREMOTE
EREMOTEIO
ERESTART
ERFKILL
EROFS
ESHUTDOWN
ESOCKTNOSUPPORT
ESPIPE
ESRCH
ESRMNT
ESTALE
ESTRPIPE
ETIME
ETIMEDOUT
ETOOMANYREFS
ETXTBSY
EUCLEAN
EUNATCH
EUSERS
EWOULDBLOCK
EXDEV
EXFULL
HAL_LOCK_ALL
HAL_LOCK_CONFIG
HAL_LOCK_LOAD
HAL_LOCK_NONE
HAL_LOCK_PARAMS
HAL_LOCK_RUN
HAL_NAME_LEN
INT8_MIN
INT8_MAX
INT16_MIN
INT16_MAX
INT32_MIN
INT32_MAX
INTPTR_MAX
INTPTR_MIN
INT_FAST8_MIN
INT_FAST8_MAX
INT_FAST16_MIN
INT_FAST16_MAX
INT_FAST32_MIN
INT_FAST32_MAX
INT_LEAST8_MIN
INT_LEAST8_MAX
INT_LEAST16_MIN
INT_LEAST16_MAX
INT_LEAST32_MIN
INT_LEAST32_MAX
LOCK_PREFIX
PRIX8
PRIX16
PRIX32
PRIX64
PRIXFAST8
PRIXFAST16
PRIXFAST32
PRIXFAST64
PRIXLEAST8
PRIXLEAST16
PRIXLEAST32
PRIXLEAST64
PRIXMAX
PRIXPTR
PRId8
PRId16
PRId32
PRId64
PRIdFAST8
PRIdFAST16
PRIdFAST32
PRIdFAST64
PRIdLEAST8
PRIdLEAST16
PRIdLEAST32
PRIdLEAST64
PRIdMAX
PRIdPTR
PRIi8
PRIi16
PRIi32
PRIi64
PRIiFAST8
PRIiFAST16
PRIiFAST32
PRIiFAST64
PRIiLEAST8
PRIiLEAST16
PRIiLEAST32
PRIiLEAST64
PRIiMAX
PRIiPTR
PRIo8
PRIo16
PRIo32
PRIo64
PRIoFAST8
PRIoFAST16
PRIoFAST32
PRIoFAST64
PRIoLEAST8
PRIoLEAST16
PRIoLEAST32
PRIoLEAST64
PRIoMAX
PRIoPTR
PRIu8
PRIu16
PRIu32
PRIu64
PRIuFAST8
PRIuFAST16
PRIuFAST32
PRIuFAST64
PRIuLEAST8
PRIuLEAST16
PRIuLEAST32
PRIuLEAST64
PRIuMAX
PRIuPTR
PRIx8
PRIx16
PRIx32
PRIx64
PRIxFAST8
PRIxFAST16
PRIxFAST32
PRIxFAST64
PRIxLEAST8
PRIxLEAST16
PRIxLEAST32
PRIxLEAST64
PRIxMAX
PRIxPTR
PTRDIFF_MAX
PTRDIFF_MIN
RTAPI_NAME_LEN
SCHED_FIFO
SCHED_OTHER
SCHED_RR
SCNd8
SCNd16
SCNd32
SCNd64
SCNdFAST8
SCNdFAST16
SCNdFAST32
SCNdFAST64
SCNdLEAST8
SCNdLEAST16
SCNdLEAST32
SCNdLEAST64
SCNdMAX
SCNdPTR
SCNi8
SCNi16
SCNi32
SCNi64
SCNiFAST8
SCNiFAST16
SCNiFAST32
SCNiFAST64
SCNiLEAST8
SCNiLEAST16
SCNiLEAST32
SCNiLEAST64
SCNiMAX
SCNiPTR
SCNo8
SCNo16
SCNo32
SCNo64
SCNoFAST8
SCNoFAST16
SCNoFAST32
SCNoFAST64
SCNoLEAST8
SCNoLEAST16
SCNoLEAST32
SCNoLEAST64
SCNoMAX
SCNoPTR
SCNu8
SCNu16
SCNu32
SCNu64
SCNuFAST8
SCNuFAST16
SCNuFAST32
SCNuFAST64
SCNuLEAST8
SCNuLEAST16
SCNuLEAST32
SCNuLEAST64
SCNuMAX
SCNuPTR
SCNx8
SCNx16
SCNx32
SCNx64
SCNxFAST8
SCNxFAST16
SCNxFAST32
SCNxFAST64
SCNxLEAST8
SCNxLEAST16
SCNxLEAST32
SCNxLEAST64
SCNxMAX
SCNxPTR
SIG_ATOMIC_MAX
SIG_ATOMIC_MIN
SIZE_MAX
UINT8_MAX
UINT16_MAX
UINT32_MAX
UINTPTR_MAX
UINT_FAST8_MAX
UINT_FAST16_MAX
UINT_FAST32_MAX
UINT_LEAST8_MAX
UINT_LEAST16_MAX
UINT_LEAST32_MAX
WINT_MAX
WINT_MIN
_ATFILE_SOURCE
_BITS_CPU_SET_H
_BITS_ERRNO_H
_BITS_SCHED_H
_BITS_STDINT_INTN_H
_BITS_STDINT_UINTN_H
_BITS_TYPESIZES_H
_BITS_TYPES_H
_BITS_WCHAR_H
_DEFAULT_SOURCE
_ERRNO_H
_FEATURES_H
_INTTYPES_H
_POSIX_C_SOURCE
_POSIX_SOURCE
_SCHED_H
_STDC_PREDEF_H
_STDINT_H
_SYS_CDEFS_H
__CPU_SETSIZE
__FD_SETSIZE
__GLIBC_MINOR__
__GLIBC_USE_DEPRECATED_GETS
__GLIBC_USE_IEC_60559_BFP_EXT
__GLIBC_USE_IEC_60559_FUNCS_EXT
__GLIBC_USE_IEC_60559_TYPES_EXT
__GLIBC_USE_LIB_EXT2
__GLIBC__
__GNUC_VA_LIST
__GNU_LIBRARY__
__HAVE_GENERIC_SELECTION
__INO_T_MATCHES_INO64_T
__OFF_T_MATCHES_OFF64_T
__PRI64_PREFIX
__PRIPTR_PREFIX
__RLIM_T_MATCHES_RLIM64_T
__STDC_IEC_559__
__STDC_IEC_559_COMPLEX__
__STDC_ISO_10646__
__STDC_NO_THREADS__
__SYSCALL_WORDSIZE
__USE_ATFILE
__USE_FORTIFY_LEVEL
__USE_ISOC11
__USE_ISOC95
__USE_ISOC99
__USE_MISC
__USE_POSIX
__USE_POSIX2
__USE_POSIX199309
__USE_POSIX199506
__USE_POSIX_IMPLICITLY
__USE_XOPEN2K
__USE_XOPEN2K8
__WORDSIZE
__WORDSIZE_TIME64_COMPAT32
____gwchar_t_defined
__bool_true_false_are_defined
__glibc_c99_flexarr_available
__time_t_defined
__timespec_defined
false_
hal_param_dir_t_HAL_RO
hal_param_dir_t_HAL_RW
hal_pin_dir_t_HAL_DIR_UNSPECIFIED
hal_pin_dir_t_HAL_IN
hal_pin_dir_t_HAL_IO
hal_pin_dir_t_HAL_OUT
hal_type_t_HAL_BIT
hal_type_t_HAL_FLOAT
hal_type_t_HAL_S32
hal_type_t_HAL_TYPE_UNSPECIFIED
hal_type_t_HAL_U32
msg_level_t_RTAPI_MSG_ALL
msg_level_t_RTAPI_MSG_DBG
msg_level_t_RTAPI_MSG_ERR
msg_level_t_RTAPI_MSG_INFO
msg_level_t_RTAPI_MSG_NONE
msg_level_t_RTAPI_MSG_WARN
true_

Functions

__errno_location
__sched_cpualloc
__sched_cpucount
__sched_cpufree
hal_add_funct_to_thread

hal_add_funct_to_thread() adds a function exported by a realtime HAL component to a realtime thread. This determines how often and in what order functions are executed. 'funct_name' is the name of the function, as specified in a call to hal_export_funct(). 'thread_name' is the name of the thread to which the function should be added. When the thread runs, the functions will be executed in the order in which they were added to the thread. 'position' is the desired location within the thread. This determines when the function will run, in relation to other functions in the thread. A positive number indicates the desired location as measured from the beginning of the thread, and a negative is measured from the end. So +1 means this function will become the first one to run, +5 means it will be the fifth one to run, -2 means it will be next to last, and -1 means it will be last. Zero is illegal. Returns 0, or a negative error code. Call only from within user space or init code, not from realtime code.

hal_comp_name

hal_comp_name() returns the name of the given component, or NULL if comp_id is not a loaded component

hal_del_funct_from_thread

hal_del_funct_from_thread() removes a function from a thread. 'funct_name' is the name of the function, as specified in a call to hal_export_funct(). 'thread_name' is the name of a thread which currently calls the function. Returns 0, or a negative error code. Call only from within user space or init code, not from realtime code.

hal_exit

'hal_exit()' must be called before a HAL component exits, to free resources associated with the component. 'comp_id' is the ID of the component as returned from its initial call to 'hal_init()'. 'hal_exit()' will remove the component's realtime functions (if any) from realtime threads. It also removes all pins and parameters exported by the component. If the component created any threads, when it exits all threads will be stopped, and the ones it created will be deleted. It is assumed that the system will no longer function correctly after a component is removed, but this cleanup will prevent crashes when the component's code and data is unmapped. 'hal_exit()' calls 'rtapi_exit()', so any rtapi reaources allocated should be discarded before calling hal_exit(), and rtapi functios should not be called afterwards. On success, hal_exit() returns 0, on failure it returns a negative error code.

hal_get_lock

The 'hal_get_lock()' function returns the current locking level locking types defined in hal.h HAL_LOCK_NONE -locks none HAL_LOCK_* - intermediate locking levels HAL_LOCK_ALL - locks everything

hal_init

'hal_init()' is called by a HAL component before any other hal function is called, to open the HAL shared memory block and do other initialization. 'name' is the name of the component. It must be unique in the system. It must be no longer than HAL_NAME_LEN. On success, hal_init() returns a positive integer component ID, which is used for subsequent calls to hal_xxx_new() and hal_exit(). On failure, returns an error code (see above). 'hal_init()' calls rtapi_init(), so after calling hal_init(), a component can use any rtapi functions. The component ID returned by 'hal_init()' is also the RTAPI module ID for the associated module, and can be used when calling rtapi functions. Call only from within user space or init/cleanup code, not from realtime code.

hal_link

'hal_link()' links a pin to a signal. 'pin_name' and 'sig_name' are strings containing the pin and signal names. If the pin is already linked to the desired signal, the command succeeds. If the pin is already linked to some other signal, it is an error. In either case, the existing connection is not modified. (Use 'hal_unlink' to break an existing connection.) If the signal already has other pins linked to it, they are unaffected - one signal can be linked to many pins, but a pin can be linked to only one signal. On success, hal_link() returns 0, on failure it returns a negative error code.

hal_malloc

hal_malloc() allocates a block of memory from the main HAL shared memory area. It should be used by all components to allocate memory for HAL pins and parameters. It allocates 'size' bytes, and returns a pointer to the allocated space, or NULL (0) on error. The returned pointer will be properly aligned for any variable HAL supports (see HAL_TYPE below.) The allocator is very simple, and there is no 'free'. It is assumed that a component will allocate all the memory it needs during initialization. The entire HAL shared memory area is freed when the last component calls hal_exit(). This means that if you continuously install and remove one component while other components are present, you eventually will fill up the shared memory and an install will fail. Removing all components completely clears memory and you start fresh.

hal_param_alias

'hal_param_alias()' assigns an alternate name, aka an alias, to a parameter. Once assigned, the parameter can be referred to by either its original name or the alias. Calling this function with 'alias' set to NULL will remove any existing alias.

hal_param_bit_new

The 'hal_param_xxx_new()' functions create a new 'parameter' object. A parameter is a value that is only used inside a component, but may need to be initialized or adjusted from outside the component to set up the system properly. Once a parameter has been created, it's value can be changed using the 'hal_param_xxx_set()' functions. There are eight functions, one for each of the data types that the HAL supports. Pins may only be linked to signals of the same type. 'name' is the name of the new parameter. It must be no longer than .HAL_NAME_LEN. If there is already a parameter with the same name the call will fail. 'dir' is the parameter direction. HAL_RO parameters are read only from outside, and are written to by the component itself, typically to provide a view "into" the component for testing or troubleshooting. HAL_RW parameters are writable from outside and also sometimes modified by the component itself as well. 'data_addr' is the address where the value of the parameter is to be stored. 'data_addr' must point to memory allocated by hal_malloc(). Typically the component allocates space for a data structure with hal_malloc(), and 'data_addr' is the address of a member of that structure. Creating the paremeter does not initialize or modify the value at *data_addr - the component should load a reasonable default value. 'comp_id' is the ID of the component that will 'own' the parameter. Normally it should be the ID of the caller, but in some cases, a user mode component may be doing setup for a realtime component, so the ID should be that of the realtime component that will actually be using the parameter. If successful, the hal_param_xxx_new() functions return 0. On failure they return a negative error code.

hal_param_bit_newf

printf_style-style versions of hal_param_XXX_new

hal_param_bit_set

The 'hal_param_xxx_set()' functions modify the value of a parameter. 'name' is the name of the parameter that is to be set. The parameter type must match the function type, and the parameter must not be read-only. 'value' is the value to be loaded into the parameter. On success, the hal_param_xxx_set() functions return 0, and on failure they return a negative error code.

hal_param_float_new
hal_param_float_newf
hal_param_float_set
hal_param_new

'hal_param_new()' creates a new 'parameter' object. It is a generic version of the eight functions above. It is provided ONLY for those special cases where a generic function is needed. It is STRONGLY recommended that the functions above be used instead, because they check the type of 'data_addr' against the parameter type at compile time. Using this function requires a cast of the 'data_addr' argument that defeats type checking and can cause subtle bugs. 'name', 'data_addr' and 'comp_id' are the same as in the functions above. 'type' is the hal type of the new parameter - the type of data that will be stored in the parameter. 'dir' is the parameter direction. HAL_RO parameters are read only from outside, and are written to by the component itself, typically to provide a view "into" the component for testing or troubleshooting. HAL_RW parameters are writable from outside and also sometimes modified by the component itself as well. If successful, hal_param_new() returns 0. On failure it returns a negative error code.

hal_param_s32_new
hal_param_s32_newf
hal_param_s32_set
hal_param_set

'hal_param_set()' is a generic function that sets the value of a parameter. It is provided ONLY for those special cases where a generic function is needed. It is STRONGLY recommended that the functions above be used instead, because they are simpler and less prone to errors. 'name', is the same as in the functions above. 'type' is the hal type of the the data at *value_addr, and must match the type of the parameter. The parameter must not be read only. 'value_addr' is a pointer to the new value of the parameter. The data at that location will be interpreted according to the type of the parameter. If successful, hal_param_set() returns 0. On failure it returns a negative error code.

hal_param_u32_new
hal_param_u32_newf
hal_param_u32_set
hal_pin_alias

'hal_pin_alias()' assigns an alternate name, aka an alias, to a pin. Once assigned, the pin can be referred to by either its original name or the alias. Calling this function with 'alias' set to NULL will remove any existing alias.

hal_pin_bit_new

The 'hal_pin_xxx_new()' functions create a new 'pin' object. Once a pin has been created, it can be linked to a signal object using hal_link(). A pin contains a pointer, and the component that owns the pin can dereference the pointer to access whatever signal is linked to the pin. (If no signal is linked, it points to a dummy signal.) There are eight functions, one for each of the data types that the HAL supports. Pins may only be linked to signals of the same type. 'name' is the name of the new pin. It must be no longer than HAL_NAME_LEN. If there is already a pin with the same name the call will fail. 'dir' is the pin direction. It indicates whether the pin is an input or output from the component. 'data_ptr_addr' is the address of the pointer that the component will use for the pin. When the pin is linked to a signal, the pointer at 'data_ptr_addr' will be changed to point to the signal data location. 'data_ptr_addr' must point to memory allocated by hal_malloc(). Typically the component allocates space for a data structure with hal_malloc(), and 'data_ptr_addr' is the address of a member of that structure. 'comp_id' is the ID of the component that will 'own' the variable. Normally it should be the ID of the caller, but in some cases, a user mode component may be doing setup for a realtime component, so the ID should be that of the realtime component that will actually be using the pin. If successful, the hal_pin_xxx_new() functions return 0. On failure they return a negative error code.

hal_pin_bit_newf

The hal_pin_XXX_newf family of functions are similar to hal_pin_XXX_new except that they also do printf-style formatting to compute the pin name If successful, the hal_pin_xxx_newf() functions return 0. On failure they return a negative error code.

hal_pin_float_new
hal_pin_float_newf
hal_pin_new

'hal_pin_new()' creates a new 'pin' object. It is a generic version of the eight functions above. It is provided ONLY for those special cases where a generic function is needed. It is STRONGLY recommended that the functions above be used instead, because they check the type of 'data_ptr_addr' against the pin type at compile time. Using this function requires a cast of the 'data_ptr_addr' argument that defeats type checking and can cause subtle bugs. 'name', 'dir', 'data_ptr_addr' and 'comp_id' are the same as in the functions above. 'type' is the hal type of the new pin - the type of data that will be passed in/out of the component through the new pin. If successful, hal_pin_new() returns 0. On failure it returns a negative error code.

hal_pin_s32_new
hal_pin_s32_newf
hal_pin_u32_new
hal_pin_u32_newf
hal_ready

hal_ready() indicates that this component is ready. This allows halcmd 'loadusr -W hal_example' to wait until the userspace component 'hal_example' is ready before continuing.

hal_set_constructor

hal_set_constructor() sets the constructor function for this component

hal_set_lock

"LOCKING" FUNCTIONS * locking types defined in hal.h HAL_LOCK_NONE -locks none HAL_LOCK_* - intermediate locking levels HAL_LOCK_ALL - locks everything

hal_signal_delete

'hal_signal_delete()' deletes a signal object. Any pins linked to the object are unlinked. 'name' is the name of the signal to be deleted. If successful, 'hal_signal_delete()' returns 0. On failure, it returns a negative error code.

hal_signal_new

'hal_signal_new()' creates a new signal object. Once a signal has been created, pins can be linked to it with hal_link(). The signal object contains the actual storage for the signal data. Pin objects linked to the signal have pointers that point to the data. 'name' is the name of the new signal. It must be no longer than HAL_NAME_LEN. If there is already a signal with the same name the call will fail. 'type' is the data type handled by the signal. Pins can only be linked to a signal of the same type. Note that the actual address of the data storage for the signal is not accessible. The data can be accessed only by linking a pin to the signal. Also note that signals, unlike pins, do not have 'owners'. Once created, a signal remains in place until either it is deleted, or the last HAL component exits. If successful, 'hal_signal_new() returns 0. On failure it returns a negative error code.

hal_start_threads

hal_start_threads() starts all threads that have been created. This is the point at which realtime functions start being called. On success it returns 0, on failure a negative error code.

hal_stop_threads

hal_stop_threads() stops all threads that were previously started by hal_start_threads(). It should be called before any component that is part of a system exits. On success it returns 0, on failure a negative error code.

hal_unlink

'hal_unlink()' unlinks any signal from the specified pin. 'pin_name' is a string containing the pin name. On success, hal_unlink() returns 0, on failure it returns a negative error code.

imaxabs
imaxdiv
rtapi_exit

'rtapi_exit()' shuts down and cleans up the RTAPI. It must be called prior to exit by any module that called rtapi_init. 'module_id' is the ID code returned when that module called rtapi_init(). Returns a status code. rtapi_exit() may attempt to clean up any tasks, shared memory, and other resources allocated by the module, but should not be relied on to replace proper cleanup code within the module. Call only from within user or init/cleanup code, not from realtime tasks.

rtapi_fifo_delete

'rtapi_fifo_delete()' is the counterpart to 'rtapi_fifo_new()'. It closes the fifo associated with 'fifo_ID'. 'module_id' is the ID of the calling module. Returns status code. Call only from within user or init/cleanup code, not from realtime tasks.

rtapi_fifo_new

'rtapi_fifo_new()' creates a realtime fifo. 'key' identifies the fifo, all modules wishing to access the same fifo must use the same key. 'module_id' is the ID of the module making the call (see rtapi_init). 'size' is the depth of the fifo. 'mode' is either 'R' or 'W', to request either read or write access to the fifo. On success, it returns a positive integer ID, which is used for subsequent calls dealing with the fifo. On failure, returns a negative error code. Call only from within user or init/cleanup code, not from realtime tasks.

rtapi_fifo_read
rtapi_fifo_write
rtapi_get_clocks

rtapi_get_clocks returns the current time in CPU clocks. It is fast, since it just reads the TSC in the CPU instead of calling a kernel or RTOS function. Of course, times measured in CPU clocks are not as convenient, but for relative measurements this works fine. Its absolute value means nothing, but it is monotonically increasing* and can be used to schedule future events, or to time the duration of some activity. (* on SMP machines, the two TSC's may get out of sync, so if a task reads the TSC, gets swapped to the other CPU, and reads again, the value may decrease. RTAPI tries to force all RT tasks to run on one CPU.) Returns a 64 bit value. The resolution of the returned value is one CPU clock, which is usually a few nanoseconds to a fraction of a nanosecond. May be called from init/cleanup code, and from within realtime tasks.

rtapi_get_msg_level

Retrieve the message level set by the last call to rtapi_set_msg_level

rtapi_get_time

rtapi_get_time returns the current time in nanoseconds. Depending on the RTOS, this may be time since boot, or time since the clock period was set, or some other time. Its absolute value means nothing, but it is monotonically increasing and can be used to schedule future events, or to time the duration of some activity. Returns a 64 bit value. The resolution of the returned value may be as good as one nano-second, or as poor as several microseconds. May be called from init/cleanup code, and from within realtime tasks.

rtapi_inb

'rtapi_inb() gets a byte from 'port'. Returns the byte. May be called from init/cleanup code, and from within realtime tasks. Note: This function always returns zero on the simulated RTOS. Note: Many platforms provide an inline inb() that is faster.

rtapi_init

'rtapi_init() sets up the RTAPI. It must be called by any module that intends to use the API, before any other RTAPI calls. 'modname' can optionally point to a string that identifies the module. The string will be truncated at RTAPI_NAME_LEN characters. If 'modname' is NULL, the system will assign a name. On success, returns a positive integer module ID, which is used for subsequent calls to rtapi_xxx_new, rtapi_xxx_delete, and rtapi_exit. On failure, returns an error code as defined above. Call only from within user or init/cleanup code, not from realtime tasks.

rtapi_is_kernelspace
rtapi_is_realtime
rtapi_outb

'rtapi_outb() writes 'byte' to 'port'. May be called from init/cleanup code, and from within realtime tasks. Note: This function does nothing on the simulated RTOS. Note: Many platforms provide an inline outb() that is faster.

rtapi_print

'rtapi_print()' prints a printf style message. Depending on the RTOS and whether the program is being compiled for user space or realtime, the message may be printed to stdout, stderr, or to a kernel message log, etc. The calling syntax and format string is similar to printf except that floating point and longlongs are NOT supported in realtime and may not be supported in user space. For some RTOS's, a 80 byte buffer is used, so the format line and arguments should not produce a line more than 80 bytes long. (The buffer is protected against overflow.) Does not block, but can take a fairly long time, depending on the format string and OS. May be called from user, init/cleanup, and realtime code.

rtapi_print_msg
rtapi_set_msg_level

Set the maximum level of message to print. In userspace code, each component has its own independent message level. In realtime code, all components share a single message level. Returns 0 for success or -EINVAL if the level is out of range.

rtapi_shmem_delete

'rtapi_shmem_delete()' frees the shared memory block associated with 'shmem_id'. 'module_id' is the ID of the calling module. Returns a status code. Call only from within user or init/cleanup code, not from realtime tasks.

rtapi_shmem_getptr

'rtapi_shmem_getptr()' sets '*ptr' to point to shared memory block associated with 'shmem_id'. Returns a status code. May be called from user code, init/cleanup code, or realtime tasks.

rtapi_shmem_new

'rtapi_shmem_new()' allocates a block of shared memory. 'key' identifies the memory block, and must be non-zero. All modules wishing to access the same memory must use the same key. 'module_id' is the ID of the module that is making the call (see rtapi_init). The block will be at least 'size' bytes, and may be rounded up. Allocating many small blocks may be very wasteful. When a particular block is allocated for the first time, the first 4 bytes are zeroed. Subsequent allocations of the same block by other modules or processes will not touch the contents of the block. Applications can use those bytes to see if they need to initialize the block, or if another module already did so. On success, it returns a positive integer ID, which is used for all subsequent calls dealing with the block. On failure it returns a negative error code. Call only from within user or init/cleanup code, not from realtime tasks.

rtapi_snprintf

'rtapi_snprintf()' works like 'snprintf()' from the normal C library, except that it may not handle long longs. It is provided here because some RTOS kernels don't provide a realtime safe version of the function, and those that do don't provide support for printing doubles. On systems with a good kernel snprintf(), or in user space, this function simply calls the normal snprintf(). May be called from user, init/cleanup, and realtime code.

rtapi_vsnprintf
sched_get_priority_max
sched_get_priority_min
sched_getparam
sched_getscheduler
sched_rr_get_interval
sched_setparam
sched_setscheduler
sched_yield
simple_strtol
strtoimax
strtoumax
wcstoimax
wcstoumax

Type Definitions

__blkcnt64_t
__blkcnt_t
__blksize_t
__builtin_va_list
__caddr_t
__clock_t
__clockid_t
__cpu_mask
__daddr_t
__dev_t
__fsblkcnt64_t
__fsblkcnt_t
__fsfilcnt64_t
__fsfilcnt_t
__fsword_t
__gid_t
__gnuc_va_list
__gwchar_t
__id_t
__ino64_t
__ino_t
__int8_t
__int16_t
__int32_t
__int64_t
__intmax_t
__intptr_t
__key_t
__loff_t
__mode_t
__nlink_t
__off64_t
__off_t
__pid_t
__quad_t
__rlim64_t
__rlim_t
__sig_atomic_t
__socklen_t
__ssize_t
__suseconds_t
__syscall_slong_t
__syscall_ulong_t
__time_t
__timer_t
__u_char
__u_int
__u_long
__u_quad_t
__u_short
__uid_t
__uint8_t
__uint16_t
__uint32_t
__uint64_t
__uintmax_t
__useconds_t
constructor

HAL 'constructor' typedef If it is not NULL, this points to a function which can construct a new instance of its component. Return value is >=0 for success, <0 for error.

hal_bit_t
hal_param_dir_t

HAL parameters also have a direction attribute. For parameters, the attribute determines whether the user can write the value of the parameter, or simply read it. HAL_RO parameters are read-only, and HAL_RW ones are writable with 'halcmd setp'.

hal_pin_dir_t

HAL pins have a direction attribute. A pin may be an input to the HAL component, an output, or it may be bidirectional. Any number of HAL_IN or HAL_IO pins may be connected to the same signal, but only one HAL_OUT pin is permitted. This is equivalent to connecting two output pins together in an electronic circuit. (HAL_IO pins can be thought of as tri-state outputs.)

hal_s32_t
hal_type_t

HAL pins and signals are typed, and the HAL only allows pins to be attached to signals of the same type. All HAL types can be read or written atomically. (Read-modify- write operations are not atomic.) Note that when a component reads or writes one of its pins, it is actually reading or writing the signal linked to that pin, by way of the pointer. 'hal_type_t' is an enum used to identify the type of a pin, signal, or parameter.

hal_u32_t
int_fast8_t
int_fast16_t
int_fast32_t
int_fast64_t
int_least8_t
int_least16_t
int_least32_t
int_least64_t
intmax_t
ireal_t
msg_level_t

'rtapi_print_msg()' prints a printf-style message when the level is less than or equal to the current message level set by rtapi_set_msg_level(). May be called from user, init/cleanup, and realtime code.

pid_t
real_t
rtapi_msg_handler_t

'rtapi_get_msg_handler' and 'rtapi_set_msg_handler' access the function pointer used by rtapi_print and rtapi_print_msg. By default, messages appear in the kernel log, but by replacing the handler a user of the rtapi library can send the messages to another destination. Calling rtapi_set_msg_handler with NULL restores the default handler. Call from real-time init/cleanup code only. When called from rtapi_print(), 'level' is RTAPI_MSG_ALL, a level which should not normally be used with rtapi_print_msg().

rtapi_s8
rtapi_s16
rtapi_s32
rtapi_s64
rtapi_u8
rtapi_u16
rtapi_u32
rtapi_u64
time_t
uint_fast8_t
uint_fast16_t
uint_fast32_t
uint_fast64_t
uint_least8_t
uint_least16_t
uint_least32_t
uint_least64_t
uintmax_t
va_list
wchar_t