798 lines
22 KiB
C
798 lines
22 KiB
C
/**
|
|
* @ingroup fifos
|
|
* @ingroup fifos_ipc
|
|
* @ingroup fifos_sem
|
|
* @file
|
|
*
|
|
* Interface of the @ref fifos "RTAI FIFO module".
|
|
*
|
|
* @note Copyright © 1999-2003 Paolo Mantegazza <mantegazza@aero.polimi.it>
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License as
|
|
* published by the Free Software Foundation; either version 2 of the
|
|
* License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
*/
|
|
|
|
#ifndef _RTAI_FIFOS_H
|
|
#define _RTAI_FIFOS_H
|
|
|
|
#include <rtai_types.h>
|
|
|
|
#define MAX_FIFOS 64
|
|
|
|
#define RTAI_FIFOS_MAJOR 150
|
|
|
|
#define RESET 1
|
|
#define RESIZE 2
|
|
#define RTF_SUSPEND_TIMED 3
|
|
#define OPEN_SIZED 4
|
|
#define READ_ALL_AT_ONCE 5
|
|
#define READ_TIMED 6
|
|
#define WRITE_TIMED 7
|
|
#define RTF_SEM_INIT 8
|
|
#define RTF_SEM_WAIT 9
|
|
#define RTF_SEM_TRYWAIT 10
|
|
#define RTF_SEM_TIMED_WAIT 11
|
|
#define RTF_SEM_POST 12
|
|
#define RTF_SEM_DESTROY 13
|
|
#define SET_ASYNC_SIG 14
|
|
#define EAVESDROP 19
|
|
#define OVRWRITE 20
|
|
#define READ_IF 21
|
|
#define WRITE_IF 22
|
|
#define RTF_NAMED_CREATE 23
|
|
|
|
#define RTF_GET_N_FIFOS 15
|
|
#define RTF_GET_FIFO_INFO 16
|
|
#define RTF_CREATE_NAMED 17
|
|
#define RTF_NAME_LOOKUP 18
|
|
|
|
#define RTF_NAMELEN 15
|
|
|
|
struct rt_fifo_info_struct{
|
|
unsigned int fifo_number;
|
|
unsigned int size;
|
|
unsigned int opncnt;
|
|
int avbs, frbs;
|
|
char name[RTF_NAMELEN+1];
|
|
};
|
|
|
|
struct rt_fifo_get_info_struct{
|
|
unsigned int fifo;
|
|
unsigned int n;
|
|
struct rt_fifo_info_struct *ptr;
|
|
};
|
|
|
|
#define FUN_FIFOS_LXRT_INDX 10
|
|
|
|
#define _CREATE 0
|
|
#define _DESTROY 1
|
|
#define _PUT 2
|
|
#define _GET 3
|
|
#define _RESET 4
|
|
#define _RESIZE 5
|
|
#define _SEM_INIT 6
|
|
#define _SEM_DESTRY 7
|
|
#define _SEM_POST 8
|
|
#define _SEM_TRY 9
|
|
#define _CREATE_NAMED 10
|
|
#define _GETBY_NAME 11
|
|
#define _OVERWRITE 12
|
|
#define _PUT_IF 13
|
|
#define _GET_IF 14
|
|
#define _NAMED_CREATE 15
|
|
#define _AVBS 16
|
|
#define _FRBS 17
|
|
|
|
#ifdef __KERNEL__
|
|
|
|
#include <rtai.h>
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif /* __cplusplus */
|
|
|
|
int __rtai_fifos_init(void);
|
|
|
|
void __rtai_fifos_exit(void);
|
|
|
|
int rtf_init(void);
|
|
|
|
typedef int (*rtf_handler_t)(unsigned int fifo, int rw);
|
|
|
|
/* Attach a handler to an RT-FIFO.
|
|
*
|
|
* Allow function handler to be called when a user process reads or writes to
|
|
* the FIFO. When the function is called, it is passed the fifo number as the
|
|
* argument.
|
|
*/
|
|
|
|
int rtf_create_handler(unsigned int fifo, /* RT-FIFO */
|
|
void *handler /* function to be called */);
|
|
|
|
|
|
/**
|
|
* @ingroup fifos_ipc
|
|
* Extended fifo handler.
|
|
*
|
|
* The usage of X_FIFO_HANDLER(handler) allows to install an extended handler,
|
|
* i.e. one prototyped as:
|
|
* @code
|
|
* int (*handler)(unsigned int fifo, int rw);
|
|
* @endcode
|
|
* to allow the user to easily understand if the handler was called at fifo
|
|
* read (@a rw is 'r') or write (rw is 'w').
|
|
*/
|
|
#define X_FIFO_HANDLER(handler) ((int (*)(unsigned int, int rw))(handler))
|
|
|
|
/* Create an RT-FIFO.
|
|
*
|
|
* An RT-FIFO fifo is created with initial size of size.
|
|
* Return value: On success, 0 is returned. On error, -1 is returned.
|
|
*/
|
|
#undef rtf_create
|
|
RTAI_SYSCALL_MODE int rtf_create(unsigned int fifo, int size);
|
|
|
|
/* Create an RT-FIFO with a name and size.
|
|
*
|
|
* An RT-FIFO is created with a name of name, it will be allocated
|
|
* the first unused minor number and will have a user assigned size.
|
|
* Return value: On success, the allocated minor number is returned.
|
|
* On error, -errno is returned.
|
|
*/
|
|
|
|
int rtf_named_create(const char *name, int size);
|
|
|
|
/* Create an RT-FIFO with a name.
|
|
*
|
|
* An RT-FIFO is created with a name of name, it will be allocated
|
|
* the first unused minor number and will have a default size.
|
|
* Return value: On success, the allocated minor number is returned.
|
|
* On error, -errno is returned.
|
|
*/
|
|
|
|
RTAI_SYSCALL_MODE int rtf_create_named(const char *name);
|
|
|
|
/* Look up a named RT-FIFO.
|
|
*
|
|
* Find the RT-FIFO with the name name.
|
|
* Return value: On success, the minor number is returned.
|
|
* On error, -errno is returned.
|
|
*/
|
|
|
|
RTAI_SYSCALL_MODE int rtf_getfifobyname(const char *name);
|
|
|
|
/* Reset an RT-FIFO.
|
|
*
|
|
* An RT-FIFO fifo is reset by setting its buffer pointers to zero, so
|
|
* that any existing data is discarded and the fifo started anew like at its
|
|
* creation.
|
|
*/
|
|
|
|
RTAI_SYSCALL_MODE int rtf_reset(unsigned int fifo);
|
|
|
|
/* destroy an RT-FIFO.
|
|
*
|
|
* Return value: On success, 0 is returned.
|
|
*/
|
|
|
|
RTAI_SYSCALL_MODE int rtf_destroy(unsigned int fifo);
|
|
|
|
|
|
/* Resize an RT-FIFO.
|
|
*
|
|
* Return value: size is returned on success. On error, a negative value
|
|
* is returned.
|
|
*/
|
|
|
|
RTAI_SYSCALL_MODE int rtf_resize(unsigned int minor, int size);
|
|
|
|
|
|
/* Write to an RT-FIFO.
|
|
*
|
|
* Try to write count bytes to an FIFO. Returns the number of bytes written.
|
|
*/
|
|
|
|
RTAI_SYSCALL_MODE int rtf_put(unsigned int fifo, /* RT-FIFO */
|
|
void * buf, /* buffer address */
|
|
int count /* number of bytes to write */);
|
|
|
|
|
|
|
|
/* Write to an RT-FIFO, over writing if there is not enough space.
|
|
*
|
|
* Try to write count bytes to an FIFO. Returns 0.
|
|
*/
|
|
|
|
RTAI_SYSCALL_MODE int rtf_ovrwr_put(unsigned int fifo, /* RT-FIFO */
|
|
void * buf, /* buffer address */
|
|
int count /* number of bytes to write */);
|
|
|
|
|
|
|
|
/* Write atomically to an RT-FIFO.
|
|
*
|
|
* Try to write count bytes in block to an FIFO. Returns the number of bytes
|
|
* written.
|
|
*/
|
|
|
|
extern RTAI_SYSCALL_MODE int rtf_put_if (unsigned int fifo, /* RT-FIFO */
|
|
void * buf, /* buffer address */
|
|
int count /* number of bytes to write */);
|
|
|
|
/* Read from an RT-FIFO.
|
|
*
|
|
* Try to read count bytes from a FIFO. Returns the number of bytes read.
|
|
*/
|
|
|
|
RTAI_SYSCALL_MODE int rtf_get(unsigned int fifo, /* RT-FIFO */
|
|
void * buf, /* buffer address */
|
|
int count /* number of bytes to read */);
|
|
|
|
|
|
/* Atomically read from an RT-FIFO.
|
|
*
|
|
* Try to read count bytes in a block from an FIFO. Returns the number of bytes read.
|
|
*/
|
|
|
|
RTAI_SYSCALL_MODE int rtf_get_if(unsigned int fifo, /* RT-FIFO */
|
|
void * buf, /* buffer address */
|
|
int count /* number of bytes to read */);
|
|
|
|
|
|
/*
|
|
* Preview the an RT-FIFO content.
|
|
*/
|
|
|
|
int rtf_evdrp(unsigned int fifo, /* RT-FIFO */
|
|
void * buf, /* buffer address */
|
|
int count /* number of bytes to read */);
|
|
|
|
/* Open an RT-FIFO semaphore.
|
|
*
|
|
*/
|
|
|
|
RTAI_SYSCALL_MODE int rtf_sem_init(unsigned int fifo, /* RT-FIFO */
|
|
int value /* initial semaphore value */);
|
|
|
|
|
|
/* Post to an RT-FIFO semaphore.
|
|
*
|
|
*/
|
|
|
|
RTAI_SYSCALL_MODE int rtf_sem_post(unsigned int fifo /* RT-FIFO */);
|
|
|
|
|
|
/* Try to acquire an RT-FIFO semaphore.
|
|
*
|
|
*/
|
|
|
|
RTAI_SYSCALL_MODE int rtf_sem_trywait(unsigned int fifo /* RT-FIFO */);
|
|
|
|
|
|
/* Destroy an RT-FIFO semaphore.
|
|
*
|
|
*/
|
|
|
|
RTAI_SYSCALL_MODE int rtf_sem_destroy(unsigned int fifo /* RT-FIFO */);
|
|
|
|
#define rtf_sem_delete rtf_sem_destroy
|
|
|
|
|
|
/* Get an RT-FIFO free bytes in buffer.
|
|
*
|
|
*/
|
|
|
|
RTAI_SYSCALL_MODE int rtf_get_frbs(unsigned int fifo /* RT-FIFO */);
|
|
|
|
/* Just for compatibility with earlier rtai_fifos releases. No more bh and user
|
|
buffers. Fifos are now awakened immediately and buffers > 128K are vmalloced */
|
|
|
|
#define rtf_create_using_bh(fifo, size, bh_list) rtf_create(fifo, size)
|
|
#define rtf_create_using_bh_and_usr_buf(fifo, buf, size, bh_list) rtf_create(fifo, size)
|
|
#define rtf_destroy_using_usr_buf(fifo) rtf_destroy(fifo)
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif /* __cplusplus */
|
|
|
|
#else /* !__KERNEL__ */
|
|
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/ioctl.h>
|
|
#include <fcntl.h>
|
|
#include <unistd.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <rtai_lxrt.h>
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif /* __cplusplus */
|
|
|
|
RTAI_PROTO(int, rtf_create,(unsigned int fifo, int size))
|
|
{
|
|
struct { unsigned long fifo, size; } arg = { fifo, size };
|
|
return rtai_lxrt(FUN_FIFOS_LXRT_INDX, SIZARG, _CREATE, &arg).i[LOW];
|
|
}
|
|
|
|
RTAI_PROTO(int, rtf_destroy,(unsigned int fifo))
|
|
{
|
|
struct { unsigned long fifo; } arg = { fifo };
|
|
return rtai_lxrt(FUN_FIFOS_LXRT_INDX, SIZARG, _DESTROY, &arg).i[LOW];
|
|
}
|
|
|
|
RTAI_PROTO(int, rtf_put,(unsigned int fifo, const void *buf, int count))
|
|
{
|
|
struct { unsigned long fifo; const void *buf; long count; } arg = { fifo, buf, count };
|
|
return rtai_lxrt(FUN_FIFOS_LXRT_INDX, SIZARG, _PUT, &arg).i[LOW];
|
|
}
|
|
|
|
RTAI_PROTO(int, rtf_put_if,(unsigned int fifo, const void *buf, int count))
|
|
{
|
|
struct { unsigned long fifo; const void *buf; long count; } arg = { fifo, buf, count };
|
|
return rtai_lxrt(FUN_FIFOS_LXRT_INDX, SIZARG, _PUT_IF, &arg).i[LOW];
|
|
}
|
|
|
|
RTAI_PROTO(int, rtf_get,(unsigned int fifo, void *buf, int count))
|
|
{
|
|
struct { unsigned long fifo; void *buf; long count; } arg = { fifo, buf, count };
|
|
return rtai_lxrt(FUN_FIFOS_LXRT_INDX, SIZARG, _GET, &arg).i[LOW];
|
|
}
|
|
|
|
RTAI_PROTO(int, rtf_get_if,(unsigned int fifo, void *buf, int count))
|
|
{
|
|
struct { unsigned long fifo; void *buf; long count; } arg = { fifo, buf, count };
|
|
return rtai_lxrt(FUN_FIFOS_LXRT_INDX, SIZARG, _GET_IF, &arg).i[LOW];
|
|
}
|
|
|
|
RTAI_PROTO(int, rtf_get_avbs, (unsigned int fifo))
|
|
{
|
|
struct { unsigned long fifo; } arg = { fifo };
|
|
return rtai_lxrt(FUN_FIFOS_LXRT_INDX, SIZARG, _AVBS, &arg).i[LOW];
|
|
}
|
|
|
|
RTAI_PROTO(int, rtf_get_frbs, (unsigned int fifo))
|
|
{
|
|
struct { unsigned long fifo; } arg = { fifo };
|
|
return rtai_lxrt(FUN_FIFOS_LXRT_INDX, SIZARG, _FRBS, &arg).i[LOW];
|
|
}
|
|
|
|
RTAI_PROTO(int, rtf_reset_lxrt,(unsigned int fifo))
|
|
{
|
|
struct { unsigned long fifo; } arg = { fifo };
|
|
return rtai_lxrt(FUN_FIFOS_LXRT_INDX, SIZARG, _RESET, &arg).i[LOW];
|
|
}
|
|
|
|
RTAI_PROTO(int, rtf_resize_lxrt,(unsigned int fifo, int size))
|
|
{
|
|
struct { unsigned long fifo, size; } arg = { fifo, size };
|
|
return rtai_lxrt(FUN_FIFOS_LXRT_INDX, SIZARG, _RESIZE, &arg).i[LOW];
|
|
}
|
|
|
|
RTAI_PROTO(int, rtf_sem_init_lxrt,(unsigned int fifo, int value))
|
|
{
|
|
struct { unsigned long fifo, value; } arg = { fifo, value };
|
|
return rtai_lxrt(FUN_FIFOS_LXRT_INDX, SIZARG, _SEM_INIT, &arg).i[LOW];
|
|
}
|
|
|
|
RTAI_PROTO(int, rtf_sem_post_lxrt,(unsigned int fifo))
|
|
{
|
|
struct { unsigned long fifo; } arg = { fifo };
|
|
return rtai_lxrt(FUN_FIFOS_LXRT_INDX, SIZARG, _SEM_POST, &arg).i[LOW];
|
|
}
|
|
|
|
RTAI_PROTO(int, rtf_sem_trywait_lxrt,(unsigned int fifo))
|
|
{
|
|
struct { unsigned long fifo; } arg = { fifo };
|
|
return rtai_lxrt(FUN_FIFOS_LXRT_INDX, SIZARG, _SEM_TRY, &arg).i[LOW];
|
|
}
|
|
|
|
RTAI_PROTO(int, rtf_sem_destroy_lxrt,(unsigned int fifo))
|
|
{
|
|
struct { unsigned long fifo; } arg = { fifo };
|
|
return rtai_lxrt(FUN_FIFOS_LXRT_INDX, SIZARG, _SEM_DESTRY, &arg).i[LOW];
|
|
}
|
|
|
|
RTAI_PROTO(int, rtf_named_create_lxrt,(const char *name, int size))
|
|
{
|
|
int len;
|
|
char lname[len = strlen(name)];
|
|
struct { char * name; long size; } arg = { lname, size };
|
|
strncpy(lname, name, len);
|
|
return rtai_lxrt(FUN_FIFOS_LXRT_INDX, SIZARG, _NAMED_CREATE, &arg).i[LOW];
|
|
}
|
|
|
|
RTAI_PROTO(int, rtf_create_named_lxrt,(const char *name))
|
|
{
|
|
int len;
|
|
char lname[len = strlen(name)];
|
|
struct { char * name; } arg = { lname };
|
|
strncpy(lname, name, len);
|
|
return rtai_lxrt(FUN_FIFOS_LXRT_INDX, SIZARG, _CREATE_NAMED, &arg).i[LOW];
|
|
}
|
|
|
|
RTAI_PROTO(int, rtf_getfifobyname_lxrt,(const char *name))
|
|
{
|
|
int len;
|
|
char lname[len = strlen(name)];
|
|
struct { char * name; } arg = { lname };
|
|
strncpy(lname, name, len);
|
|
return rtai_lxrt(FUN_FIFOS_LXRT_INDX, SIZARG, _GETBY_NAME, &arg).i[LOW];
|
|
}
|
|
|
|
RTAI_PROTO(int, rtf_ovrwr_put,(unsigned int fifo, const void *buf, int count))
|
|
{
|
|
struct { unsigned long fifo; const void *buf; long count; } arg = { fifo, buf, count };
|
|
return rtai_lxrt(FUN_FIFOS_LXRT_INDX, SIZARG, _OVERWRITE, &arg).i[LOW];
|
|
}
|
|
|
|
RTAI_PROTO(int, rtf_reset,(int fd))
|
|
{
|
|
int ret = ioctl(fd, RESET);
|
|
return ret < 0 ? -errno : ret;
|
|
}
|
|
|
|
RTAI_PROTO(int, rtf_resize,(int fd, int size))
|
|
{
|
|
int ret = ioctl(fd, RESIZE, size);
|
|
return ret < 0 ? -errno : ret;
|
|
}
|
|
|
|
/**
|
|
* @ingroup fifos_ipc
|
|
* Suspend a process for some time
|
|
*
|
|
* rtf_suspend_timed suspends a Linux process according to @a delay.
|
|
*
|
|
* @param fd is the file descriptor returned at fifo open, rtf_suspend_timed
|
|
* needs a fifo support.
|
|
* @param ms_delay is the timeout time in milliseconds.
|
|
*
|
|
* @note The standard, clumsy, way to achieve the same result is to use select
|
|
* with null file arguments, for long sleeps, with seconds resolution, sleep is
|
|
* also available.
|
|
*/
|
|
RTAI_PROTO(int, rtf_suspend_timed,(int fd, int ms_delay))
|
|
{
|
|
int ret = ioctl(fd, RTF_SUSPEND_TIMED, ms_delay);
|
|
return ret < 0 ? -errno : ret;
|
|
}
|
|
|
|
/**
|
|
* @ingroup fifos_ipc
|
|
* Create a real-time FIFO
|
|
*
|
|
* rtf_open_sized is the equivalent of rtf_create() in user space; it creates a
|
|
* real-time fifo (RT-FIFO) of initial size @a size.
|
|
*
|
|
* @param size is the requested size for the fifo.
|
|
*
|
|
* The RT-FIFO is a character based mechanism to communicate among real-time
|
|
* tasks and ordinary Linux processes. The rtf_* functions are used by the
|
|
* real-time tasks; Linux processes use standard character device access
|
|
* functions such as read, write, and select.
|
|
*
|
|
* If this function finds an existing fifo of lower size it resizes it to the
|
|
* larger new size. Note that the same condition apply to the standard Linux
|
|
* device open, except that when it does not find any already existing fifo it
|
|
* creates it with a default size of 1K bytes.
|
|
*
|
|
* It must be remarked that practically any fifo size can be asked for. In
|
|
* fact if @a size is within the constraint allowed by kmalloc such a function
|
|
* is used, otherwise vmalloc is called, thus allowing any size that can fit
|
|
* into the available core memory.
|
|
*
|
|
* Multiple calls of this function are allowed, a counter is kept internally to
|
|
* track their number, and avoid destroying/closing a fifo that is still used.
|
|
*
|
|
* @return the usual Unix file descriptor on succes, to be used in standard reads
|
|
* and writes.
|
|
* @retval -ENOMEM if the necessary size could not be allocated for the RT-FIFO.
|
|
*
|
|
* @note In user space, the standard UNIX open acts like rtf_open_sized with a
|
|
* default 1K size.
|
|
*/
|
|
RTAI_PROTO(int, rtf_open_sized,(const char *dev, int perm, int size))
|
|
{
|
|
int fd;
|
|
|
|
if ((fd = open(dev, perm)) < 0) {
|
|
return -errno;
|
|
}
|
|
if (ioctl(fd, RESIZE, size) < 0) {
|
|
close(fd);
|
|
return -errno;
|
|
}
|
|
return fd;
|
|
}
|
|
|
|
RTAI_PROTO(int, rtf_evdrp,(int fd, void *buf, int count))
|
|
{
|
|
struct { void *buf; long count; } args = { buf, count };
|
|
int ret = ioctl(fd, EAVESDROP, &args);
|
|
return ret < 0 ? -errno : ret;
|
|
}
|
|
|
|
/**
|
|
* @ingroup fifos_ipc
|
|
* Read data from FIFO in user space, waiting for all of them
|
|
*
|
|
* rtf_read_all_at_once reads a block of data from a real-time fifo identified
|
|
* by the file descriptor @a fd blocking till all waiting at most @a count
|
|
* bytes are available, whichever option was used at the related device
|
|
* opening.
|
|
*
|
|
* @param fd is the file descriptor returned at fifo open.
|
|
* @param buf points the block of data to be written.
|
|
* @param count is the size in bytes of the buffer.
|
|
*
|
|
* @return the number of bytes read on success.
|
|
* @retval -EINVAL if @a fd refers to a not opened fifo.
|
|
*/
|
|
RTAI_PROTO(int, rtf_read_all_at_once,(int fd, void *buf, int count))
|
|
{
|
|
struct { void *buf; long count; } args = { buf, count };
|
|
int ret = ioctl(fd, READ_ALL_AT_ONCE, &args);
|
|
return ret < 0 ? -errno : ret;
|
|
}
|
|
|
|
/**
|
|
* @ingroup fifos_ipc
|
|
* Read data from FIFO in user space, with timeout.
|
|
*
|
|
* rtf_read_timed reads a block of data from a real-time fifo identified by the
|
|
* file descriptor @a fd waiting at most @a delay milliseconds to complete the
|
|
* operation.
|
|
*
|
|
* @param fd is the file descriptor returned at fifo open.
|
|
* @param buf points the block of data to be written.
|
|
* @param count is the size of the block in bytes.
|
|
* @param ms_delay is the timeout time in milliseconds.
|
|
*
|
|
* @return the number of bytes read is returned on success or timeout. Note that
|
|
* this value may be less than @a count if @a count bytes of free space is not
|
|
* available in the fifo or a timeout occured.
|
|
* @retval -EINVAL if @a fd refers to a not opened fifo.
|
|
*
|
|
* @note The standard, clumsy, Unix way to achieve the same result is to use
|
|
* select.
|
|
*/
|
|
RTAI_PROTO(int, rtf_read_timed,(int fd, void *buf, int count, int ms_delay))
|
|
{
|
|
struct { void *buf; long count, delay; } args = { buf, count, ms_delay };
|
|
int ret = ioctl(fd, READ_TIMED, &args);
|
|
return ret < 0 ? -errno : ret;
|
|
}
|
|
|
|
RTAI_PROTO(int, rtf_read_if,(int fd, void *buf, int count))
|
|
{
|
|
struct { void *buf; long count; } args = { buf, count };
|
|
int ret = ioctl(fd, READ_IF, &args);
|
|
return ret < 0 ? -errno : ret;
|
|
}
|
|
|
|
/**
|
|
* @ingroup fifos_ipc
|
|
* Write data to FIFO in user space, with timeout.
|
|
*
|
|
* rtf_write_timed writes a block of data to a real-time fifo identified by the
|
|
* file descriptor @a fd waiting at most @æ delay milliseconds to complete the
|
|
* operation.
|
|
*
|
|
* @param fd is the file descriptor returned at fifo open.
|
|
* @param buf points the block of data to be written.
|
|
* @param count is the size of the block in bytes.
|
|
* @param ms_delay is the timeout time in milliseconds.
|
|
*
|
|
* @return the number of bytes written on succes. Note that this value may
|
|
* be less than @a count if @a count bytes of free space is not available in the
|
|
* fifo.
|
|
* @retval -EINVAL if @a fd refers to a not opened fifo.
|
|
*
|
|
* @note The standard, clumsy, Unix way to achieve the same result is to use
|
|
* select.
|
|
*/
|
|
RTAI_PROTO(int, rtf_write_timed,(int fd, void *buf, int count, int ms_delay))
|
|
{
|
|
struct { void *buf; long count, delay; } args = { buf, count, ms_delay };
|
|
int ret = ioctl(fd, WRITE_TIMED, &args);
|
|
return ret < 0 ? -errno : ret;
|
|
}
|
|
|
|
RTAI_PROTO(int, rtf_overwrite,(int fd, void *buf, int count))
|
|
{
|
|
struct { void *buf; long count; } args = { buf, count };
|
|
int ret = ioctl(fd, OVRWRITE, &args);
|
|
return ret < 0 ? -errno : ret;
|
|
}
|
|
|
|
RTAI_PROTO(int, rtf_write_if,(int fd, void *buf, int count))
|
|
{
|
|
struct { void *buf; long count; } args = { buf, count };
|
|
int ret = ioctl(fd, WRITE_IF, &args);
|
|
return ret < 0 ? -errno : ret;
|
|
}
|
|
|
|
RTAI_PROTO(int, rtf_sem_init,(int fd, int value))
|
|
{
|
|
int ret = ioctl(fd, RTF_SEM_INIT, value);
|
|
return ret < 0 ? -errno : ret;
|
|
}
|
|
|
|
/**
|
|
* @ingroup fifos_sem
|
|
* Take a semaphore.
|
|
*
|
|
* rtf_sem_wait waits for a event to be posted (signaled) to a semaphore. The
|
|
* semaphore value is set to tested and set to zero. If it was one
|
|
* rtf_sem_wait returns immediately. Otherwise the caller process is blocked and
|
|
* queued up in a priority order based on is POSIX real time priority.
|
|
*
|
|
* A process blocked on a semaphore returns when:
|
|
* - the caller task is in the first place of the waiting queue and somebody
|
|
* issues a rtf_sem_post;
|
|
* - an error occurs (e.g. the semaphore is destroyed).
|
|
*
|
|
* @param fd is the file descriptor returned by standard UNIX open in user space
|
|
*
|
|
* Since it is blocking rtf_sem_waitcannot be used both in kernel and user
|
|
* space.
|
|
*
|
|
* @retval 0 on success.
|
|
* @retval -EINVAL if @a fd_fifo refers to an invalid file descriptor or fifo.
|
|
*/
|
|
RTAI_PROTO(int, rtf_sem_wait,(int fd))
|
|
{
|
|
int ret = ioctl(fd, RTF_SEM_WAIT);
|
|
return ret < 0 ? -errno : ret;
|
|
}
|
|
|
|
RTAI_PROTO(int, rtf_sem_trywait,(int fd))
|
|
{
|
|
int ret = ioctl(fd, RTF_SEM_TRYWAIT);
|
|
return ret < 0 ? -errno : ret;
|
|
}
|
|
|
|
/**
|
|
* @ingroup fifos_sem
|
|
* Wait a semaphore with timeout
|
|
*
|
|
* rtf_sem_timed_wait is a timed version of the standard semaphore wait
|
|
* call. The semaphore value is tested and set to zero. If it was one
|
|
* rtf_sem_timed_wait returns immediately. Otherwise the caller process is
|
|
* blocked and queued up in a priority order based on is POSIX real time
|
|
* priority.
|
|
*
|
|
* A process blocked on a semaphore returns when:
|
|
* - the caller task is in the first place of the waiting queue and somebody
|
|
* issues a rtf_sem_post;
|
|
* - timeout occurs;
|
|
* - an error occurs (e.g. the semaphore is destroyed).
|
|
*
|
|
* @param fd is the file descriptor returned by standard UNIX open in user
|
|
* space. In case of timeout the semaphore value is set to one before return.
|
|
* @param ms_delay is in milliseconds and is relative to the Linux current time.
|
|
*
|
|
* Since it is blocking rtf_sem_timed_wait cannot be used both in kernel and
|
|
* user space.
|
|
*
|
|
* @retval 0 on success.
|
|
* @retval -EINVAL if fd_fifo refers to an invalid file descriptor or fifo.
|
|
*/
|
|
RTAI_PROTO(int, rtf_sem_timed_wait,(int fd, int ms_delay))
|
|
{
|
|
int ret = ioctl(fd, RTF_SEM_TIMED_WAIT, ms_delay);
|
|
return ret < 0 ? -errno : ret;
|
|
}
|
|
|
|
RTAI_PROTO(int, rtf_sem_post,(int fd))
|
|
{
|
|
int ret = ioctl(fd, RTF_SEM_POST);
|
|
return ret < 0 ? -errno : ret;
|
|
}
|
|
|
|
RTAI_PROTO(int, rtf_sem_destroy,(int fd))
|
|
{
|
|
int ret = ioctl(fd, RTF_SEM_DESTROY);
|
|
return ret < 0 ? -errno : ret;
|
|
}
|
|
|
|
/**
|
|
* @ingroup fifos_ipc
|
|
* Activate asynchronous notification of data availability
|
|
*
|
|
* rtf_set_async_sig activate an asynchronous signals to notify data
|
|
* availability by catching a user set signal signum.
|
|
*
|
|
* @param signum is a user chosen signal number to be used, default is SIGIO.
|
|
*
|
|
* @retval -EINVAL if fd refers to a not opened fifo.
|
|
*/
|
|
RTAI_PROTO(int, rtf_set_async_sig,(int fd, int signum))
|
|
{
|
|
int ret = ioctl(fd, SET_ASYNC_SIG, signum);
|
|
return ret < 0 ? -errno : ret;
|
|
}
|
|
|
|
/*
|
|
* Support for named FIFOS : Ian Soanes (ians@zentropix.com)
|
|
* Based on ideas from Stuart Hughes and David Schleef
|
|
*/
|
|
|
|
RTAI_PROTO_ALWAYS_INLINE(char *, rtf_getfifobyminor,(int minor, char *buf, int len))
|
|
{
|
|
snprintf(buf,len,CONFIG_RTAI_FIFOS_TEMPLATE,minor);
|
|
return buf;
|
|
}
|
|
|
|
RTAI_PROTO(int, rtf_getfifobyname,(const char *name))
|
|
{
|
|
int fd, minor;
|
|
char nm[RTF_NAMELEN+1];
|
|
|
|
if (strlen(name) > RTF_NAMELEN) {
|
|
return -1;
|
|
}
|
|
if ((fd = open(rtf_getfifobyminor(0,nm,sizeof(nm)), O_RDONLY)) < 0) {
|
|
return -errno;
|
|
}
|
|
strncpy(nm, name, RTF_NAMELEN+1);
|
|
minor = ioctl(fd, RTF_NAME_LOOKUP, nm);
|
|
close(fd);
|
|
return minor < 0 ? -errno : minor;
|
|
}
|
|
|
|
RTAI_PROTO(int, rtf_named_create,(const char *name, int size))
|
|
{
|
|
int fd, minor;
|
|
char nm[RTF_NAMELEN+1];
|
|
|
|
if (strlen(name) > RTF_NAMELEN) {
|
|
return -1;
|
|
}
|
|
if ((fd = open(rtf_getfifobyminor(0,nm,sizeof(nm)), O_RDONLY)) < 0) {
|
|
return -errno;
|
|
}
|
|
strncpy(nm, name, RTF_NAMELEN+1);
|
|
minor = ioctl(fd, RTF_NAMED_CREATE, nm, size);
|
|
close(fd);
|
|
return minor < 0 ? -errno : minor;
|
|
}
|
|
|
|
RTAI_PROTO(int, rtf_create_named,(const char *name))
|
|
{
|
|
int fd, minor;
|
|
char nm[RTF_NAMELEN+1];
|
|
|
|
if (strlen(name) > RTF_NAMELEN) {
|
|
return -1;
|
|
}
|
|
if ((fd = open(rtf_getfifobyminor(0,nm,sizeof(nm)), O_RDONLY)) < 0) {
|
|
return -errno;
|
|
}
|
|
strncpy(nm, name, RTF_NAMELEN+1);
|
|
minor = ioctl(fd, RTF_CREATE_NAMED, nm);
|
|
close(fd);
|
|
return minor < 0 ? -errno : minor;
|
|
}
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif /* __cplusplus */
|
|
|
|
#endif /* __KERNEL__ */
|
|
|
|
#endif /* !_RTAI_FIFOS_H */
|