Release 6.1.7
This commit is contained in:
362
utility/rtos_compatibility_layers/posix/readme_threadx_posix.txt
Normal file
362
utility/rtos_compatibility_layers/posix/readme_threadx_posix.txt
Normal file
@@ -0,0 +1,362 @@
|
||||
POSIX Compliancy Wrapper for Azure RTOS ThreadX
|
||||
|
||||
|
||||
|
||||
1.0 POSIX Compliancy Wrapper Overview
|
||||
|
||||
The POSIX Compliancy Wrapper supports many of the basic POSIX calls, with
|
||||
some limitations, and utilizes ThreadX<64> primitives underneath. This POSIX
|
||||
compatibility layer should have good performance since it utilizes internal
|
||||
ThreadX primitives and bypasses basic ThreadX error checking.
|
||||
|
||||
|
||||
1.1 POSIX Compliancy Wrapper Source
|
||||
|
||||
The Wrapper source code is designed for simplicity and is comprised of separate source
|
||||
files for most functions. Including the supplied pthread.h file will import
|
||||
all the necessary POSIX constants and subroutine prototypes.
|
||||
|
||||
|
||||
1.2 POSIX Compliancy Wrapper Documentation
|
||||
|
||||
This document itself serves as a POSIX Compliancy Wrapper User Guide by
|
||||
providing an overview of the porting process, including various caveats and
|
||||
pitfalls to watch out for. In addition, each covered POSIX call is documented,
|
||||
including information about supported/unsupported options, limitations, deviations,
|
||||
and suggestions on how to work-around any limitations.
|
||||
|
||||
|
||||
2.0 Installation
|
||||
|
||||
The POSIX Compliancy Wrapper is easily installed by adding the
|
||||
the posix library to your current application build. Make sure your application build
|
||||
references the same header files as the ones the posix library has been built with.
|
||||
The file pthread.h must be included in your application source where POSIX
|
||||
calls are required.
|
||||
Since the POSIX compliancy wrapper does not cover the complete standard, not all prototypes
|
||||
are provided. Most notably is the header file tx_px_time.h.
|
||||
|
||||
2.1 Initialization
|
||||
|
||||
The POSIX Compliancy Wrapper requires that a special initialization function is called
|
||||
prior to accessing any POSIX calls. The function to call and its prototype is:
|
||||
|
||||
VOID *posix_initialize(VOID * posix_memory);
|
||||
|
||||
This function is usually called from the application specific ThreadX
|
||||
initialization routine, tx_application_define(). The memory pointer supplied
|
||||
to posix_initialize must be a contiguouis reserved section of memory
|
||||
that has at least the following number of bytes:
|
||||
|
||||
|
||||
POSIX_SYSTEM_STACK_SIZE +
|
||||
TX_REGION0_SIZE_IN_BYTES + /* Region0 size */
|
||||
(WORK_QUEUE_DEPTH * WORK_REQ_SIZE) + /* system queue size */
|
||||
POSIX_HEAP_SIZE_IN_BYTES
|
||||
|
||||
|
||||
These equates are defined in tx_posix.h. The following additional equates
|
||||
define the number of POSIX objects supported by the POSIX Wrapper (default
|
||||
value is shown):
|
||||
|
||||
SEM_NSEMS_MAX 100 /* simultaneous POSIX semaphores */
|
||||
|
||||
SEM_NAME_MAX 10 /* maximum length of name of semaphore */
|
||||
|
||||
SEM_VALUE_MAX 100 /* max value of semaphore while initialization */
|
||||
|
||||
POSIX_MAX_QUEUES 32 /* maximum number of simultaneous POSIX
|
||||
message queues supported */
|
||||
|
||||
PATH_MAX 10 /* maximum length of name of a message queue */
|
||||
|
||||
PTHREAD_THREADS_MAX 256 /* define the maximum number of simultaneous
|
||||
POSIX Pthreads supported. */
|
||||
|
||||
POSIX_MAX_MUTEX 32 /* define the maximum number of simultaneous
|
||||
POSIX mutexes sported. */
|
||||
|
||||
|
||||
The function posix_initialize will return a pointer to the next free
|
||||
available memory location for the application.
|
||||
|
||||
|
||||
3.0 POSIX Calls
|
||||
|
||||
Once posix_initialize returns, POSIX calls can be made.
|
||||
The Threadx POSIX Compliancy Wrapper supports the following POSIX
|
||||
calls:
|
||||
|
||||
/***********************************************************************/
|
||||
/* CALLS RELATED TO POSIX MESSAGE QUEUE */
|
||||
/***********************************************************************/
|
||||
|
||||
INT mq_send(mqd_t mqdes, const char * msg_ptr,
|
||||
ssize_t msg_len,ULONG msg_prio );
|
||||
ssize_t mq_receive(mqd_t mqdes, VOID *pMsg, ssize_t msgLen,
|
||||
ULONG *pMsgPrio );
|
||||
INT mq_unlink(const char * mqName);
|
||||
INT mq_close(mqd_t mqdes);
|
||||
mqd_t mq_open(const CHAR * mqName, ULONG oflags,...);
|
||||
|
||||
|
||||
/***********************************************************************/
|
||||
/* CALLS RELATED TO POSIX SEMAPHORE */
|
||||
/***********************************************************************/
|
||||
|
||||
INT sem_close(sem_t * sem);
|
||||
INT sem_getvalue(sem_t * sem,ULONG * sval);
|
||||
sem_t *sem_open(const char * name, ULONG oflag, ...);
|
||||
INT sem_post(sem_t * sem);
|
||||
INT sem_trywait(sem_t * sem);
|
||||
INT sem_unlink(const char * name);
|
||||
INT sem_wait( sem_t * sem );
|
||||
INT sem_init(sem_t *sem , INT pshared, UINT value);
|
||||
INT sem_destroy(sem_t *sem);
|
||||
|
||||
/***********************************************************************/
|
||||
/* CALLS RELATED TO POSIX pthreads */
|
||||
/***********************************************************************/
|
||||
|
||||
INT sched_yield(VOID);
|
||||
INT pthread_create (pthread_t *thread,
|
||||
pthread_attr_t *attr,
|
||||
VOID *(*start_routine)(VOID*),VOID *arg);
|
||||
INT pthread_detach(pthread_t thread);
|
||||
INT pthread_join(pthread_t thread, VOID **value_ptr);
|
||||
INT pthread_equal(pthread_t thread1, pthread_t thread2);
|
||||
VOID pthread_exit(VOID *value_ptr);
|
||||
pthread_t pthread_self(VOID);
|
||||
INT pthread_attr_destroy(pthread_attr_t *attr);
|
||||
INT pthread_attr_getdetachstate( pthread_attr_t *attr,INT *detachstate);
|
||||
INT pthread_attr_setdetachstate(pthread_attr_t *attr,INT detachstate);
|
||||
INT pthread_attr_getinheritsched(pthread_attr_t *attr, INT *inheritsched);
|
||||
INT pthread_attr_setinheritsched(pthread_attr_t *attr, INT inheritsched);
|
||||
INT pthread_attr_getschedparam(pthread_attr_t *attr,struct sched_param *param);
|
||||
INT pthread_attr_setschedparam(pthread_attr_t *attr,struct sched_param *param);
|
||||
INT pthread_attr_getschedpolicy(pthread_attr_t *attr, INT *policy);
|
||||
INT pthread_attr_setschedpolicy(pthread_attr_t *attr, INT policy);
|
||||
INT pthread_attr_init(pthread_attr_t *attr);
|
||||
INT phread_attr_getstackaddr( pthread_attr_t *attr,VOID **stackaddr);
|
||||
INT phread_attr_setstackaddr(pthread_attr_t *attr,VOID **stackaddr);
|
||||
INT pthread_attr_getstacksize( pthread_attr_t *attr, ssize_t *stacksize);
|
||||
INT pthread_attr_setstacksize(pthread_attr_t *attr, ssize_t stacksize);
|
||||
INT phread_attr_getstack( pthread_attr_t *attr,VOID **stackaddr,
|
||||
ssize_t *stacksize);
|
||||
INT phread_attr_setstack( pthread_attr_t *attr,VOID *stackaddr,
|
||||
ssize_t stacksize);
|
||||
|
||||
INT pthread_mutexattr_gettype(pthread_mutexattr_t *attr, INT *type);
|
||||
INT pthread_mutexattr_settype(pthread_mutexattr_t *attr, INT type);
|
||||
INT pthread_mutexattr_destroy(pthread_mutexattr_t *attr);
|
||||
INT pthread_mutexattr_init(pthread_mutexattr_t *attr);
|
||||
INT pthread_mutex_destroy(pthread_mutex_t *mutex);
|
||||
INT pthread_mutex_init(pthread_mutex_t *mutex, pthread_mutexattr_t *attr);
|
||||
INT pthread_mutex_lock(pthread_mutex_t *mutex );
|
||||
INT pthread_mutex_unlock(pthread_mutex_t *mutex );
|
||||
INT pthread_mutex_trylock(pthread_mutex_t *mutex);
|
||||
INT pthread_mutexattr_getprotocol( pthread_mutexattr_t *attr, INT *protocol);
|
||||
INT pthread_mutexattr_setprotocol(pthread_mutexattr_t *attr, INT protocol);
|
||||
INT pthread_mutexattr_getpshared (pthread_mutexattr_t *attr, INT *pshared);
|
||||
INT pthread_mutexattr_setpshared (pthread_mutexattr_t *attr, INT pshared);
|
||||
INT pthread_mutex_timedlock(pthread_mutex_t *mutex, struct timespec *abs_timeout);
|
||||
INT pthread_setcancelstate (INT state, INT *oldstate);
|
||||
INT pthread_setcanceltype (INT type, INT *oldtype);
|
||||
INT pthread_cancel(pthread_t thread);
|
||||
VOID pthread_yield(VOID);
|
||||
VOID pthread_testcancel(VOID);
|
||||
INT pthread_getschedparam(pthread_t thread, INT *policy, struct sched_param *param);
|
||||
INT pthread_setschedparam(pthread_t thread, INT policy, const struct sched_param *param);
|
||||
|
||||
INT sched_get_priority_max(INT policy)
|
||||
INT sched_get_priority_min(INT policy)
|
||||
|
||||
INT pthread_once (pthread_once_t * once_control, VOID (*init_routine) (VOID))
|
||||
|
||||
INT pthread_kill(ULONG thread_id, int sig)
|
||||
INT pthread_sigmask(int how, const sigset_t *newmask, sigset_t *oldmask)
|
||||
|
||||
|
||||
/***********************************************************************/
|
||||
/* CALLS RELATED TO POSIX CONDITION VARIABLE */
|
||||
/***********************************************************************/
|
||||
|
||||
INT pthread_cond_destroy(pthread_cond_t *cond);
|
||||
INT pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *attr);
|
||||
INT pthread_cond_broadcast(pthread_cond_t *cond);
|
||||
INT pthread_cond_signal(pthread_cond_t *cond);
|
||||
INT pthread_cond_timedwait(pthread_cond_t *cond,pthread_mutex_t *mutex,
|
||||
struct timespec *abstime);
|
||||
INT pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
|
||||
|
||||
|
||||
/***********************************************************************/
|
||||
/* CALLS RELATED TO Timer */
|
||||
/***********************************************************************/
|
||||
|
||||
INT nanosleep(struct timespec *req, struct timespec *rem)
|
||||
INT sleep(ULONG seconds)
|
||||
INT clock_gettime(clockid_t t, struct timespec * tspec)
|
||||
INT clock_settime(clockid_t t, const struct timespec * tspec)
|
||||
INT clock_getres(clockid_t t, struct timespec * tspec)
|
||||
|
||||
/***********************************************************************/
|
||||
/* CALLS RELATED TO Signal */
|
||||
/***********************************************************************/
|
||||
|
||||
INT sigwait(const sigset_t *set, int *sig)
|
||||
INT sigaddset(sigset_t *set, int signo)
|
||||
INT sigdelset(sigset_t *set, int signo)
|
||||
INT sigemptyset(sigset_t *set)
|
||||
INT signal(int signo, void (*func)(int))
|
||||
INT sigfillset(sigset_t *set)
|
||||
|
||||
|
||||
4.0 POSIX Compliancy Wrapper Error Handling
|
||||
|
||||
There are two "error handling" functions defined in tx_posix.c and used
|
||||
throughout the Wrapper, as follows:
|
||||
|
||||
posix_error_handler
|
||||
posix_internal_error
|
||||
|
||||
In general these routines are called when basic usage errors occur. These
|
||||
routines may also be used as a place to catch errors that are not detected if the
|
||||
application source is not checking the return status. The default processing for each of
|
||||
these is a simple spin loop.
|
||||
|
||||
Most functions can provide an error number. The means by which each function
|
||||
provides its error numbers is specified in its description. Some functions
|
||||
provide the error number in a variable accessed through the symbol posix_errno.
|
||||
While other functions return an error number directly as the function value. Functions
|
||||
return a value of zero to indicate success. If more than one error occurs in
|
||||
processing a function call, any one of the possible errors may be returned, as the order
|
||||
of detection is undefined.
|
||||
|
||||
Some functions may return [ENOSYS] suggesting that an attempt was made to
|
||||
use a function that is not available in this implementation.
|
||||
|
||||
Each pthread has its own error number, which can be obtained through a
|
||||
function call:
|
||||
|
||||
INT posix_get_pthread_errno(pthread_t ptid)
|
||||
|
||||
This call will return the last generated error code for the pthread having
|
||||
ptid as an ID.
|
||||
|
||||
|
||||
5.1 POSIX Compliancy Wrapper Limitations
|
||||
|
||||
Due to performance and architecture issues, this POSIX Compliancy Wrapper
|
||||
does not support all the POSIX calls. A summary of the POSIX Compliancy
|
||||
Wrapper limitations is as follows:
|
||||
|
||||
<EFBFBD> Configuration
|
||||
<EFBFBD> Initialization
|
||||
<EFBFBD> Driver and I/O model might require porting of current drivers.
|
||||
<EFBFBD> Multi-processor extensions are not supported
|
||||
<EFBFBD> Unsupported calls (please see below)
|
||||
. Calls supported with certain limitations (please see list below)
|
||||
|
||||
The POSIX Compliancy Wrapper supports a subset of POSIX calls. In addition,
|
||||
there are also certain limitations with respect to some services. Below is the list of
|
||||
such limitations:
|
||||
|
||||
|
||||
LIMITATIONS
|
||||
|
||||
Following calls are implemented with some limitations:
|
||||
|
||||
1.) mq_open()
|
||||
|
||||
LIMITATIONS :
|
||||
a.) The value of mode (mode_t) has no effect in this implementation.
|
||||
b.) If pAttr is NULL, the message queue is created with
|
||||
implementation-defined default message queue attributes.
|
||||
The default message queue attributes selected are :
|
||||
|
||||
#define MQ_MAXMSG 125 [MQ_MAXMSG 1024 (POSIX value)]
|
||||
#define MQ_MSGSIZE 500 [MQ_MSGSIZE 4096 (POSIX value)]
|
||||
#define MQ_FLAGS 0
|
||||
|
||||
This is due to limitation of size of posix_region0_byte_pool (64KB ).
|
||||
|
||||
2.) mq_send()
|
||||
|
||||
LIMITATIONS :
|
||||
a.) In POSIX : If more than one mq_send() is blocked on a queue and
|
||||
space becomes available in that queue, the message with the highest
|
||||
priority will be unblocked. THIS FEATURE IS NOT IMPLEMENTED.
|
||||
|
||||
b.) If a message is sent (or received) to a queue with out opening the named
|
||||
queue, in such a case mqdes (message queue descriptor) pointer is
|
||||
invalid and may result in erratic behavior.
|
||||
|
||||
3.) mq_receive()
|
||||
|
||||
LIMITATIONS :
|
||||
a.) If a receive (or send) message from queue with out it being opened, erratic
|
||||
behavior may ensue.
|
||||
|
||||
4.) ULONG sem_close()
|
||||
|
||||
LIMITATIONS :
|
||||
a.) This routine does not deallocate any system resources.
|
||||
|
||||
5.) POSIX SEMAPHORE
|
||||
|
||||
LIMITATIONS :
|
||||
a.) If any operation (eg. sem_post, sem_wait, sem_trywait, sem_getvalue ) is done on a
|
||||
semaphore before creating or opening (sem_open()) the named semaphore, erratic
|
||||
behavior may result.
|
||||
|
||||
6.) ULONG sem_trywait(sem_t * sem)
|
||||
|
||||
LIMITATIONS :
|
||||
|
||||
a.) EDEADLKA :->[ This is a return value when deadlock condition is detected; i.e., two separate
|
||||
processes are waiting for an available resource to be released via a
|
||||
semaphore "held" by the other process.] This is not implemented.
|
||||
|
||||
b.) EINTR :->[ This is a return value when sem_wait() was interrupted by a signal.]
|
||||
This is not implemented.
|
||||
7.) Thread Cancelation
|
||||
|
||||
pthread cancelation cleanup handlers are not supported which means
|
||||
pthread_cleanup_push( ) and pthread_cleanup_pop( ) functions are not
|
||||
implemented.
|
||||
|
||||
When the pthread_cancel( ) function is called the target thread is canceled
|
||||
with immediate effect. (provided cancelability is enabled for the target
|
||||
pthread)
|
||||
|
||||
The cancelation processing in the target thread shall run asynchronously
|
||||
with respect to the ailing thread returning from pthread_cancel( ).
|
||||
|
||||
8.) Attributes for Condition Variable
|
||||
No attributes are supported for condition variable in this implementation.
|
||||
|
||||
9.) pthreads suspended by nanosleep() and sleep() calls can not be awakened
|
||||
by signals, once in the suspension both these calls will complete the
|
||||
suspension period.
|
||||
|
||||
10.) pthread_once (pthread_once_t * once_control, VOID (*init_routine) (VOID))
|
||||
There is no provision if the init_routine contains a cancellation point.
|
||||
|
||||
|
||||
6.0 Demonstration System
|
||||
|
||||
The file posix_demo.c contains a demonstration system that utilizes POSIX
|
||||
calls. This Demo application will demonstrate some of the basic POSIX
|
||||
calls. This demo application should be used as an example of how to integrate the POSIX
|
||||
Compliancy Wrapper into your application.
|
||||
|
||||
|
||||
7.0 Future POSIX Compliancy Wrapper Phases
|
||||
|
||||
Please get in touch with us for next phases of this POSIX Compliancy
|
||||
Wrapper.
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user