|
From: <jmk...@us...> - 2003-07-19 02:17:44
|
Update of /cvsroot/emc/rtapi/src/rtapi
In directory sc8-pr-cvs1:/tmp/cvs-serv9258/src/rtapi
Modified Files:
Makefile localdefs.h rtai_rtapi.c rtapi.h ulapi.h
Log Message:
revised the API definition and made coresponding changes to rtai_rtapi.c
Index: Makefile
===================================================================
RCS file: /cvsroot/emc/rtapi/src/rtapi/Makefile,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -d -r1.2 -r1.3
*** Makefile 9 Jul 2003 17:51:26 -0000 1.2
--- Makefile 19 Jul 2003 02:17:41 -0000 1.3
***************
*** 77,91 ****
# DO NOT DELETE
! /proj/foundation/home/proctor/rtapi/lib/rtai_rtapi.o: rtapi.h
! /proj/foundation/home/proctor/rtapi/lib/rtai_ulapi.o: ulapi.h
! /proj/foundation/home/proctor/rtapi/lib/rtl_rtapi.o: rtapi.h
! /proj/foundation/home/proctor/rtapi/lib/rtl_ulapi.o: ulapi.h
! /proj/foundation/home/proctor/rtapi/lib/sim_rtapi.o: rtapi.h
! /proj/foundation/home/proctor/rtapi/lib/sim_ulapi.o: ulapi.h
! /proj/foundation/home/proctor/rtapi/rtlib/rtai_rtapi.o: rtapi.h
! /proj/foundation/home/proctor/rtapi/rtlib/rtai_ulapi.o: ulapi.h
! /proj/foundation/home/proctor/rtapi/rtlib/rtl_rtapi.o: rtapi.h
! /proj/foundation/home/proctor/rtapi/rtlib/rtl_ulapi.o: ulapi.h
! /proj/foundation/home/proctor/rtapi/rtlib/sim_rtapi.o: rtapi.h
! /proj/foundation/home/proctor/rtapi/rtlib/sim_ulapi.o: ulapi.h
--- 77,91 ----
# DO NOT DELETE
! /home/John/emcdev/rtapi/lib/rtai_rtapi.o: rtapi.h
! /home/John/emcdev/rtapi/lib/rtai_ulapi.o: ulapi.h
! /home/John/emcdev/rtapi/lib/rtl_rtapi.o: rtapi.h
! /home/John/emcdev/rtapi/lib/rtl_ulapi.o: ulapi.h
! /home/John/emcdev/rtapi/lib/sim_rtapi.o: rtapi.h
! /home/John/emcdev/rtapi/lib/sim_ulapi.o: ulapi.h
! /home/John/emcdev/rtapi/rtlib/rtai_rtapi.o: rtapi.h
! /home/John/emcdev/rtapi/rtlib/rtai_ulapi.o: ulapi.h
! /home/John/emcdev/rtapi/rtlib/rtl_rtapi.o: rtapi.h
! /home/John/emcdev/rtapi/rtlib/rtl_ulapi.o: ulapi.h
! /home/John/emcdev/rtapi/rtlib/sim_rtapi.o: rtapi.h
! /home/John/emcdev/rtapi/rtlib/sim_ulapi.o: ulapi.h
Index: localdefs.h
===================================================================
RCS file: /cvsroot/emc/rtapi/src/rtapi/localdefs.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -d -r1.2 -r1.3
*** localdefs.h 19 Jul 2003 01:32:47 -0000 1.2
--- localdefs.h 19 Jul 2003 02:17:41 -0000 1.3
***************
*** 2,6 ****
#define LOCALDEFS_H
! /* automatically generated by config script on Fri Jul 18 21:25:01 EDT 2003 */
#define LOCAL_MHZ 233.866
--- 2,6 ----
#define LOCALDEFS_H
! /* automatically generated by config script on Fri Jul 18 22:11:03 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.2
retrieving revision 1.3
diff -C2 -d -r1.2 -r1.3
*** rtai_rtapi.c 11 Jul 2003 02:52:43 -0000 1.2
--- rtai_rtapi.c 19 Jul 2003 02:17:41 -0000 1.3
***************
*** 8,12 ****
#include <linux/module.h>
#include <linux/kernel.h>
! #include <linux/malloc.h> /* kmalloc(), kfree(), GFP_USER */
#include <rtai.h>
#include <rtai_sched.h>
--- 8,15 ----
#include <linux/module.h>
#include <linux/kernel.h>
! /* FIXME - on my system malloc.h is deprecated, use slab.h instead */
! /* #include <linux/malloc.h> */ /* kmalloc(), kfree(), GFP_USER */
! #include <linux/slab.h>
!
#include <rtai.h>
#include <rtai_sched.h>
***************
*** 27,34 ****
--- 30,70 ----
#include "rtapi.h" /* these decls */
+
+ struct rtapi_task {
+ int magic; /* to check for valid handle */
+ RT_TASK ostask; /* OS specific task data */
+ };
+
+ struct rtapi_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 rtapi_sem {
+ int magic; /* to check for valid handle */
+ SEM ossem; /* OS specific semaphore data */
+ };
+
+ struct rtapi_fifo {
+ int magic; /* to check for valid handle */
+ int fd; /* file descripter for fifo */
+ unsigned long int size; /* size of fifo area */
+ };
+
+ #define TASK_MAGIC 21979 /* random numbers used as signatures */
+ #define SHMEM_MAGIC 25453
+ #define SEM_MAGIC 27594
+ #define FIFO_MAGIC 10293
+
+
/* declare vsprintf() explicitly instead of including all of <stdio.h>,
since we don't need all of it and it may cause problems */
extern int vsprintf(char *s, const char *format, va_list arg);
+ /* Priority functions. RTAI uses 0 as the highest priority, as the
+ number increases, the actual priority of the task decreases. */
+
int rtapi_prio_highest(void)
{
***************
*** 43,49 ****
int rtapi_prio_next_higher(int prio)
{
! if (prio == rtapi_prio_highest())
! return prio;
return prio - 1;
}
--- 79,89 ----
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;
}
***************
*** 51,70 ****
int rtapi_prio_next_lower(int prio)
{
! if (prio == rtapi_prio_lowest())
! return prio;
!
return prio + 1;
}
int rtapi_init(void)
{
rt_linux_use_fpu(1);
!
! return 0;
}
int rtapi_exit(void)
{
! return 0;
}
--- 91,113 ----
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)
{
rt_linux_use_fpu(1);
! return RTAPI_SUCCESS;
}
int rtapi_exit(void)
{
! return RTAPI_SUCCESS;
}
***************
*** 73,165 ****
rt_set_periodic_mode();
start_rt_timer(nano2count((RTIME) nsecs));
! return 0;
}
! void *rtapi_task_new(void)
{
! return kmalloc(sizeof(RT_TASK), GFP_USER);
}
! int rtapi_task_delete(void *task)
{
! if (0 == task) {
! return -1;
! }
! kfree(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)
{
int retval;
! if (0 != rt_task_init((RT_TASK *) task, taskcode, 0, stacksize, prio, 1, 0))
! return -1;
! if (0 != rt_task_use_fpu((RT_TASK *) task, (int) uses_fp))
! return -1;
! if (period_nsec > 0) {
! retval = rt_task_make_periodic((RT_TASK *) task, rt_get_time(),
! nano2count((RTIME) period_nsec));
! } else {
! retval = rt_task_resume((RT_TASK *) task);
}
! return retval;
}
! int rtapi_task_stop(void *task)
{
! return rt_task_delete((RT_TASK *) task);
}
! int rtapi_task_pause(void *task)
{
! return rt_task_suspend((RT_TASK *) task);
}
! int rtapi_task_resume(void *task)
{
! return rt_task_resume((RT_TASK *) task);
}
! int rtapi_task_set_period(void *task, unsigned long int period_nsec)
{
! return rt_task_make_periodic((RT_TASK *) task, rt_get_time(),
nano2count((RTIME) period_nsec));
}
! int rtapi_self_set_period(unsigned long int period_nsec)
{
! return rt_task_make_periodic(rt_whoami(), rt_get_time(),
! nano2count((RTIME) period_nsec));
}
! int rtapi_wait(void)
{
! rt_task_wait_period();
! return 0;
}
! int rtapi_alloc_shmem(int key, unsigned int size, int *id, void **ptr)
{
! *ptr = rtai_kmalloc(key, size);
! /* leave id alone; we don't use it */
! if (0 != *ptr) {
! return 0;
}
! return -1;
}
! int rtapi_free_shmem(int key, unsigned int size, int id, const void *ptr)
{
! rtai_kfree(key);
! return 0;
}
--- 116,348 ----
rt_set_periodic_mode();
start_rt_timer(nano2count((RTIME) nsecs));
! return RTAPI_SUCCESS;
}
! int rtapi_task_new( rtapi_task_handle *taskptr )
{
! rtapi_task_handle task;
!
! /* validate taskptr */
! if ( taskptr == NULL )
! return RTAPI_INVAL;
!
! /* alloc space for task structure */
! task = kmalloc(sizeof(struct rtapi_task), GFP_USER);
! if ( task == NULL )
! return RTAPI_NOMEM;
!
! /* label as a valid task structure */
! 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;
! /* free the task struct */
! task->magic = 0;
! kfree( task );
return 0;
}
!
! 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;
! /* validate task handle */
! if ( task == NULL )
! return RTAPI_BADH;
! if ( task->magic != TASK_MAGIC )
! return RTAPI_BADH;
!
! /* call OS to initialize the task */
! retval = rt_task_init( &(task->ostask), taskcode, arg,
! stacksize, prio, (int) uses_fp, 0);
! if ( retval != 0 ) {
! if ( retval == EINVAL )
! /* task already in use */
! return RTAPI_BUSY;
! if ( retval == ENOMEM )
! /* not enough space for stack */
! return RTAPI_NOMEM;
! /* unknown error */
! return RTAPI_INVAL;
}
! if ( period_nsec > 0) {
! /* start the task in periodic mode */
! retval = rt_task_make_periodic( &(task->ostask), rt_get_time(),
! nano2count((RTIME) period_nsec));
! if ( retval != 0 )
! return RTAPI_INVAL;
! }
! else {
! /* start task in free-running mode */
! retval = rt_task_resume( &(task->ostask) );
! if ( retval != 0 )
! return RTAPI_INVAL;
! }
!
! return RTAPI_SUCCESS;
}
! int rtapi_task_stop( rtapi_task_handle task )
{
! /* validate task handle */
! if ( task == NULL )
! return RTAPI_BADH;
! if ( task->magic != TASK_MAGIC )
! return RTAPI_BADH;
!
! return rt_task_delete( &(task->ostask) );
}
!
! 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;
!
! return rt_task_suspend( &(task->ostask) );
}
! 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;
!
! 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 )
! return RTAPI_BADH;
! if ( task->magic != TASK_MAGIC )
! return RTAPI_BADH;
!
! return rt_task_make_periodic( &(task->ostask), rt_get_time(),
nano2count((RTIME) period_nsec));
}
! int rtapi_wait( void )
{
! rt_task_wait_period();
! return RTAPI_SUCCESS;
}
!
! int rtapi_task_get_handle( rtapi_task_handle *taskptr )
{
! int offset;
! void *ptr;
!
! /* validate taskptr */
! if ( taskptr == NULL )
! return RTAPI_INVAL;
!
! /* ask OS for pointer to its data for the current task */
! ptr = rt_whoami();
! if ( ptr == NULL )
! /* called from outside a task? */
! return RTAPI_STATE;
!
! /* ptr points to OS data, somewhere inside rtapi
! struct, so calculate offset from start of struct */
! offset = (int)&(((struct rtapi_task *)0)->ostask);
!
! /* subtract offset to get start of struct */
! ptr -= offset;
!
! *taskptr = (rtapi_task_handle)ptr;
! return RTAPI_SUCCESS;
}
!
! 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 = 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 );
! 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 )
! {
! /* validate shmem handle */
! if ( shmem == NULL )
! return RTAPI_BADH;
! if ( shmem->magic != SHMEM_MAGIC )
! return RTAPI_BADH;
!
! /* free the shared memory */
! rtai_kfree( shmem->key );
!
! /* free the shmem structure */
! shmem->magic = 0;
! kfree ( shmem );
! return RTAPI_SUCCESS;
}
***************
*** 171,175 ****
/* the call to vsprintf() will put arbitrarily many characters into
'buffer', and we can't easily check how many beforehand. This may
! cause a buffer overflow. The correct way to do this is as in
Exercise 7-3 in K&R's _C Language, 2nd Ed_ book */
va_start(args, fmt);
--- 354,358 ----
/* the call to vsprintf() will put arbitrarily many characters into
'buffer', and we can't easily check how many beforehand. This may
! cause a buffer overflow. The correct way to do this is as in
Exercise 7-3 in K&R's _C Language, 2nd Ed_ book */
va_start(args, fmt);
***************
*** 232,289 ****
}
! void *rtapi_sem_new(void)
{
! void *retval;
! retval = kmalloc(sizeof(SEM), GFP_USER);
! rt_sem_init(retval, 0);
! return retval;
}
! int rtapi_sem_delete(void *sem)
{
! if (0 == sem) {
! return -1;
! }
! kfree(sem);
! return 0;
}
! int rtapi_sem_give(void *sem)
{
! rt_sem_signal(sem);
! return 0;
}
! int rtapi_sem_take(void *sem)
{
! rt_sem_wait(sem);
! return 0;
}
! int rtapi_fifo_new(int key, int *fd, unsigned long int size)
{
! *fd = key;
! rtf_destroy(key);
! return rtf_create(key, size);
}
! int rtapi_fifo_delete(int key, int fd, unsigned long int size)
{
! return rtf_destroy(key);
}
! int rtapi_fifo_write(int fd, char *buf, unsigned long int size)
{
! return rtf_put(fd, buf, size);
}
! int rtapi_fifo_read(int fd, char *buf, unsigned long int size)
{
! return rtf_get(fd, buf, size);
}
--- 415,591 ----
}
!
!
! int rtapi_sem_new( rtapi_sem_handle *semptr )
{
! rtapi_sem_handle sem;
! /* validate semptr */
! if ( semptr == NULL )
! return RTAPI_INVAL;
! /* alloc space for sem structure */
! sem = kmalloc(sizeof(struct rtapi_sem), GFP_USER);
! if ( sem == NULL )
! return RTAPI_NOMEM;
! /* ask the OS to initialize the semaphore */
! rt_sem_init( &(sem->ossem), 0 );
!
! /* label as a valid sem structure */
! sem->magic = SEM_MAGIC;
!
! /* return handle to the caller */
! *semptr = sem;
! return RTAPI_SUCCESS;
}
!
! int rtapi_sem_delete( rtapi_sem_handle sem )
{
! /* validate sem handle */
! if ( sem == NULL )
! return RTAPI_BADH;
! if ( sem->magic != SEM_MAGIC )
! return RTAPI_BADH;
! /* ask the OS to shut down the semaphore */
! rt_sem_delete ( &(sem->ossem) );
!
! /* free the sem structure */
! sem->magic = 0;
! kfree ( sem );
! return RTAPI_SUCCESS;
}
! int rtapi_sem_give( rtapi_sem_handle sem )
{
! /* validate sem handle */
! if ( sem == NULL )
! return RTAPI_BADH;
! if ( sem->magic != SEM_MAGIC )
! return RTAPI_BADH;
! /* give up the semaphore */
! rt_sem_signal( &(sem->ossem) );
! return RTAPI_SUCCESS;
}
! int rtapi_sem_take( rtapi_sem_handle sem )
{
! /* validate sem handle */
! if ( sem == NULL )
! return RTAPI_BADH;
! if ( sem->magic != SEM_MAGIC )
! return RTAPI_BADH;
! /* get the semaphore */
! rt_sem_wait( &(sem->ossem) );
! return RTAPI_SUCCESS;
}
! extern int rtapi_sem_try( rtapi_sem_handle sem )
{
! /* validate sem handle */
! if ( sem == NULL )
! return RTAPI_BADH;
! if ( sem->magic != SEM_MAGIC )
! return RTAPI_BADH;
!
! /* try the semaphore */
! if ( rt_sem_wait_if ( &(sem->ossem) ) <= 0 )
! return RTAPI_BUSY;
! return RTAPI_SUCCESS;
}
!
! extern int rtapi_fifo_new( int key, unsigned long int size,
! rtapi_fifo_handle *fifoptr )
{
! rtapi_fifo_handle fifo;
! int retval;
!
! /* validate fifoptr */
! if ( fifoptr == NULL )
! return RTAPI_INVAL;
!
! /* alloc space for fifo structure */
! fifo = kmalloc(sizeof(struct rtapi_fifo), GFP_USER);
! if ( fifo == NULL )
! return RTAPI_NOMEM;
!
! /* I'm not sure why Fred calls destroy before create */
! rtf_destroy ( key );
!
! /* create the fifo */
! retval = rtf_create ( key, size );
! if ( retval != size ) {
! kfree ( fifo );
! if ( retval == ENOMEM )
! /* couldn't allocate memory */
! return RTAPI_NOMEM;
! return RTAPI_INVAL;
! }
!
! /* label as a valid fifo structure */
! fifo->magic = FIFO_MAGIC;
! /* fill in the rest of the struct */
! fifo->fd = key;
!
! /* return handle to the caller */
! *fifoptr = fifo;
! return RTAPI_SUCCESS;
}
! int rtapi_fifo_delete( rtapi_fifo_handle fifo )
{
! /* validate fifo handle */
! if ( fifo == NULL )
! return RTAPI_BADH;
! if ( fifo->magic != FIFO_MAGIC )
! return RTAPI_BADH;
!
! /* call the OS to destroy the fifo */
! rtf_destroy( fifo->fd );
!
! /* free the fifo structure */
! fifo->magic = 0;
! kfree ( fifo );
! return RTAPI_SUCCESS;
}
! int rtapi_fifo_read( rtapi_fifo_handle fifo,
! char *buf, unsigned long int size)
{
! int retval;
!
! /* validate fifo handle */
! if ( fifo == NULL )
! return RTAPI_BADH;
! if ( fifo->magic != FIFO_MAGIC )
! return RTAPI_BADH;
!
! /* get whatever data is available */
! retval = rtf_get( fifo->fd, buf, size );
! if ( retval < 0 )
! return RTAPI_INVAL;
! return retval;
! }
!
! int rtapi_fifo_write( rtapi_fifo_handle fifo,
! char *buf, unsigned long int size)
! {
! int retval;
!
! /* validate fifo handle */
! if ( fifo == NULL )
! return RTAPI_BADH;
! if ( fifo->magic != FIFO_MAGIC )
! return RTAPI_BADH;
!
! /* get whatever data is available */
! retval = rtf_put( fifo->fd, buf, size );
! if ( retval < 0 )
! return RTAPI_INVAL;
! return retval;
}
Index: rtapi.h
===================================================================
RCS file: /cvsroot/emc/rtapi/src/rtapi/rtapi.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -d -r1.3 -r1.4
*** rtapi.h 15 Jul 2003 11:42:48 -0000 1.3
--- rtapi.h 19 Jul 2003 02:17:41 -0000 1.4
***************
*** 2,5 ****
--- 2,42 ----
#define RTAPI_H
+ /** These status codes are returned by many RTAPI functions. */
+
+ #define RTAPI_SUCCESS 0 /* call successfull */
+ #define RTAPI_UNSUP -1 /* function not supported */
+ #define RTAPI_BADH -2 /* bad task, shmem, sem, or fifo handle */
+ #define RTAPI_INVAL -3 /* invalid argument*/
+ #define RTAPI_NOMEM -4 /* not enough memory */
+ #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 */
+
+
+ /** Typedefs for object handles. The structs to which these handles *
+ * refer are private, and may vary from one RTOS to another. *
+ * In fact, don't even count on handles always being pointers. */
+
+ typedef struct rtapi_task *rtapi_task_handle;
+ typedef struct rtapi_shmem *rtapi_shmem_handle;
+ typedef struct rtapi_sem *rtapi_sem_handle;
+ typedef struct rtapi_fifo *rtapi_fifo_handle;
+
+
+ /** 'rtapi_init() sets up the RTAPI. It must be called before calling *
+ * any rtapi functions. Returns a status code, as defined above. */
+
+ extern int rtapi_init( void );
+
+
+ /** '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 rtapi_exit( void );
***************
*** 10,27 ****
* two methods: *
* *
! * Set your lowest priority task to 'rtapi_prio_lowest()', and for *
* each task of the next lowest priority, set their priorities to *
* 'rtapi_prio_next_higher(previous)'. *
* *
! * Or, *
! * *
! * Set your highest priority task to 'rtapi_prio_highest()', and for *
* each task of the next highest priority, set their priorities to *
* 'rtapi_prio_next_lower(previous)'. */
! extern int rtapi_prio_highest(void);
! extern int rtapi_prio_lowest(void);
! extern int rtapi_prio_next_higher(int prio);
! extern int rtapi_prio_next_lower(int prio);
--- 47,62 ----
* two methods: *
* *
! * 1) Set your lowest priority task to 'rtapi_prio_lowest()', and for *
* each task of the next lowest priority, set their priorities to *
* 'rtapi_prio_next_higher(previous)'. *
* *
! * 2) Set your highest priority task to 'rtapi_prio_highest()', and for *
* each task of the next highest priority, set their priorities to *
* 'rtapi_prio_next_lower(previous)'. */
! extern int rtapi_prio_highest( void );
! extern int rtapi_prio_lowest( void );
! extern int rtapi_prio_next_higher( int prio );
! extern int rtapi_prio_next_lower( int prio );
***************
*** 34,64 ****
* multiple realtime tasks in multiple kernel modules. Calling this *
* function after realtime tasks have been started may disrupt the *
! * tasks. Returns 0 on success, an RTOS specific error code on fail. */
extern int rtapi_clock_set_period(unsigned long int nsecs);
! /** 'rtapi_task_new()' is the first step in creating a task. Returns *
! * a pointer to internal rtapi and rtos data that describes the task. *
! * All other calls that relate to the task use this pointer as a task *
! * handle. Normally called from module init code, may block. Returns *
! * a non-zero task handle on success, zero on failure. */
!
! /* FIXME - I want to replace the current declaration with:
!
! typedef struct rtapi_task *rtapi_task_handle;
!
! rtapi_task_handle rtapi_task_new(void);
!
! The typedef permits typechecking on the task handle, while still
! hiding the internal contents of the structure. All functions that
! currently take or return a void pointer to a task would instead
! take or return a rtapi_task_handle. The actual code generated is
! the same, but this form allows compile time type checking.
!
! I will implement the change if/when we reach a concensus that it
! is a good thing. John M Kasunich - 7/10/03 */
! extern void *rtapi_task_new(void);
--- 69,84 ----
* multiple realtime tasks in multiple kernel modules. Calling this *
* function after realtime tasks have been started may disrupt the *
! * tasks. Returns a status code. */
extern int rtapi_clock_set_period(unsigned long int nsecs);
! /** 'rtapi_task_new()' is the first step in creating a task. Allocs *
! * and initializes internal rtapi and rtos data related to the task. *
! * Returns a status code. On success, '*taskptr' becomes a handle *
! * which points to the internal task data. This handle is used for all *
! * subsequent calls that need to act on the task. */
! extern int rtapi_task_new( rtapi_task_handle *taskptr );
***************
*** 66,89 ****
* It frees memory associated with 'task', and does any other cleanup *
* needed. If the task has been started, you must stop it before *
! * deleting it, or bad things might happen. Returns zero on success, *
! * an RTOS dependent error code on failure. Call from within module *
! * cleanup code or any _other_ task - a task should not attempt to *
! * delete itself! */
!
! /* FIXME change to:
! int rtapi_task_delete( rtapi_task_handle task );
! */
! extern int rtapi_task_delete(void *task);
/** 'rtapi_task_start()' does the bulk of the work needed to create *
* and run a realtime task. 'task' is a task handle from a call to *
! * rtapi_task_new(). 'taskcode' is the name of a function containing *
! * the task code. 'prio' is the priority, as determined by one of the *
! * priority functions above. 'stacksize' is the amount of stack to be *
! * reserved for the task - be generous, hardware interrupts use the *
! * same stack. 'period_nsec' is the task period in nanoseconds, which *
! * will be rounded to the nearest multiple of the global clock period. *
* If non-zero, 'uses_fp' tells the OS that the task uses floating *
* point so it can save the FPU registers on a task switch. Failing *
--- 86,106 ----
* It frees memory associated with 'task', and does any other cleanup *
* needed. If the task has been started, you must stop it before *
! * deleting it, or bad things might happen. Returns a status code. *
! * Call from within module cleanup code or any other task. A task *
! * should not attempt to delete itself! */
! extern int rtapi_task_delete( rtapi_task_handle task );
/** 'rtapi_task_start()' does the bulk of the work needed to create *
* and run a realtime task. 'task' is a task handle from a call to *
! * rtapi_task_new(). 'taskcode' is the name of a function taking one *
! * int and returning void, which contains the task code. 'arg' will be *
! * passed to 'taskcode' when the task is invoked. 'prio' is the *
! * priority, as determined by one of the priority functions above. *
! * 'stacksize' is the amount of stack to be reserved for the task - be *
! * generous, hardware interrupts may use the same stack. 'period_nsec' *
! * is the task period in nanoseconds, which will be rounded to the *
! * nearest multiple of the global clock period. *
* If non-zero, 'uses_fp' tells the OS that the task uses floating *
* point so it can save the FPU registers on a task switch. Failing *
***************
*** 91,97 ****
* tasks should set 'uses_fp' to 1. If a task definitely does not use *
* floating point, setting 'uses_fp' to zero saves a few microseconds *
! * on each task switch. Returns zero on success, an RTOS dependent *
! * error code on failure. call from module init code (preferred) or *
! * within a realtime task. May block. */
/* FIXME - Fred, you have code in the implementations of this function
--- 108,113 ----
* tasks should set 'uses_fp' to 1. If a task definitely does not use *
* floating point, setting 'uses_fp' to zero saves a few microseconds *
! * per task switch. Returns a status code. Call from module init code *
! * (preferred) or within a realtime task. May block. */
/* FIXME - Fred, you have code in the implementations of this function
***************
*** 101,216 ****
*/
! /* FIXME - change to:
! extern 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);
!
! This declares 'taskcode' as a 'pointer to function taking one int and
! returning void', which lets the compiler make sure it is really a
! valid function. Adding 'arg' lets the task init code pass a parameter
! to the realtime task code, which can be cast to a pointer to any kind
! of data structure that might be needed. Can be useful for letting the
! task code know where shared memory is located.
! */
!
! extern int rtapi_task_start(void *task, void *taskcode, int prio,
! unsigned long int stacksize,
! unsigned long int period_nsec,
! unsigned char uses_fp);
/** 'rtapi_task_stop()' is the counterpart to 'rtapi_task_start()'. *
* Permanently stops 'task', and prepares it to be deleted. Returns *
! * zero on success, and an RTOS dependent error code on failure. Call *
! * from within module cleanup code or any _other_ task - a task should *
! * not attempt to stop itself! */
!
! /* FIXME - change to:
! extern int rtapi_task_stop(rtapi_task_handle task );
! */
! extern int rtapi_task_stop(void *task);
/** 'rtapi_task_pause() causes 'task' to temporarily stop execution. *
* It will resume when 'rtapi_task_resume()' is called with the same *
! * task handle. Returns zero on success, an RTOS dependent error code *
! * on failure. A task can pause itself, but obviously cannot resume *
! * itself. Note: depending on the RTOS, multiple 'pauses' may or may *
! * not be canceled by a single 'resume'. To be safe, don't pause a *
! * task more than once. */
! /* FIXME - we could modify the wrapper function to keep track of pauses
! and resumes, and consistently provide one behavior or the other, instead
! of leaving it RTOS dependent.
! */
- /* FIXME - change to:
- extern int rtapi_task_pause(rtapi_task_handle task);
- extern int rtapi_task_resume(rtapi_task_handle task);
- */
! extern int rtapi_task_pause(void *task);
! extern int rtapi_task_resume(void *task);
! /** 'rtapi_task_set_period()' and 'rtapi_self_set_period()' are used *
! * to change the period of a task. The new period is 'period_nsec', *
! * rounded to the nearest integer multiple of the global period as set *
! * by 'rtapi_clock_set_period()'. Returns zero on success, an RTOS *
! * dependent error code on failure. */
- /* FIXME - consider deleting the 'self' version of this function, and
- instead provide a function that returns the handle of the current task,
- like this:
- rtapi_task_handle rtapi_self(void);
! That's a more generic way to allow a task to call any rtapi function
! on itself.
! */
! /* FIXME - replace with:
- extern int rtapi_task_set_period(rtapi_task_handle task,
- unsigned long int period_nsec);
- */
! extern int rtapi_task_set_period(void *task, unsigned long int period_nsec);
! extern int rtapi_self_set_period(unsigned long int period_nsec);
- /** 'rtapi_wait()' suspends execution of the current task until the *
- * next period. At the beginning of the next period, execution will *
- * resume immediately after the call to 'rtapi_wait()', instead of at *
- * beginning of the 'taskcode' function. Returns zero on success, and *
- * an RTOS dependent errorcode on failure. Call only from a task. */
! extern int rtapi_wait(void);
- /** 'rtapi_alloc_shmem()' allocates and maps a block of shared memory. *
- * 'key' identifies the memory block, all modules wishing to access *
- * the same 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. 'id' is a pointer to an int that may be used *
- * by rtapi_alloc_shmem() for an internal identifier - retain the value *
- * in 'id' until you call rtapi_free_shmem(). 'ptr' is a pointer to *
- * a void pointer, which will be set to point to the allocated memory. *
- * Returns zero on success, and an RTOS dependent errorcode on failure. */
! extern int rtapi_alloc_shmem(int key, unsigned int size,
! int *id, void **ptr);
- /** 'rtapi_free_shmem()' frees a block of memory that was allocated by *
- * rtapi_alloc_shmem(). 'key', 'size', 'id', and 'ptr' must match the *
- * values from the call that allocated the block. Returns zero on *
- * success, and an RTOS dependent errorcode on failure. */
! extern int rtapi_free_shmem(int key, unsigned int size,
! int id, const void *ptr);
--- 117,194 ----
*/
! extern 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 );
/** 'rtapi_task_stop()' is the counterpart to 'rtapi_task_start()'. *
* Permanently stops 'task', and prepares it to be deleted. Returns *
! * a status code. Call from within module cleanup code or any other *
! * task - a task should not attempt to stop itself! */
! extern int rtapi_task_stop( rtapi_task_handle task );
/** 'rtapi_task_pause() causes 'task' to temporarily stop execution. *
* It will resume when 'rtapi_task_resume()' is called with the same *
! * task handle. A task can pause itself, but obviously cannot resume *
! * itself. Returns a status code. */
! extern int rtapi_task_pause( rtapi_task_handle task );
! extern int rtapi_task_resume( rtapi_task_handle task );
! /** 'rtapi_task_set_period()' sets the period of a task. The new *
! * period is 'period_nsec', rounded to the nearest integer multiple of *
! * the global period as set by 'rtapi_clock_set_period()'. Returns a *
! * status code. */
! extern int rtapi_task_set_period( rtapi_task_handle task,
! unsigned long int period_nsec );
! /** 'rtapi_wait()' suspends execution of the current task until the *
! * next period. At the beginning of the next period, execution will *
! * resume immediately after the call to 'rtapi_wait()', instead of at *
! * beginning of the 'taskcode' function. Call only from a task. *
! * Returns a status code. */
! extern int rtapi_wait( void );
! /** 'rtapi_task_get_handle()' sets '*taskptr' equal to the handle of */
! /* the current task. Call only from a task. Returns a status code. */
+ extern int rtapi_task_get_handle( rtapi_task_handle *taskptr );
! /** 'rtapi_shmem_new()' allocates a block of shared memory. 'key' *
! * identifies the memory block, all modules wishing to access the same *
! * 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 handle pointing *
! * to internal data for the shared memory and is used for subsequent *
! * calls dealing with the block. Remember that '*shmemptr' points to *
! * internal data, not the actual shared memory. To get a pointer to *
! * the shared memory, pass the handle to 'rtapi_shmem_getptr()'. *
! * Returns a status code. */
+ extern int rtapi_shmem_new( int key, unsigned int size,
+ rtapi_shmem_handle *shmemptr );
! /** 'rtapi_shmem_getptr()' sets '*ptr' to point to the start of the *
! * shared memory block 'mbuf'. Returns a status code. */
+ extern int rtapi_shmem_getptr ( rtapi_shmem_handle shmem, void **ptr );
! /** 'rtapi_shmem_delete()' frees the shared memory block 'mbuf'. *
! * Returns a status code. */
!
! extern int rtapi_shmem_delete( rtapi_shmem_handle shmem );
***************
*** 223,227 ****
* can take a fairly long time, depending on the format string and OS. */
! extern void rtapi_print(const char *fmt, ...);
--- 201,205 ----
* can take a fairly long time, depending on the format string and OS. */
! extern void rtapi_print( const char *fmt, ... );
***************
*** 229,239 ****
* Note: This function does nothing on the simulated RTOS. */
! extern void rtapi_outb(unsigned char byte, unsigned int port);
! /** 'rtapi_inb() gets a byte from 'port'. *
* Note: This function always returns zero on the simulated RTOS. */
! extern unsigned char rtapi_inb(unsigned int port);
--- 207,217 ----
* Note: This function does nothing on the simulated RTOS. */
! extern void rtapi_outb( unsigned char byte, unsigned int port );
! /** 'rtapi_inb() gets a byte from 'port'. Returns the byte. *
* Note: This function always returns zero on the simulated RTOS. */
! extern unsigned char rtapi_inb( unsigned int port );
***************
*** 241,251 ****
* a hardware interrupt. 'irq' is the interrupt number, and 'handler' *
* is a pointer to a function taking no arguements and returning void. *
! * 'handler will be called when the interrupt occurs. Returns zero on *
! * success, and an RTOS specific error code on failure. Note: The *
! * simulated RTOS always returns zero, but does nothing - it does not *
! * support interrupts. */
! extern int rtapi_assign_interrupt_handler(unsigned int irq,
! void (*handler) (void));
--- 219,227 ----
* a hardware interrupt. 'irq' is the interrupt number, and 'handler' *
* is a pointer to a function taking no arguements and returning void. *
! * 'handler will be called when the interrupt occurs. Returns a status *
! * code. Note: The simulated RTOS does not support interrupts. */
! extern int rtapi_assign_interrupt_handler( unsigned int irq,
! void (*handler) (void) );
***************
*** 254,389 ****
* is the interrupt number. Removing a realtime module without freeing *
* any handlers it has installed will almost certainly crash the box. *
! * Returns zero on success, an RTOS specific error code on failure. */
! extern int rtapi_free_interrupt_handler(unsigned int irq);
/** 'rtapi_enable_interrupt()' and 'rtapi_disable_interrupt()' are *
* are used to enable and disable interrupts, presumably ones that have *
! * handlers assigned to them. Returns 0 on success, an RTOS specific *
! * error code on failure. */
!
! extern int rtapi_enable_interrupt(unsigned int irq);
! extern int rtapi_disable_interrupt(unsigned int irq);
!
!
! /** 'rtapi_sem_new()' creates a realtime semaphore. Returns a pointer *
! * to RTAPI and RTOS specific data associated with the semaphore. All *
! * other semaphore functions use this pointer as a semaphore handle. *
! * Normally called from module init code, may block. Returns a non- *
! * zero semaphore handle on success, zero on failure. */
! /* FIXME - I want to treat semaphore handles like task handles:
- typedef struct rtapi_sem *rtapi_sem_handle;
! rtapi_sem_handle rtapi_sem_new(void);
! */
! extern void *rtapi_sem_new(void);
/** 'rtapi_sem_delete()' is the counterpart to 'rtapi_sem_new()'. It *
* destroys the semaphore 'sem'. Any tasks blocked on 'sem' will *
! * resume execution. Returns zero on success, an RTOS dependent error *
! * code on failure. */
!
! /* FIXME change to:
! int rtapi_sem_delete( rtapi_sem_handle sem );
! */
! extern int rtapi_sem_delete(void *sem);
/** 'rtapi_sem_give()' unlocks a semaphore. If a higher priority task *
* is blocked on the semaphore, the calling task will block and the *
! * higher priority task will begin to run. Returns zero on success, an *
! * RTOS dependent error code on failure. */
!
! /* FIXME change to:
! int rtapi_sem_give( rtapi_sem_handle sem );
! */
! extern int rtapi_sem_give(void *sem);
- /** 'rtapi_sem_take()' locks a semaphore. If the semaphore is *
- * unlocked it returns zero immediately. If the semaphore is locked, *
- * the calling task blocks until the semaphore is unlocked, then it *
- * returns zero. On an error, it returns an RTOS dependent error code. */
! /* FIXME change to:
! int rtapi_sem_take( rtapi_sem_handle sem );
! */
! extern int rtapi_sem_take(void *sem);
/** 'rtapi_sem_try()' does a non-blocking attempt to lock a semaphore. *
! * If the semaphore is unlocked, it returns zero. If the semaphore is *
! * locked it does not block, instead it returns EAGAIN, and the caller *
! * can decide how to deal with the situation. On an error, it returns *
! * an RTOS dependent error code. */
!
! /* FIXME this function was not in the original RTAPI. Both RTLinux and
! RTAI provide the neccessary primitives, and if there is no objection I
! will implement it. JMK 7/14/03
! int rtapi_sem_try( rtapi_sem_handle sem );
! */
/** 'rtapi_fifo_new()' creates a realtime fifo. 'key' identifies the *
* fifo, all modules wishing to access the same fifo must use the same *
! * key. 'size' is the size of the desired fifo. 'fd' is a pointer *
! * to an int used by rtapi_fifo_new() as a file descripter associated *
! * with the fifo - retain the value in 'fd' until you delete the fifo. *
! * Returns zero on success, and an RTOS dependent errorcode on failure. */
!
! extern int rtapi_fifo_new(int key, int *fd, unsigned long int size);
!
! /** "rtapi_fifo_delete()' deletes a fifo that was created by a call to *
! * rtapi_fifo_new(). 'key', 'fd', and 'size' must match the values *
! * from the call that created the fifo. On success, returns zero or a *
! * positive number that identifies the number of other modules still *
! * attached to the fifo. On error, returns an RTOS dependent errorcode *
! * that is negative. */
- /* FIXME - the return value above is based on RTAI. The RTLinux docs
- aren't clear about what the return value is, may be the same or maybe
- not. Should we change the implementation to always return zero on
- success, or is the RTAI style return value usefull? I will make the
- change unless there are objections. JMK 7/14/03 */
! extern int rtapi_fifo_delete(int key, int fd, unsigned long int size);
- /** 'rtapi_fifo_read()' reads data from a fifo. 'fd' is the fifo *
- * descripter returned when the fifo was created. 'buf' is a buffer *
- * for the data. 'size' is the maximum number of bytes to read. *
- * Returns the number of bytes read, or a negative error code on *
- * failure. 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_write(int fd, char *buf, unsigned long int size);
- /** 'rtapi_fifo_write()' writes data to a fifo. 'fd' is the descripter *
- * returned when the fifo was created. 'buf' is a buffer for the data. *
- * Returns the number of bytes written. If successfull, the return *
- * value will match 'size'. Does not block. If 'size' bytes of space *
- * are not available in the fifo, rtapi_fifo_write() will either do a *
- * partial write and return the number of bytes actually written, or *
- * fail and return a negative error code, depending on the RTOS. */
! /* FIXME - different actions when the fifo is full could cause problems.
! The second action can be modified to be compatible with the first - if
! there isn't enough room for 'size' bytes, return zero, to indicate zero
! bytes written. Any caller that can deal with the partial writes
! should also be able to handle partial writes that write nothing.
! I will implement this if there are no objections. JMK 7/14/03 */
! extern int rtapi_fifo_read(int fd, char *buf, unsigned long int size);
--- 230,320 ----
* is the interrupt number. Removing a realtime module without freeing *
* any handlers it has installed will almost certainly crash the box. *
! * Returns RTAPI_SUCCESS or RTAPI_INVAL. */
! extern int rtapi_free_interrupt_handler( unsigned int irq );
/** 'rtapi_enable_interrupt()' and 'rtapi_disable_interrupt()' are *
* are used to enable and disable interrupts, presumably ones that have *
! * handlers assigned to them. Returns a status code. */
! extern int rtapi_enable_interrupt( unsigned int irq );
! extern int rtapi_disable_interrupt( unsigned int irq );
! /** 'rtapi_sem_new()' creates a realtime semaphore. On success, *
! * '*semptr' becomes a semaphore handle, which points to internal data *
! * for the semaphore is used for subsequent calls dealing with it. *
! * Returns a status code. */
! extern int rtapi_sem_new( rtapi_sem_handle *semptr );
/** 'rtapi_sem_delete()' is the counterpart to 'rtapi_sem_new()'. It *
* destroys the semaphore 'sem'. Any tasks blocked on 'sem' will *
! * resume execution. Returns a status code. */
! extern int rtapi_sem_delete( rtapi_sem_handle sem );
/** 'rtapi_sem_give()' unlocks a semaphore. If a higher priority task *
* is blocked on the semaphore, the calling task will block and the *
! * higher priority task will begin to run. Returns a status code. */
! extern int rtapi_sem_give( rtapi_sem_handle sem );
! /** 'rtapi_sem_take()' locks a semaphore. Returns RTAPI_SUCCESS or *
! * RTAPI_BADH. If the semaphore is unlocked it returns RTAPI_SUCCESS *
! * immediately. If the semaphore is locked, the calling task blocks *
! * until the semaphore is unlocked, then it returns RTAPI_SUCCESS. */
! extern int rtapi_sem_take( rtapi_sem_handle sem );
/** 'rtapi_sem_try()' does a non-blocking attempt to lock a semaphore. *
! * Returns RTAPI_SUCCESS, RTAPI_BADH, or RTAPI_BUSY. If the semaphore *
! * is unlocked, it returns RTAPI_SUCCESS. If the semaphore is locked *
! * it does not block, instead it returns RTAPI_BUSY, and the caller can *
! * decide how to deal with the situation. */
! extern int rtapi_sem_try( rtapi_sem_handle sem );
/** 'rtapi_fifo_new()' creates a realtime fifo. 'key' identifies the *
* fifo, all modules wishing to access the same fifo must use the same *
! * key. 'size' is the depth of the fifo. On success, '*fifoptr' *
! * 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 rtapi_fifo_new( int key, unsigned long int size,
! rtapi_fifo_handle *fifoptr );
! /** 'rtapi_fifo_delete()' is the counterpart to 'rtapi_fifo_new()'. *
! * It destroys the fifo 'fifo'. Returns a status code. */
+ extern int rtapi_fifo_delete( rtapi_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( rtapi_fifo_handle fifo,
! char *buf, unsigned long int size);
Index: ulapi.h
===================================================================
RCS file: /cvsroot/emc/rtapi/src/rtapi/ulapi.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -d -r1.2 -r1.3
*** ulapi.h 15 Jul 2003 11:42:48 -0000 1.2
--- ulapi.h 19 Jul 2003 02:17:41 -0000 1.3
***************
*** 3,86 ****
/** 'ulapi_init() sets up the user space interface to the RTAPI. It *
! * must be called before calling any ulapi functions. Returns zero on *
! * success, and an RTOS specific error code on failure. */
- extern int ulapi_init(void);
/** 'ulapi_exit()' shuts down and cleans up the user space interface *
! * to the RTAPI. It must be called before program exit. Returns zero *
! * on success, and an RTOS specific error code on failure. */
! extern int ulapi_exit(void);
! /** 'ulapi_alloc_shmem()' allocates and maps a block of shared memory. *
! * 'key' identifies the memory block, all modules wishing to access *
! * the same 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. 'id' is a pointer to an int that may be used *
! * by ulapi_alloc_shmem() for an internal identifier - retain the value *
! * in 'id' until you call ulapi_free_shmem(). 'ptr' is a pointer to *
! * a void pointer, which will be set to point to the allocated memory. *
! * Returns zero on success, and an RTOS dependent errorcode on failure. */
! extern int ulapi_alloc_shmem(int key, unsigned int size,
! int *id, void **ptr);
! /** 'ulapi_free_shmem()' frees a block of memory that was allocated by *
! * ulapi_alloc_shmem(). 'key', 'size', 'id', and 'ptr' must match the *
! * values from the call that allocated the block. Returns zero on *
! * success, and an RTOS dependent errorcode on failure. */
! extern int ulapi_free_shmem(int key, unsigned int size,
! int id, const void *ptr);
! /** 'ulapi_fifo_new()' creates a realtime fifo. 'key' identifies the *
! * fifo, all modules wishing to access the same fifo must use the same *
! * key. 'size' is the size of the desired fifo. 'fd' is a pointer *
! * to an int used by ulapi_fifo_new() as a file descripter associated *
! * with the fifo - retain the value in 'fd' until you delete the fifo. *
! * Returns zero on success, and an RTOS dependent errorcode on failure. */
! /* FIXME - the current inplementations open the fifo using O_RDONLY.
! That means it can only be used with ulapi_fifo_read() to transfer
! data from kernel space (realtime tasks) to user space. Probably
! need to add a mode or data direction parameter to this function. */
- extern int ulapi_fifo_new(int key, int *fd, unsigned long int size);
! /** "ulapi_fifo_delete()' deletes a fifo that was created by a call to *
! * ulapi_fifo_new(). 'key', 'fd', and 'size' must match the values *
! * from the call that created the fifo. Returns zero on success, and *
! * an RTOS dependent errorcode on failure. */
- extern int ulapi_fifo_delete(int key, int fd, unsigned long int size);
! /** 'ulapi_fifo_read()' reads data from a fifo. 'fd' is the fifo *
! * descripter returned when the fifo was created. 'buf' is a buffer *
! * for the data. 'size' is the maximum number of bytes to read. *
! * Returns the number of bytes read, or a negative error code on *
! * failure. */
- /* FIXME - Blocking/nonblocking behavior depends on how the fifo
- was opened, which is not clear at this time. */
! extern int ulapi_fifo_read(int fd, char *buf, unsigned long int size);
- /** 'ulapi_fifo_write()' writes data to a fifo. 'fd' is the descripter *
- * returned when the fifo was created. 'buf' is a buffer for the data. *
- * Returns the number of bytes written. If successfull, the return *
- * value will match 'size'. */
! /* FIXME - Blocking/nonblocking behavior depends on how the fifo
! was opened, which is not clear at this time. */
! extern int ulapi_fifo_write(int fd, char *buf, unsigned long int size);
--- 3,101 ----
+ /** Error Codes: These error codes may be returned by UTAPI functions. */
+
+ #define ULAPI_SUCCESS 0 /* no error */
+ #define ULAPI_UNSUP -1 /* function not supported */
+ #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 */
+
+
+ /** Typedefs for object handles. The structs to which these handles *
+ * refer are private, and may vary from one RTOS to another. */
+
+ 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 );
/** '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 );
! /** 'ulapi_shmem_new()' allocates a block of shared memory. 'key' *
! * identifies the memory block, all modules wishing to access the same *
! * 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 );
+ /** 'ulapi_fifo_new()' opens a fifo for communication with realtime *
+ * code. 'key' identifies the fifo, all modules wishing to access the *
+ * same fifo must use the same key. 'size' is the size of the desired *
+ * fifo. 'mode' is either 'R' or 'W', for readable or writeable fifos. *
+ * 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);
|