|
From: <jmk...@us...> - 2003-07-19 07:17:25
|
Update of /cvsroot/emc/rtapi/src/rtapi
In directory sc8-pr-cvs1:/tmp/cvs-serv7212/src/rtapi
Modified Files:
localdefs.h rtai_rtapi.c rtai_ulapi.c rtapi.h sim_rtapi.c
sim_ulapi.c ulapi.h
Log Message:
sim and rtai implementations now match new API
Index: localdefs.h
===================================================================
RCS file: /cvsroot/emc/rtapi/src/rtapi/localdefs.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -d -r1.3 -r1.4
*** localdefs.h 19 Jul 2003 02:17:41 -0000 1.3
--- localdefs.h 19 Jul 2003 07:17:22 -0000 1.4
***************
*** 2,6 ****
#define LOCALDEFS_H
! /* automatically generated by config script on Fri Jul 18 22:11:03 EDT 2003 */
#define LOCAL_MHZ 233.866
--- 2,6 ----
#define LOCALDEFS_H
! /* automatically generated by config script on Fri Jul 18 22:40:51 EDT 2003 */
#define LOCAL_MHZ 233.866
Index: rtai_rtapi.c
===================================================================
RCS file: /cvsroot/emc/rtapi/src/rtapi/rtai_rtapi.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -d -r1.3 -r1.4
*** rtai_rtapi.c 19 Jul 2003 02:17:41 -0000 1.3
--- rtai_rtapi.c 19 Jul 2003 07:17:22 -0000 1.4
***************
*** 31,34 ****
--- 31,37 ----
+ /* These structs hold data associated with objects like tasks, etc. */
+ /* Task handles are pointers to these structs. */
+
struct rtapi_task {
int magic; /* to check for valid handle */
***************
*** 50,53 ****
--- 53,57 ----
struct rtapi_fifo {
int magic; /* to check for valid handle */
+ int key; /* key to fifo */
int fd; /* file descripter for fifo */
unsigned long int size; /* size of fifo area */
***************
*** 72,75 ****
--- 76,80 ----
}
+
int rtapi_prio_lowest(void)
{
***************
*** 77,80 ****
--- 82,86 ----
}
+
int rtapi_prio_next_higher(int prio)
{
***************
*** 89,92 ****
--- 95,99 ----
}
+
int rtapi_prio_next_lower(int prio)
{
***************
*** 107,110 ****
--- 114,118 ----
}
+
int rtapi_exit(void)
{
***************
*** 112,115 ****
--- 120,124 ----
}
+
int rtapi_clock_set_period(unsigned long int nsecs)
{
***************
*** 119,122 ****
--- 128,132 ----
}
+
int rtapi_task_new( rtapi_task_handle *taskptr )
{
***************
*** 128,132 ****
/* alloc space for task structure */
! task = kmalloc(sizeof(struct rtapi_task), GFP_USER);
if ( task == NULL )
return RTAPI_NOMEM;
--- 138,142 ----
/* alloc space for task structure */
! task = kmalloc( sizeof(struct rtapi_task), GFP_USER );
if ( task == NULL )
return RTAPI_NOMEM;
***************
*** 141,144 ****
--- 151,155 ----
}
+
int rtapi_task_delete( rtapi_task_handle task )
{
***************
*** 152,156 ****
task->magic = 0;
kfree( task );
! return 0;
}
--- 163,167 ----
task->magic = 0;
kfree( task );
! return RTAPI_SUCCESS;
}
***************
*** 171,174 ****
--- 182,190 ----
return RTAPI_BADH;
+ /* check requested priority */
+ if ( ( prio < rtapi_prio_highest() ) ||
+ ( prio > rtapi_prio_lowest() ) )
+ return RTAPI_INVAL;
+
/* call OS to initialize the task */
retval = rt_task_init( &(task->ostask), taskcode, arg,
***************
*** 182,186 ****
return RTAPI_NOMEM;
/* unknown error */
! return RTAPI_INVAL;
}
--- 198,202 ----
return RTAPI_NOMEM;
/* unknown error */
! return RTAPI_FAIL;
}
***************
*** 190,194 ****
nano2count((RTIME) period_nsec));
if ( retval != 0 )
! return RTAPI_INVAL;
}
else {
--- 206,210 ----
nano2count((RTIME) period_nsec));
if ( retval != 0 )
! return RTAPI_FAIL;
}
else {
***************
*** 196,200 ****
retval = rt_task_resume( &(task->ostask) );
if ( retval != 0 )
! return RTAPI_INVAL;
}
--- 212,216 ----
retval = rt_task_resume( &(task->ostask) );
if ( retval != 0 )
! return RTAPI_FAIL;
}
***************
*** 202,207 ****
--- 218,226 ----
}
+
int rtapi_task_stop( rtapi_task_handle task )
{
+ int retval;
+
/* validate task handle */
if ( task == NULL )
***************
*** 210,214 ****
return RTAPI_BADH;
! return rt_task_delete( &(task->ostask) );
}
--- 229,236 ----
return RTAPI_BADH;
! retval = rt_task_delete( &(task->ostask) );
! if ( retval != 0 )
! return RTAPI_FAIL;
! return RTAPI_SUCCESS;
}
***************
*** 216,219 ****
--- 238,243 ----
int rtapi_task_pause( rtapi_task_handle task )
{
+ int retval;
+
/* validate task handle */
if ( task == NULL )
***************
*** 222,230 ****
return RTAPI_BADH;
! return rt_task_suspend( &(task->ostask) );
}
int rtapi_task_resume( rtapi_task_handle task )
{
/* validate task handle */
if ( task == NULL )
--- 246,263 ----
return RTAPI_BADH;
! /* FIXME - depending on the version of rtai, a single
! call to resume() may or may not cancel multiple calls
! to suspend(). */
! retval = rt_task_suspend( &(task->ostask) );
! if ( retval != 0 )
! return RTAPI_FAIL;
! return RTAPI_SUCCESS;
}
+
int rtapi_task_resume( rtapi_task_handle task )
{
+ int retval;
+
/* validate task handle */
if ( task == NULL )
***************
*** 233,242 ****
return RTAPI_BADH;
! return rt_task_resume( &(task->ostask) );
}
int rtapi_task_set_period( rtapi_task_handle task,
unsigned long int period_nsec )
{
/* validate task handle */
if ( task == NULL )
--- 266,284 ----
return RTAPI_BADH;
! /* FIXME - depending on the version of rtai, a single
! call to resume() may or may not cancel multiple calls
! to suspend(). */
! retval = rt_task_resume( &(task->ostask) );
! if ( retval != 0 )
! return RTAPI_FAIL;
! return RTAPI_SUCCESS;
}
+
int rtapi_task_set_period( rtapi_task_handle task,
unsigned long int period_nsec )
{
+ int retval;
+
/* validate task handle */
if ( task == NULL )
***************
*** 245,252 ****
return RTAPI_BADH;
! return rt_task_make_periodic( &(task->ostask), rt_get_time(),
! nano2count((RTIME) period_nsec));
}
int rtapi_wait( void )
{
--- 287,298 ----
return RTAPI_BADH;
! retval = rt_task_make_periodic( &(task->ostask), rt_get_time(),
! nano2count((RTIME) period_nsec));
! if ( retval != 0 )
! return RTAPI_FAIL;
! return RTAPI_SUCCESS;
}
+
int rtapi_wait( void )
{
***************
*** 269,273 ****
if ( ptr == NULL )
/* called from outside a task? */
! return RTAPI_STATE;
/* ptr points to OS data, somewhere inside rtapi
--- 315,319 ----
if ( ptr == NULL )
/* called from outside a task? */
! return RTAPI_FAIL;
/* ptr points to OS data, somewhere inside rtapi
***************
*** 293,302 ****
/* alloc space for shmem structure */
! shmem = kmalloc(sizeof(struct rtapi_shmem), GFP_USER);
if ( shmem == NULL )
return RTAPI_NOMEM;
/* now get shared memory block from OS */
! shmem->mem = rtai_kmalloc(key, size);
if ( shmem->mem == NULL ) {
kfree ( shmem );
--- 339,348 ----
/* alloc space for shmem structure */
! shmem = kmalloc( sizeof(struct rtapi_shmem), GFP_USER );
if ( shmem == NULL )
return RTAPI_NOMEM;
/* now get shared memory block from OS */
! shmem->mem = rtai_kmalloc( key, size );
if ( shmem->mem == NULL ) {
kfree ( shmem );
***************
*** 347,350 ****
--- 393,397 ----
}
+
void rtapi_print(const char *fmt, ...)
{
***************
*** 362,365 ****
--- 409,413 ----
}
+
void rtapi_outb(unsigned char byte, unsigned int port)
{
***************
*** 367,370 ****
--- 415,419 ----
}
+
unsigned char rtapi_inb(unsigned int port)
{
***************
*** 372,375 ****
--- 421,425 ----
}
+
int rtapi_assign_interrupt_handler(unsigned int irq, void (*handler) (void))
{
***************
*** 377,384 ****
retval = rt_request_global_irq(irq, handler);
!
! return retval;
}
int rtapi_free_interrupt_handler(unsigned int irq)
{
--- 427,439 ----
retval = rt_request_global_irq(irq, handler);
! if ( retval != 0 )
! if ( retval == EBUSY )
! return RTAPI_BUSY;
! else
! return RTAPI_INVAL;
! return RTAPI_SUCCESS;
}
+
int rtapi_free_interrupt_handler(unsigned int irq)
{
***************
*** 387,413 ****
rt_shutdown_irq(irq);
retval = rt_free_global_irq(irq);
!
! return retval;
}
int rtapi_enable_interrupt(unsigned int irq)
{
rt_startup_irq(irq);
! return 0;
}
int rtapi_disable_interrupt(unsigned int irq)
{
rt_shutdown_irq(irq);
! return 0;
}
int rtapi_app_init(void)
{
! return 0;
}
void rtapi_app_return(void)
{
--- 442,473 ----
rt_shutdown_irq(irq);
retval = rt_free_global_irq(irq);
! if ( retval != 0 )
! return RTAPI_INVAL;
! return RTAPI_SUCCESS;
}
+
int rtapi_enable_interrupt(unsigned int irq)
{
rt_startup_irq(irq);
! return RTAPI_SUCCESS;
}
+
int rtapi_disable_interrupt(unsigned int irq)
{
rt_shutdown_irq(irq);
! return RTAPI_SUCCESS;
}
+
int rtapi_app_init(void)
{
! return RTAPI_SUCCESS;
}
+
void rtapi_app_return(void)
{
***************
*** 416,420 ****
-
int rtapi_sem_new( rtapi_sem_handle *semptr )
{
--- 476,479 ----
***************
*** 426,430 ****
/* alloc space for sem structure */
! sem = kmalloc(sizeof(struct rtapi_sem), GFP_USER);
if ( sem == NULL )
return RTAPI_NOMEM;
--- 485,489 ----
/* alloc space for sem structure */
! sem = kmalloc( sizeof(struct rtapi_sem), GFP_USER );
if ( sem == NULL )
return RTAPI_NOMEM;
***************
*** 459,462 ****
--- 518,522 ----
}
+
int rtapi_sem_give( rtapi_sem_handle sem )
{
***************
*** 472,475 ****
--- 532,536 ----
}
+
int rtapi_sem_take( rtapi_sem_handle sem )
{
***************
*** 485,489 ****
}
! extern int rtapi_sem_try( rtapi_sem_handle sem )
{
/* validate sem handle */
--- 546,551 ----
}
!
! int rtapi_sem_try( rtapi_sem_handle sem )
{
/* validate sem handle */
***************
*** 500,505 ****
! extern int rtapi_fifo_new( int key, unsigned long int size,
! rtapi_fifo_handle *fifoptr )
{
rtapi_fifo_handle fifo;
--- 562,567 ----
! int rtapi_fifo_new( int key, unsigned long int size,
! rtapi_fifo_handle *fifoptr )
{
rtapi_fifo_handle fifo;
***************
*** 511,515 ****
/* alloc space for fifo structure */
! fifo = kmalloc(sizeof(struct rtapi_fifo), GFP_USER);
if ( fifo == NULL )
return RTAPI_NOMEM;
--- 573,577 ----
/* alloc space for fifo structure */
! fifo = kmalloc( sizeof(struct rtapi_fifo), GFP_USER );
if ( fifo == NULL )
return RTAPI_NOMEM;
***************
*** 521,524 ****
--- 583,587 ----
retval = rtf_create ( key, size );
if ( retval != size ) {
+ /* create failed */
kfree ( fifo );
if ( retval == ENOMEM )
***************
*** 531,534 ****
--- 594,598 ----
fifo->magic = FIFO_MAGIC;
/* fill in the rest of the struct */
+ fifo->key = key;
fifo->fd = key;
***************
*** 538,541 ****
--- 602,606 ----
}
+
int rtapi_fifo_delete( rtapi_fifo_handle fifo )
{
***************
*** 555,558 ****
--- 620,624 ----
}
+
int rtapi_fifo_read( rtapi_fifo_handle fifo,
char *buf, unsigned long int size)
***************
*** 572,575 ****
--- 638,642 ----
return retval;
}
+
int rtapi_fifo_write( rtapi_fifo_handle fifo,
Index: rtai_ulapi.c
===================================================================
RCS file: /cvsroot/emc/rtapi/src/rtapi/rtai_ulapi.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -C2 -d -r1.1.1.1 -r1.2
*** rtai_ulapi.c 8 Jul 2003 15:54:38 -0000 1.1.1.1
--- rtai_ulapi.c 19 Jul 2003 07:17:22 -0000 1.2
***************
*** 4,7 ****
--- 4,8 ----
Implementation of user-level API to RTAI modules
*/
+ #include <stdio.h> /* sprintf() */
#include <stddef.h> /* NULL, needed for rtai_shm.h */
#include <unistd.h> /* open(), close() */
***************
*** 10,63 ****
#include <sys/fcntl.h> /* O_RDWR, needed for rtai_shm.h */
#include <rtai_shm.h> /* rtai_malloc,free() */
#include "ulapi.h"
int ulapi_init(void)
{
! return 0;
}
int ulapi_exit(void)
{
! return 0;
}
! int ulapi_alloc_shmem(int key, unsigned int size, int *id, void **ptr)
{
! *ptr = rtai_malloc(key, size);
! /* leave id alone; we don't use it */
! return 0;
}
! int ulapi_free_shmem(int key, unsigned int size, int id, const void *ptr)
{
! rtai_free(key, (void *) ptr);
- return 0;
}
! int ulapi_fifo_new(int key, int *fd, unsigned long int size)
{
! enum { DEVSTR_LEN = 256 };
! char devstr[DEVSTR_LEN];
sprintf(devstr, "/dev/rtf%d", key);
- *fd = open(devstr, O_RDONLY);
! return *fd;
}
! int ulapi_fifo_delete(int key, int fd, unsigned long int size)
{
! return close(fd);
}
! int ulapi_fifo_write(int fd, char *buf, unsigned long int size)
{
! return write(fd, buf, size);
}
! int ulapi_fifo_read(int fd, char *buf, unsigned long int size)
{
! return read(fd, buf, size);
}
--- 11,227 ----
#include <sys/fcntl.h> /* O_RDWR, needed for rtai_shm.h */
#include <rtai_shm.h> /* rtai_malloc,free() */
+ #include <malloc.h> /* malloc(), free() */
#include "ulapi.h"
+
+ /* These structs hold data associated with objects like tasks, etc. */
+ /* Task handles are pointers to these structs. */
+
+ struct ulapi_shmem {
+ int magic; /* to check for valid handle */
+ int key; /* key to shared memory area */
+ unsigned long int size; /* size of shared memory area */
+ void *mem; /* pointer to the memory */
+ };
+
+ struct ulapi_fifo {
+ int magic; /* to check for valid handle */
+ int key; /* key to fifo */
+ int fd; /* file descripter for fifo */
+ int mode; /* O_RDONLY or O_WRONLY */
+ unsigned long int size; /* size of fifo area */
+ };
+
+
+ #define SHMEM_MAGIC 25453 /* random numbers used as signatures */
+ #define FIFO_MAGIC 10293
+
+
int ulapi_init(void)
{
! /* does nothing, for now */
! return ULAPI_SUCCESS;
}
+
int ulapi_exit(void)
{
! /* does nothing, for now */
! return ULAPI_SUCCESS;
}
!
! int ulapi_shmem_new( int key, unsigned int size,
! ulapi_shmem_handle *shmemptr )
{
! ulapi_shmem_handle shmem;
! /* validate shmemptr */
! if ( shmemptr == NULL )
! return ULAPI_INVAL;
!
! /* alloc space for shmem structure */
! shmem = malloc( sizeof(struct ulapi_shmem) );
! if ( shmem == NULL )
! return ULAPI_NOMEM;
!
! /* now get shared memory block from OS */
! shmem->mem = rtai_malloc(key, size);
! if ( shmem->mem == NULL ) {
! free ( shmem );
! return ULAPI_NOMEM;
! }
!
! /* label as a valid shmem structure */
! shmem->magic = SHMEM_MAGIC;
! /* fill in the other fields */
! shmem->size = size;
! shmem->key = key;
!
! /* return handle to the caller */
! *shmemptr = shmem;
! return ULAPI_SUCCESS;
}
!
! int ulapi_shmem_getptr ( ulapi_shmem_handle shmem, void **ptr )
{
! /* validate shmem handle */
! if ( shmem == NULL )
! return ULAPI_BADH;
! if ( shmem->magic != SHMEM_MAGIC )
! return ULAPI_BADH;
!
! /* pass memory address back to caller */
! *ptr = shmem->mem;
! return ULAPI_SUCCESS;
}
!
! int ulapi_shmem_delete( ulapi_shmem_handle shmem )
{
! /* validate shmem handle */
! if ( shmem == NULL )
! return ULAPI_BADH;
! if ( shmem->magic != SHMEM_MAGIC )
! return ULAPI_BADH;
!
! /* free the shared memory */
! rtai_free( shmem->key, shmem->mem );
!
! /* free the shmem structure */
! shmem->magic = 0;
! free ( shmem );
! return ULAPI_SUCCESS;
! }
!
! int ulapi_fifo_new( int key, unsigned long int size, char mode,
! ulapi_fifo_handle *fifoptr )
! {
! ulapi_fifo_handle fifo;
! int retval, flags;
! enum { DEVSTR_LEN = 256 };
! char devstr[DEVSTR_LEN];
!
! /* validate fifoptr */
! if ( fifoptr == NULL )
! return ULAPI_INVAL;
!
! /* alloc space for fifo structure */
! fifo = malloc( sizeof(struct ulapi_fifo) );
! if ( fifo == NULL )
! return ULAPI_NOMEM;
+ /* determine system name for fifo */
sprintf(devstr, "/dev/rtf%d", key);
! /* determine mode for fifo */
! if ( mode == 'R' )
! flags = O_RDONLY;
! else if ( mode == 'W' )
! flags = O_WRONLY;
! else
! return ULAPI_INVAL;
!
! /* open the fifo */
! retval = open( devstr, flags );
! if ( retval < 0 ) {
! /* open failed */
! free ( fifo );
! return ULAPI_NOTFND;
! }
!
! /* label as a valid fifo structure */
! fifo->magic = FIFO_MAGIC;
! /* fill in the rest of the struct */
! fifo->key = key;
! fifo->fd = retval;
! fifo->mode = flags;
!
! /* return handle to the caller */
! *fifoptr = fifo;
! return ULAPI_SUCCESS;
}
!
! int ulapi_fifo_delete( ulapi_fifo_handle fifo )
{
! /* validate fifo handle */
! if ( fifo == NULL )
! return ULAPI_BADH;
! if ( fifo->magic != FIFO_MAGIC )
! return ULAPI_BADH;
!
! /* close the fifo */
! if ( close( fifo->fd ) < 0 )
! return ULAPI_NOTFND;
!
! /* free the fifo structure */
! fifo->magic = 0;
! free ( fifo );
! return ULAPI_SUCCESS;
!
}
! int ulapi_fifo_read( ulapi_fifo_handle fifo,
! char *buf, unsigned long int size)
{
! int retval;
!
! /* validate fifo handle */
! if ( fifo == NULL )
! return ULAPI_BADH;
! if ( fifo->magic != FIFO_MAGIC )
! return ULAPI_BADH;
! if ( fifo->mode != O_RDONLY )
! return ULAPI_UNSUP;
!
! /* get whatever data is available */
! retval = read( fifo->fd, buf, size );
! if ( retval < 0 )
! return ULAPI_FAIL;
! return retval;
!
}
! int ulapi_fifo_write( ulapi_fifo_handle fifo,
! char *buf, unsigned long int size)
{
! int retval;
!
! /* validate fifo handle */
! if ( fifo == NULL )
! return ULAPI_BADH;
! if ( fifo->magic != FIFO_MAGIC )
! return ULAPI_BADH;
! if ( fifo->mode != O_WRONLY )
! return ULAPI_UNSUP;
!
! /* get whatever data is available */
! retval = write( fifo->fd, buf, size );
! if ( retval < 0 )
! return ULAPI_FAIL;
! return retval;
}
+
Index: rtapi.h
===================================================================
RCS file: /cvsroot/emc/rtapi/src/rtapi/rtapi.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -C2 -d -r1.4 -r1.5
*** rtapi.h 19 Jul 2003 02:17:41 -0000 1.4
--- rtapi.h 19 Jul 2003 07:17:22 -0000 1.5
***************
*** 11,19 ****
#define RTAPI_PERM -5 /* permission denied */
#define RTAPI_BUSY -6 /* resource is busy or locked */
! #define RTAPI_EMPTY -7 /* buffer or fifo empty */
! #define RTAPI_FULL -8 /* buffer or fifo full */
! #define RTAPI_STATE -9 /* object state inappropriate, example:
! calling init() after already inited,
! or pausing an already paused task */
--- 11,17 ----
#define RTAPI_PERM -5 /* permission denied */
#define RTAPI_BUSY -6 /* resource is busy or locked */
! #define RTAPI_NOTFND -7 /* object not found */
! #define RTAPI_FAIL -8 /* operation failed */
!
Index: sim_rtapi.c
===================================================================
RCS file: /cvsroot/emc/rtapi/src/rtapi/sim_rtapi.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -d -r1.2 -r1.3
*** sim_rtapi.c 15 Jul 2003 11:42:48 -0000 1.2
--- sim_rtapi.c 19 Jul 2003 07:17:22 -0000 1.3
***************
*** 15,21 ****
#include "rtapi.h" /* these decls */
int rtapi_prio_highest(void)
{
! return 1;
}
--- 15,52 ----
#include "rtapi.h" /* these decls */
+
+ /* These structs hold data associated with objects like tasks, etc. */
+ /* Task handles are pointers to these structs. */
+
+ struct rtapi_task {
+ int magic; /* to check for valid handle */
+ pthread_t id; /* OS specific task identifier */
+ int arg; /* argument for task function */
+ void (*taskcode)( int ); /* pointer to task function */
+ };
+
+ struct rtapi_shmem {
+ int magic; /* to check for valid handle */
+ int key; /* key to shared memory area */
+ int id; /* OS identifier for shmem */
+ unsigned long int size; /* size of shared memory area */
+ void *mem; /* pointer to the memory */
+ };
+
+ #define TASK_MAGIC 21979 /* random numbers used as signatures */
+ #define SHMEM_MAGIC 25453
+
+ #define MAX_TASKS 64
+
+ /* data for all tasks */
+ static struct rtapi_task task_array[MAX_TASKS];
+
+
+ /* Priority functions. SIM uses 0 as the highest priority, as the
+ number increases, the actual priority of the task decreases. */
+
int rtapi_prio_highest(void)
{
! return 0;
}
***************
*** 27,33 ****
int rtapi_prio_next_higher(int prio)
{
! if (prio == rtapi_prio_highest())
! return prio;
return prio - 1;
}
--- 58,68 ----
int rtapi_prio_next_higher(int prio)
{
! /* return a valid priority for out of range arg */
! if (prio <= rtapi_prio_highest())
! return rtapi_prio_highest();
! if (prio > rtapi_prio_lowest())
! return rtapi_prio_lowest();
+ /* return next higher priority for in-range arg */
return prio - 1;
}
***************
*** 35,110 ****
int rtapi_prio_next_lower(int prio)
{
! if (prio == rtapi_prio_lowest())
! return prio;
!
return prio + 1;
}
int rtapi_init(void)
{
! return 0;
}
int rtapi_exit(void)
{
! return 0;
}
int rtapi_clock_set_period(unsigned long int nsecs)
{
! return 0;
}
! int rtapi_self_set_period(unsigned long int period_nsec)
{
! return 0;
}
! void *rtapi_task_new(void)
{
! return malloc(sizeof(pthread_t));
}
! int rtapi_task_delete(void *task)
{
! free(task);
! return 0;
}
! int
! rtapi_task_start(void *task,
! void *taskcode,
! int prio,
! unsigned long int stacksize,
! unsigned long int period_nsec, unsigned char uses_fp)
{
pthread_attr_t attr;
struct sched_param sched_param;
! pthread_attr_init(&attr);
sched_param.sched_priority = prio;
! pthread_attr_setschedparam(&attr, &sched_param);
! pthread_create((pthread_t *) task, &attr, taskcode, 0);
! pthread_setschedparam(*((pthread_t *) task), SCHED_FIFO, &sched_param);
! return 0;
}
! int rtapi_task_stop(void *task)
{
! return pthread_cancel(*((pthread_t *) task));
}
! int rtapi_task_pause(void *task)
{
! return 0;
}
! int rtapi_task_resume(void *task)
{
! return 0;
}
int rtapi_wait(void)
{
--- 70,274 ----
int rtapi_prio_next_lower(int prio)
{
! /* return a valid priority for out of range arg */
! if (prio >= rtapi_prio_lowest())
! return rtapi_prio_lowest();
! if (prio < rtapi_prio_highest())
! return rtapi_prio_highest();
! /* return next lower priority for in-range arg */
return prio + 1;
}
+
int rtapi_init(void)
{
! int n;
! /* clear the task array - if magic doesn't contain the magic
! number, that means that array entry is empty */
! for ( n = 0 ; n < MAX_TASKS ; n++ )
! task_array[n].magic = 0;
!
! return RTAPI_SUCCESS;
}
+
int rtapi_exit(void)
{
! return RTAPI_SUCCESS;
}
+
int rtapi_clock_set_period(unsigned long int nsecs)
{
! return RTAPI_SUCCESS;
}
!
! int rtapi_task_new( rtapi_task_handle *taskptr )
{
! int n;
! rtapi_task_handle task;
!
! /* validate taskptr */
! if ( taskptr == NULL )
! return RTAPI_INVAL;
!
! /* find an empty entry in the task array */
! /* FIXME - this is not 100% thread safe. If another thread
! calls this function after the first thread breaks out of
! the loop but before it sets the magic number, two tasks
! might wind up assigned to the same structure. Need an
! atomic test and set for the magic number. Not tonight! */
! n = 0;
! while ( ( n < MAX_TASKS ) &&
! ( task_array[n].magic == TASK_MAGIC ) )
! n++;
! if ( n == MAX_TASKS )
! return RTAPI_NOMEM;
! task = &(task_array[n]);
!
! /* label as a valid task structure */
! /* FIXME - end of non-threadsafe window */
! task->magic = TASK_MAGIC;
!
! /* and return handle to the caller */
! *taskptr = task;
!
! return RTAPI_SUCCESS;
}
!
! int rtapi_task_delete( rtapi_task_handle task )
{
! /* validate task handle */
! if ( task == NULL )
! return RTAPI_BADH;
! if ( task->magic != TASK_MAGIC )
! return RTAPI_BADH;
!
! /* mark the task struct as available */
! task->magic = 0;
! return 0;
}
!
! /* we define taskcode as taking an int and returning void. */
! /* pthread wants it to take a void pointer and return a void pointer */
! /* we solve this with a wrapper function that meets pthread's needs */
!
! static void *wrapper ( void *arg )
{
! rtapi_task_handle task;
! /* use the argument to point to the task data */
! task = arg;
! /* call the task function with the task argument */
! (task->taskcode)( task->arg );
! /* done */
! return NULL;
}
!
! int rtapi_task_start( rtapi_task_handle task,
! void (*taskcode)( int ),
! int arg, int prio,
! unsigned long int stacksize,
! unsigned long int period_nsec,
! unsigned char uses_fp )
{
+ int retval;
pthread_attr_t attr;
struct sched_param sched_param;
! /* validate task handle */
! if ( task == NULL )
! return RTAPI_BADH;
! if ( task->magic != TASK_MAGIC )
! return RTAPI_BADH;
!
! /* check requested priority */
! if ( ( prio < rtapi_prio_highest() ) ||
! ( prio > rtapi_prio_lowest() ) )
! return RTAPI_INVAL;
!
! /* get default thread attributes */
! pthread_attr_init( &attr );
!
! /* set priority */
sched_param.sched_priority = prio;
! pthread_attr_setschedparam( &attr, &sched_param );
! /* create the thread - use the wrapper function, pass it a pointer
! to the task structure so it can call the actual task function */
! retval = pthread_create( &(task->id), &attr, wrapper, (void *)task );
! if ( retval != 0 )
! return RTAPI_NOMEM;
! retval = pthread_setschedparam( task->id, SCHED_FIFO, &sched_param);
! if ( retval != 0 )
! /* need to be root to set SCHED_FIFO */
! return RTAPI_PERM;
! return RTAPI_SUCCESS;
}
!
! int rtapi_task_stop( rtapi_task_handle task )
{
! int retval;
!
! /* validate task handle */
! if ( task == NULL )
! return RTAPI_BADH;
! if ( task->magic != TASK_MAGIC )
! return RTAPI_BADH;
!
! retval = pthread_cancel( task->id );
! if ( retval != 0 )
! return RTAPI_FAIL;
! return RTAPI_SUCCESS;
}
! int rtapi_task_pause( rtapi_task_handle task )
{
!
! /* validate task handle */
! if ( task == NULL )
! return RTAPI_BADH;
! if ( task->magic != TASK_MAGIC )
! return RTAPI_BADH;
!
! /* FIXME - Fred originally had this function return success.
! I changed it to return Not Supported. Is that right? */
! return RTAPI_UNSUP;
}
! int rtapi_task_resume( rtapi_task_handle task )
{
!
! /* validate task handle */
! if ( task == NULL )
! return RTAPI_BADH;
! if ( task->magic != TASK_MAGIC )
! return RTAPI_BADH;
!
! /* FIXME - Fred originally had this function return success.
! I changed it to return Not Supported. Is that right? */
! return RTAPI_UNSUP;
}
+
+ int rtapi_task_set_period( rtapi_task_handle task,
+ unsigned long int period_nsec )
+ {
+ /* validate task handle */
+ if ( task == NULL )
+ return RTAPI_BADH;
+ if ( task->magic != TASK_MAGIC )
+ return RTAPI_BADH;
+
+ /* FIXME - Fred originally had this function return success.
+ I changed it to return Not Supported. Is that right? */
+ return RTAPI_UNSUP;
+ }
+
+
int rtapi_wait(void)
{
***************
*** 112,143 ****
usleep(1);
pthread_testcancel();
}
! int rtapi_alloc_shmem(int key, unsigned int size, int *id, void **ptr)
{
! *id = shmget((key_t) key, (int) size, IPC_CREAT | 0666);
! *ptr = shmat(*id, 0, 0);
! if (0 != *ptr) {
! return 0;
}
! return -1;
}
! int rtapi_free_shmem(int key, unsigned int size, int id, const void *ptr)
{
! struct shmid_ds d;
! int r1, r2;
! r1 = shmdt(ptr);
! /* FIXME - according to the man page for shmctl() on my system, id is
! the first arg, cmd is the second. Is this different on different
! kernel/lib versions, or just wrong here? */
! r2 = shmctl(IPC_RMID, id, &d);
! return (r1 || r2 ? -1 : 0);
}
void rtapi_print(const char *fmt, ...)
{
--- 276,394 ----
usleep(1);
pthread_testcancel();
+ return RTAPI_SUCCESS;
}
!
! int rtapi_task_get_handle( rtapi_task_handle *taskptr )
{
! int n;
! pthread_t task_id;
! /* validate taskptr */
! if ( taskptr == NULL )
! return RTAPI_INVAL;
!
! /* ask OS for task id */
! task_id = pthread_self();
!
! /* search task array for a matching entry */
! n = 0;
! while ( n < MAX_TASKS ) {
! if ( ( task_array[n].magic == TASK_MAGIC ) &&
! ( task_array[n].id == task_id ) ) {
! /* found it */
! *taskptr = &(task_array[n]);
! return RTAPI_SUCCESS;
! }
! n++;
}
+ return RTAPI_FAIL;
+ }
!
! int rtapi_shmem_new( int key, unsigned int size,
! rtapi_shmem_handle *shmemptr )
! {
! rtapi_shmem_handle shmem;
!
! /* validate shmemptr */
! if ( shmemptr == NULL )
! return RTAPI_INVAL;
!
! /* alloc space for shmem structure */
! shmem = malloc( sizeof(struct rtapi_shmem) );
! if ( shmem == NULL )
! return RTAPI_NOMEM;
!
! /* now get shared memory block from OS */
! shmem->id = shmget( (key_t) key, (int) size, IPC_CREAT | 0666 );
! if ( shmem->id == -1 ) {
! free ( shmem );
! return RTAPI_NOMEM;
! }
! /* and map it into process space */
! shmem->mem = shmat( shmem->id, 0, 0);
! if ( (int)(shmem->mem) == -1 ) {
! free ( shmem );
! return RTAPI_NOMEM;
! }
!
! /* label as a valid shmem structure */
! shmem->magic = SHMEM_MAGIC;
! /* fill in the other fields */
! shmem->size = size;
! shmem->key = key;
!
! /* return handle to the caller */
! *shmemptr = shmem;
! return RTAPI_SUCCESS;
}
!
! int rtapi_shmem_getptr ( rtapi_shmem_handle shmem, void **ptr )
{
! /* validate shmem handle */
! if ( shmem == NULL )
! return RTAPI_BADH;
! if ( shmem->magic != SHMEM_MAGIC )
! return RTAPI_BADH;
! /* pass memory address back to caller */
! *ptr = shmem->mem;
! return RTAPI_SUCCESS;
! }
!
! int rtapi_shmem_delete( rtapi_shmem_handle shmem )
! {
! struct shmid_ds d;
! int r1, r2;
!
! /* validate shmem handle */
! if ( shmem == NULL )
! return RTAPI_BADH;
! if ( shmem->magic != SHMEM_MAGIC )
! return RTAPI_BADH;
!
! /* unmap the shared memory */
! r1 = shmdt( shmem->mem );
!
! /* destroy the shared memory */
! r2 = shmctl( shmem->id, IPC_RMID, &d );
! /* FIXME - Fred had the first two arguments reversed. I changed
! them to match the shmctl man page on my machine. Since his way
! worked, maybe there is difference between different libs, or
! maybe my man page is just wrong. */
!
! /* free the shmem structure */
! shmem->magic = 0;
! free ( shmem );
!
! if ( ( r1 != 0 ) || ( r2 != 0 ) )
! return RTAPI_FAIL;
! return RTAPI_SUCCESS;
}
+
void rtapi_print(const char *fmt, ...)
{
***************
*** 160,173 ****
/*
! no support for simulated interrupts
*/
int rtapi_assign_interrupt_handler(unsigned int irq, void (*handler) (void))
{
! return 0;
}
int rtapi_free_interrupt_handler(unsigned int irq)
{
! return 0;
}
--- 411,491 ----
/*
! FIXME - no support for simulated interrupts
*/
int rtapi_assign_interrupt_handler(unsigned int irq, void (*handler) (void))
{
! return RTAPI_UNSUP;
}
int rtapi_free_interrupt_handler(unsigned int irq)
{
! return RTAPI_UNSUP;
! }
!
! int rtapi_enable_interrupt( unsigned int irq )
! {
! return RTAPI_UNSUP;
}
+
+ int rtapi_disable_interrupt( unsigned int irq )
+ {
+ return RTAPI_UNSUP;
+ }
+
+
+ /* FIXME - no support for semaphores */
+
+ int rtapi_sem_new( rtapi_sem_handle *semptr )
+ {
+ return RTAPI_UNSUP;
+ }
+
+ int rtapi_sem_delete( rtapi_sem_handle sem )
+ {
+ return RTAPI_UNSUP;
+ }
+
+ int rtapi_sem_give( rtapi_sem_handle sem )
+ {
+ return RTAPI_UNSUP;
+ }
+
+ int rtapi_sem_take( rtapi_sem_handle sem )
+ {
+ return RTAPI_UNSUP;
+ }
+
+ int rtapi_sem_try( rtapi_sem_handle sem )
+ {
+ return RTAPI_UNSUP;
+ }
+
+
+ /* FIXME - no support for fifos */
+
+ int rtapi_fifo_new( int key, unsigned long int size,
+ rtapi_fifo_handle *fifoptr )
+ {
+ return RTAPI_UNSUP;
+ }
+
+ int rtapi_fifo_delete( rtapi_fifo_handle fifo )
+ {
+ return RTAPI_UNSUP;
+ }
+
+ int rtapi_fifo_read( rtapi_fifo_handle fifo,
+ char *buf, unsigned long int size)
+ {
+ return RTAPI_UNSUP;
+ }
+
+ int rtapi_fifo_write( rtapi_fifo_handle fifo,
+ char *buf, unsigned long int size)
+ {
+ return RTAPI_UNSUP;
+ }
+
+
+
Index: sim_ulapi.c
===================================================================
RCS file: /cvsroot/emc/rtapi/src/rtapi/sim_ulapi.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -C2 -d -r1.1.1.1 -r1.2
*** sim_ulapi.c 8 Jul 2003 15:54:38 -0000 1.1.1.1
--- sim_ulapi.c 19 Jul 2003 07:17:22 -0000 1.2
***************
*** 5,42 ****
*/
#include <sys/ipc.h> /* IPC_* */
#include <sys/shm.h> /* shmget() */
#include "ulapi.h"
int ulapi_init(void)
{
! return 0;
}
int ulapi_exit(void)
{
! return 0;
}
! int ulapi_alloc_shmem(int key, unsigned int size, int *id, void **ptr)
{
! *id = shmget((key_t) key, (int) size, IPC_CREAT | 0666);
! *ptr = shmat(*id, 0, 0);
! if (0 != *ptr) {
! return 0;
}
! return -1;
}
! int ulapi_free_shmem(int key, unsigned int size, int id, const void *ptr)
{
! struct shmid_ds d;
! int r1, r2;
! r1 = shmdt(ptr);
! r2 = shmctl(IPC_RMID, id, &d);
! return (r1 || r2 ? -1 : 0);
}
--- 5,150 ----
*/
+ #include <stddef.h> /* NULL */
#include <sys/ipc.h> /* IPC_* */
#include <sys/shm.h> /* shmget() */
+ #include <malloc.h> /* malloc(), free() */
#include "ulapi.h"
+ /* These structs hold data associated with objects like tasks, etc. */
+ /* Task handles are pointers to these structs. */
+
+ struct ulapi_shmem {
+ int magic; /* to check for valid handle */
+ int key; /* key to shared memory area */
+ int id; /* OS identifier for shmem */
+ unsigned long int size; /* size of shared memory area */
+ void *mem; /* pointer to the memory */
+ };
+
+
+ #define SHMEM_MAGIC 25453 /* random numbers used as signatures */
+
+
int ulapi_init(void)
{
! /* does nothing, for now */
! return ULAPI_SUCCESS;
}
+
int ulapi_exit(void)
{
! /* does nothing, for now */
! return ULAPI_SUCCESS;
}
!
! int ulapi_shmem_new( int key, unsigned int size,
! ulapi_shmem_handle *shmemptr )
{
! ulapi_shmem_handle shmem;
! /* validate shmemptr */
! if ( shmemptr == NULL )
! return ULAPI_INVAL;
!
! /* alloc space for shmem structure */
! shmem = malloc( sizeof(struct ulapi_shmem) );
! if ( shmem == NULL )
! return ULAPI_NOMEM;
!
! /* now get shared memory block from OS */
! shmem->id = shmget( (key_t) key, (int) size, IPC_CREAT | 0666 );
! if ( shmem->id == -1 ) {
! free ( shmem );
! return ULAPI_NOMEM;
! }
! /* and map it into process space */
! shmem->mem = shmat( shmem->id, 0, 0);
! if ( (int)(shmem->mem) == -1 ) {
! free ( shmem );
! return ULAPI_NOMEM;
}
! /* label as a valid shmem structure */
! shmem->magic = SHMEM_MAGIC;
! /* fill in the other fields */
! shmem->size = size;
! shmem->key = key;
!
! /* return handle to the caller */
! *shmemptr = shmem;
! return ULAPI_SUCCESS;
}
!
! int ulapi_shmem_getptr ( ulapi_shmem_handle shmem, void **ptr )
{
! /* validate shmem handle */
! if ( shmem == NULL )
! return ULAPI_BADH;
! if ( shmem->magic != SHMEM_MAGIC )
! return ULAPI_BADH;
! /* pass memory address back to caller */
! *ptr = shmem->mem;
! return ULAPI_SUCCESS;
! }
!
! int ulapi_shmem_delete( ulapi_shmem_handle shmem )
! {
! struct shmid_ds d;
! int r1, r2;
!
! /* validate shmem handle */
! if ( shmem == NULL )
! return ULAPI_BADH;
! if ( shmem->magic != SHMEM_MAGIC )
! return ULAPI_BADH;
!
! /* unmap the shared memory */
! r1 = shmdt( shmem->mem );
!
! /* destroy the shared memory */
! r2 = shmctl( shmem->id, IPC_RMID, &d );
! /* FIXME - Fred had the first two arguments reversed. I changed
! them to match the shmctl man page on my machine. Since his way
! worked, maybe there is difference between different libs, or
! maybe my man page is just wrong. */
!
! /* free the shmem structure */
! shmem->magic = 0;
! free ( shmem );
!
! if ( ( r1 != 0 ) || ( r2 != 0 ) )
! return ULAPI_FAIL;
! return ULAPI_SUCCESS;
! }
!
!
! /* FIXME - no support for fifos */
!
! int ulapi_fifo_new( int key, unsigned long int size, char mode,
! ulapi_fifo_handle *fifoptr )
! {
! return ULAPI_UNSUP;
! }
!
! int ulapi_fifo_delete( ulapi_fifo_handle fifo )
! {
! return ULAPI_UNSUP;
}
+
+ int ulapi_fifo_read( ulapi_fifo_handle fifo,
+ char *buf, unsigned long int size)
+ {
+ return ULAPI_UNSUP;
+ }
+
+ int ulapi_fifo_write( ulapi_fifo_handle fifo,
+ char *buf, unsigned long int size)
+ {
+ return ULAPI_UNSUP;
+ }
+
Index: ulapi.h
===================================================================
RCS file: /cvsroot/emc/rtapi/src/rtapi/ulapi.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -d -r1.3 -r1.4
*** ulapi.h 19 Jul 2003 02:17:41 -0000 1.3
--- ulapi.h 19 Jul 2003 07:17:22 -0000 1.4
***************
*** 3,7 ****
! /** Error Codes: These error codes may be returned by UTAPI functions. */
#define ULAPI_SUCCESS 0 /* no error */
--- 3,7 ----
! /** These status codes are returned by many ULAPI functions. */
#define ULAPI_SUCCESS 0 /* no error */
***************
*** 9,17 ****
#define ULAPI_BADH -2 /* bad task, shmem, sem, or fifo handle */
#define ULAPI_INVAL -3 /* invalid argument*/
- #define ULAPI_BUSY -4 /* resource is busy or locked */
#define ULAPI_NOMEM -5 /* not enough memory */
#define ULAPI_PERM -6 /* permission denied */
! #define ULAPI_EMPTY -7 /* buffer or fifo empty */
! #define ULAPI_FULL -8 /* buffer or fifo full */
--- 9,17 ----
#define ULAPI_BADH -2 /* bad task, shmem, sem, or fifo handle */
#define ULAPI_INVAL -3 /* invalid argument*/
#define ULAPI_NOMEM -5 /* not enough memory */
#define ULAPI_PERM -6 /* permission denied */
! #define ULAPI_BUSY -4 /* resource is busy or locked */
! #define ULAPI_NOTFND -7 /* object not found */
! #define ULAPI_FAIL -8 /* operation failed */
***************
*** 20,30 ****
typedef struct ulapi_shmem *ulapi_shmem_handle;
- typedef struct ulapi_sem *ulapi_sem_handle;
typedef struct ulapi_fifo *ulapi_fifo_handle;
/** 'ulapi_init() sets up the user space interface to the RTAPI. It *
! * must be called before calling any ulapi functions. Returns *
! * ULAPI_SUCCESS, ULAPI_BUSY, ULAPI_NOMEM, or ULAPI_PERM. */
extern int ulapi_init( void );
--- 20,29 ----
typedef struct ulapi_shmem *ulapi_shmem_handle;
typedef struct ulapi_fifo *ulapi_fifo_handle;
/** 'ulapi_init() sets up the user space interface to the RTAPI. It *
! * must be called before calling any ulapi functions. Returns a statis *
! * code, as defined above. */
extern int ulapi_init( void );
***************
*** 32,37 ****
/** 'ulapi_exit()' shuts down and cleans up the user space interface *
! * to the RTAPI. It must be called before program exit. Returns *
! * ULAPI_SUCCESS. */
extern int ulapi_exit( void );
--- 31,36 ----
/** 'ulapi_exit()' shuts down and cleans up the user space interface *
! * to the RTAPI. It must be called before program exit. Returns a *
! * status code. */
extern int ulapi_exit( void );
***************
*** 42,64 ****
* memory must use the same key. The block will be at least 'size' *
* bytes, and may be rounded up. Allocating many small blocks may be *
! * very wasteful. On success, '*mbuf' becomes a shared memory handle, *
! * which points to internal data for the shared memory and is used for *
! * subsequent calls dealing with the block. Returns ULAPI_SUCCESS, *
! * ULAPI_INVAL, or ULAPI_NOMEM. */
extern int ulapi_shmem_new( int key, unsigned int size,
! ulapi_shmem_handle *mbuf );
/** 'ulapi_shmem_getptr()' sets '*ptr' to point to the start of the *
! * shared memory block 'mbuf'. Returns ULAPI_SUCCESS or ULAPI_BADH. */
! extern int ulapi_shmem_getptr ( ulapi_shmem_handle mbuf, void **ptr );
/** 'ulapi_shmem_delete()' frees the shared memory block 'mbuf'. *
! * Returns ULAPI_SUCCESS or ULAPI_BADH. */
! extern int ulapi_shmem_delete( ulapi_shmem_handle mbuf );
--- 41,63 ----
* memory must use the same key. The block will be at least 'size' *
* bytes, and may be rounded up. Allocating many small blocks may be *
! * very wasteful. On success, '*shmemptr' becomes a shared memory *
! * handle, which points to internal data for the shared memory and is *
! * used for subsequent calls dealing with the block. Returns a status *
! * code. */
extern int ulapi_shmem_new( int key, unsigned int size,
! ulapi_shmem_handle *shmemptr );
/** 'ulapi_shmem_getptr()' sets '*ptr' to point to the start of the *
! * shared memory block 'mbuf'. Returns a status code. */
! extern int ulapi_shmem_getptr ( ulapi_shmem_handle shmem, void **ptr );
/** 'ulapi_shmem_delete()' frees the shared memory block 'mbuf'. *
! * Returns a status code. */
! extern int ulapi_shmem_delete( ulapi_shmem_handle shmem );
***************
*** 69,101 ****
* On success, '*fifo' becomes a fifo handle, which points to internal *
* data for the fifo and is used for subsequent calls dealing with it. *
! * Returns ULAPI_SUCCESS, ULAPI_INVAL, ULAPI_NOMEM, or ULAPI_PERM. */
extern int ulapi_fifo_new( int key, unsigned long int size, char mode,
! ulapi_fifo_handle *fifo );
/** 'ulapi_fifo_delete()' is the counterpart to 'ulapi_fifo_new()'. *
! * It destroys the fifo 'fifo'. Returns ULAPI_SUCCESS or ULAPI_BADH. */
extern int ulapi_fifo_delete( ulapi_fifo_handle fifo );
! /** 'rtapi_fifo_read()' reads data from 'fifo'. 'buf' is a buffer for *
* the data, and 'size' is the maximum number of bytes to read. *
! * Returns the number of bytes actually read, or RTAPI_BADH. Does not *
! * block. If 'size' bytes are not available, it will read whatever is *
! * available, and return that count (which could be zero). */
! extern int rtapi_fifo_read( rtapi_fifo_handle fifo,
! char *buf, unsigned long int size);
! /** 'rtapi_fifo_write()' writes data to 'fifo'. Up to 'size' bytes are *
* taken from the buffer at 'buf'. Returns the count of bytes actually *
! * written, or RTAPI_BADH. Does not block. If 'size' bytes of space *
! * are not available in the fifo, rtapi_fifo_write() will write as many *
* bytes as it can and return that count (which may be zero). */
! extern int rtapi_fifo_write(int fd, char *buf, unsigned long int size);
--- 68,104 ----
* On success, '*fifo' becomes a fifo handle, which points to internal *
* data for the fifo and is used for subsequent calls dealing with it. *
! * Returns a status code. */
extern int ulapi_fifo_new( int key, unsigned long int size, char mode,
! ulapi_fifo_handle *fifoptr );
/** 'ulapi_fifo_delete()' is the counterpart to 'ulapi_fifo_new()'. *
! * It destroys the fifo 'fifo'. Returns a status code. */
extern int ulapi_fifo_delete( ulapi_fifo_handle fifo );
! /** 'ulapi_fifo_read()' reads data from 'fifo'. 'buf' is a buffer for *
* the data, and 'size' is the maximum number of bytes to read. *
! * Returns the number of bytes actually read, or RTAPI_BADH. If there *
! * is no data in the fifo, it blocks until data appears (or a signal *
! * occurs). If 'size' bytes are not available, it will read whatever *
! * is available, and return that count (will be greater than zero). If *
! * interrupted by a signal or some other error occurs, will return *
! * ULAPI_FAIL. */
! extern int ulapi_fifo_read( ulapi_fifo_handle fifo,
! char *buf, unsigned long int size);
! /** 'ulapi_fifo_write()' writes data to 'fifo'. Up to 'size' bytes are *
* taken from the buffer at 'buf'. Returns the count of bytes actually *
! * written, or RTAPI_BADH, or ULAPI_FAIL. If 'size' bytes of space are *
! * not available in the fifo, rtapi_fifo_write() will write as many *
* bytes as it can and return that count (which may be zero). */
! extern int ulapi_fifo_write( ulapi_fifo_handle fifo,
! char *buf, unsigned long int size);
|