LinuxCNC Documentation

SYNOPSIS

#include <hal.h>

typedef int (*hal_query_cb)(hal_query_t *query, void *arg);

int hal_set_s(hal_query_t *query, hal_query_cb callback, void *arg);

ARGUMENTS

query

The query structure containing the name to search for and value to set.

callback

The callback function to invoke when the signal has been found to get the value to set. This can also be NULL if no callback is required. Both query.sig.value and query.sig.type must be appropriately set if callback is NULL.

arg

A user defined pointer to a user defined data structure. The arg pointer is passed verbatim to the callback function.

DESCRIPTION

The hal_set_s() function will find the named signal and set its value to the user supplied value. The query structure should be set to zero before the call, except for the fields noted below.

The query.name must be set to the name of the signal you want to set.

You can further limit the search by setting query.sig.type to the HAL type you want to set. If the signal is found, but has a different type, then -EEXIST is returned.

Setting a signal with a writer pin connected will fail with an -EACCES error.

The callback is called with all fields set appropriately, including data reference. You must set the correct query.sig.value subfield in the callback according to the query.sig.type field. The signal’s value will be set if the callback returns with zero (0).

If you do not wish to use a callback, then you must set both query.sig.type and query.sig.value beforehand. The actual type will be checked against what is found and a mismatch will result in an -EEXIST error.

If found, hal_set_s() sets the query.name field to the actual live signal name.

Setting a signal of type HAL_PORT will allocate the port’s message queue. The size of the queue is determined by the value passed in query.sig.value.u. A port’s queue size cannot be larger than 65536 bytes. Trying to reallocate a port’s queue will fail with an -EISCONN error.

RETURN VALUE

The hal_set_s() function returns zero (0) on success. The return value of the callback is returned if it got called and was non-zero. A negative errno code is returned if any problem is detected:

-EFAULT

The shared memory was not mapped.

-EINVAL

An invalid argument was passed.

-ENOENT

The signal does not exist.

-EEXIST

The signal exists but is of different type.

-EACCES

Trying to write a signal with HAL_OUT a pin connected.

-EISCONN

Attempt to set a HAL_PORT signal with an allocated queue.

-EBADF

The signal type is not supported.

-EIO

The internal data pointer is missing.

EXAMPLES

int set_sig_fpval(const char *signame, rtapi_real val)
{
    hal_query_t query = {};
    query.name = signame;
    query.sig.type = HAL_REAL;  // We want to set a floating point value
    query.sig.value.r = val;    // This is the value

    int rv = hal_set_s(&query, NULL, NULL);

    if(0 != rv)
        printf("Failed to set '%s': %s\n", signame, hal_strerror(rv));
    return rv;
}
static int sigsetter_cb(hal_query_t *query, void *arg)
{
    const char *str = (const char *)arg;

    // Perform conversion based on type
    switch(query->sig.type) {
    case HAL_BOOL: query->sig.value.b = str2bool(str); break;
    case HAL_REAL: query->sig.value.r = str2real(str); break;
    case HAL_SINT: query->sig.value.s = str2sint(str); break;
    case HAL_UINT: query->sig.value.u = str2uint(str); break;

    case HAL_PORT: // This you'd normally handle as a special case in your code
    default:
        printf("unsupported value type %d\n", (int)query->sig.type);
        return -EBADF;
    }

    return 0;
}

int set_s_val(const char *signame, const char *str)
{
    hal_query_t query = {};
    query.name = signame;

    int rv = hal_set_s(&query, sigsetter_cb, (void *)str);

    if(0 != rv)
        printf("Failed to set '%s' to '%s': %s\n", signame, str, hal_strerror(rv));
    return rv;
}

SEE ALSO

hal_query_t(3), hal_get_p(3), hal_set_s(3)