1 POSIX Compliancy Wrapper for Azure RTOS ThreadX
2
3
4
51.0 POSIX Compliancy Wrapper Overview
6
7The POSIX Compliancy Wrapper supports many of the basic POSIX calls, with
8some limitations, and utilizes ThreadX� primitives underneath. This POSIX
9compatibility layer should have good performance since it utilizes internal
10ThreadX primitives and bypasses basic ThreadX error checking.
11
12
131.1 POSIX Compliancy Wrapper Source
14
15The Wrapper source code is designed for simplicity and is comprised of separate source
16files for most functions. Including the supplied pthread.h file will import
17all the necessary POSIX constants and subroutine prototypes.
18
19
201.2 POSIX Compliancy Wrapper Documentation
21
22This document itself serves as a POSIX Compliancy Wrapper User Guide by
23providing an overview of the porting process, including various caveats and
24pitfalls to watch out for. In addition, each covered POSIX call is documented,
25including information about supported/unsupported options, limitations, deviations,
26and suggestions on how to work-around any limitations.
27
28
292.0 Installation
30
31The POSIX Compliancy Wrapper is easily installed by adding the
32the posix library to your current application build. Make sure your application build
33references the same header files as the ones the posix library has been built with.
34The file pthread.h must be included in your application source where POSIX
35calls are required.
36Since the POSIX compliancy wrapper does not cover the complete standard, not all prototypes
37are provided. Most notably is the header file tx_px_time.h.
38
392.1 Initialization
40
41The POSIX Compliancy Wrapper requires that a special initialization function is called
42prior to accessing any POSIX calls. The function to call and its prototype is:
43
44VOID *posix_initialize(VOID * posix_memory);
45
46This function is usually called from the application specific ThreadX
47initialization routine, tx_application_define(). The memory pointer supplied
48to posix_initialize must be a contiguouis reserved section of memory
49that has at least the following number of bytes:
50
51
52 POSIX_SYSTEM_STACK_SIZE +
53 TX_REGION0_SIZE_IN_BYTES + /* Region0 size */
54 (WORK_QUEUE_DEPTH * WORK_REQ_SIZE) + /* system queue size */
55 POSIX_HEAP_SIZE_IN_BYTES
56
57
58These equates are defined in tx_posix.h. The following additional equates
59define the number of POSIX objects supported by the POSIX Wrapper (default
60value is shown):
61
62 SEM_NSEMS_MAX 100 /* simultaneous POSIX semaphores */
63
64 SEM_NAME_MAX 10 /* maximum length of name of semaphore */
65
66 SEM_VALUE_MAX 100 /* max value of semaphore while initialization */
67
68 POSIX_MAX_QUEUES 32 /* maximum number of simultaneous POSIX
69 message queues supported */
70
71 PATH_MAX 10 /* maximum length of name of a message queue */
72
73 PTHREAD_THREADS_MAX 256 /* define the maximum number of simultaneous
74 POSIX Pthreads supported. */
75
76 POSIX_MAX_MUTEX 32 /* define the maximum number of simultaneous
77 POSIX mutexes sported. */
78
79
80The function posix_initialize will return a pointer to the next free
81available memory location for the application.
82
83
843.0 POSIX Calls
85
86Once posix_initialize returns, POSIX calls can be made.
87The Threadx POSIX Compliancy Wrapper supports the following POSIX
88calls:
89
90/***********************************************************************/
91/* CALLS RELATED TO POSIX MESSAGE QUEUE */
92/***********************************************************************/
93
94INT mq_send(mqd_t mqdes, const char * msg_ptr,
95 ssize_t msg_len,ULONG msg_prio );
96ssize_t mq_receive(mqd_t mqdes, VOID *pMsg, ssize_t msgLen,
97 ULONG *pMsgPrio );
98INT mq_unlink(const char * mqName);
99INT mq_close(mqd_t mqdes);
100mqd_t mq_open(const CHAR * mqName, ULONG oflags,...);
101
102
103/***********************************************************************/
104/* CALLS RELATED TO POSIX SEMAPHORE */
105/***********************************************************************/
106
107INT sem_close(sem_t * sem);
108INT sem_getvalue(sem_t * sem,ULONG * sval);
109sem_t *sem_open(const char * name, ULONG oflag, ...);
110INT sem_post(sem_t * sem);
111INT sem_trywait(sem_t * sem);
112INT sem_unlink(const char * name);
113INT sem_wait( sem_t * sem );
114INT sem_init(sem_t *sem , INT pshared, UINT value);
115INT sem_destroy(sem_t *sem);
116
117/***********************************************************************/
118/* CALLS RELATED TO POSIX pthreads */
119/***********************************************************************/
120
121INT sched_yield(VOID);
122INT pthread_create (pthread_t *thread,
123 pthread_attr_t *attr,
124 VOID *(*start_routine)(VOID*),VOID *arg);
125INT pthread_detach(pthread_t thread);
126INT pthread_join(pthread_t thread, VOID **value_ptr);
127INT pthread_equal(pthread_t thread1, pthread_t thread2);
128VOID pthread_exit(VOID *value_ptr);
129pthread_t pthread_self(VOID);
130INT pthread_attr_destroy(pthread_attr_t *attr);
131INT pthread_attr_getdetachstate( pthread_attr_t *attr,INT *detachstate);
132INT pthread_attr_setdetachstate(pthread_attr_t *attr,INT detachstate);
133INT pthread_attr_getinheritsched(pthread_attr_t *attr, INT *inheritsched);
134INT pthread_attr_setinheritsched(pthread_attr_t *attr, INT inheritsched);
135INT pthread_attr_getschedparam(pthread_attr_t *attr,struct sched_param *param);
136INT pthread_attr_setschedparam(pthread_attr_t *attr,struct sched_param *param);
137INT pthread_attr_getschedpolicy(pthread_attr_t *attr, INT *policy);
138INT pthread_attr_setschedpolicy(pthread_attr_t *attr, INT policy);
139INT pthread_attr_init(pthread_attr_t *attr);
140INT phread_attr_getstackaddr( pthread_attr_t *attr,VOID **stackaddr);
141INT phread_attr_setstackaddr(pthread_attr_t *attr,VOID **stackaddr);
142INT pthread_attr_getstacksize( pthread_attr_t *attr, ssize_t *stacksize);
143INT pthread_attr_setstacksize(pthread_attr_t *attr, ssize_t stacksize);
144INT phread_attr_getstack( pthread_attr_t *attr,VOID **stackaddr,
145 ssize_t *stacksize);
146INT phread_attr_setstack( pthread_attr_t *attr,VOID *stackaddr,
147 ssize_t stacksize);
148
149INT pthread_mutexattr_gettype(pthread_mutexattr_t *attr, INT *type);
150INT pthread_mutexattr_settype(pthread_mutexattr_t *attr, INT type);
151INT pthread_mutexattr_destroy(pthread_mutexattr_t *attr);
152INT pthread_mutexattr_init(pthread_mutexattr_t *attr);
153INT pthread_mutex_destroy(pthread_mutex_t *mutex);
154INT pthread_mutex_init(pthread_mutex_t *mutex, pthread_mutexattr_t *attr);
155INT pthread_mutex_lock(pthread_mutex_t *mutex );
156INT pthread_mutex_unlock(pthread_mutex_t *mutex );
157INT pthread_mutex_trylock(pthread_mutex_t *mutex);
158INT pthread_mutexattr_getprotocol( pthread_mutexattr_t *attr, INT *protocol);
159INT pthread_mutexattr_setprotocol(pthread_mutexattr_t *attr, INT protocol);
160INT pthread_mutexattr_getpshared (pthread_mutexattr_t *attr, INT *pshared);
161INT pthread_mutexattr_setpshared (pthread_mutexattr_t *attr, INT pshared);
162INT pthread_mutex_timedlock(pthread_mutex_t *mutex, struct timespec *abs_timeout);
163INT pthread_setcancelstate (INT state, INT *oldstate);
164INT pthread_setcanceltype (INT type, INT *oldtype);
165INT pthread_cancel(pthread_t thread);
166VOID pthread_yield(VOID);
167VOID pthread_testcancel(VOID);
168INT pthread_getschedparam(pthread_t thread, INT *policy, struct sched_param *param);
169INT pthread_setschedparam(pthread_t thread, INT policy, const struct sched_param *param);
170
171INT sched_get_priority_max(INT policy)
172INT sched_get_priority_min(INT policy)
173
174INT pthread_once (pthread_once_t * once_control, VOID (*init_routine) (VOID))
175
176INT pthread_kill(ALIGN_TYPE thread_id, int sig)
177INT pthread_sigmask(int how, const sigset_t *newmask, sigset_t *oldmask)
178
179
180/***********************************************************************/
181/* CALLS RELATED TO POSIX CONDITION VARIABLE */
182/***********************************************************************/
183
184INT pthread_cond_destroy(pthread_cond_t *cond);
185INT pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *attr);
186INT pthread_cond_broadcast(pthread_cond_t *cond);
187INT pthread_cond_signal(pthread_cond_t *cond);
188INT pthread_cond_timedwait(pthread_cond_t *cond,pthread_mutex_t *mutex,
189 struct timespec *abstime);
190INT pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
191
192
193/***********************************************************************/
194/* CALLS RELATED TO Timer */
195/***********************************************************************/
196
197INT nanosleep(struct timespec *req, struct timespec *rem)
198INT sleep(ULONG seconds)
199INT clock_gettime(clockid_t t, struct timespec * tspec)
200INT clock_settime(clockid_t t, const struct timespec * tspec)
201INT clock_getres(clockid_t t, struct timespec * tspec)
202
203/***********************************************************************/
204/* CALLS RELATED TO Signal */
205/***********************************************************************/
206
207INT sigwait(const sigset_t *set, int *sig)
208INT sigaddset(sigset_t *set, int signo)
209INT sigdelset(sigset_t *set, int signo)
210INT sigemptyset(sigset_t *set)
211INT signal(int signo, void (*func)(int))
212INT sigfillset(sigset_t *set)
213
214
2154.0 POSIX Compliancy Wrapper Error Handling
216
217There are two "error handling" functions defined in tx_posix.c and used
218throughout the Wrapper, as follows:
219
220 posix_error_handler
221 posix_internal_error
222
223In general these routines are called when basic usage errors occur. These
224routines may also be used as a place to catch errors that are not detected if the
225application source is not checking the return status. The default processing for each of
226these is a simple spin loop.
227
228Most functions can provide an error number. The means by which each function
229provides its error numbers is specified in its description. Some functions
230provide the error number in a variable accessed through the symbol posix_errno.
231While other functions return an error number directly as the function value. Functions
232return a value of zero to indicate success. If more than one error occurs in
233processing a function call, any one of the possible errors may be returned, as the order
234of detection is undefined.
235
236Some functions may return [ENOSYS] suggesting that an attempt was made to
237use a function that is not available in this implementation.
238
239Each pthread has its own error number, which can be obtained through a
240function call:
241
242INT posix_get_pthread_errno(pthread_t ptid)
243
244This call will return the last generated error code for the pthread having
245ptid as an ID.
246
247
2485.1 POSIX Compliancy Wrapper Limitations
249
250Due to performance and architecture issues, this POSIX Compliancy Wrapper
251does not support all the POSIX calls. A summary of the POSIX Compliancy
252Wrapper limitations is as follows:
253
254� Configuration
255� Initialization
256� Driver and I/O model might require porting of current drivers.
257� Multi-processor extensions are not supported
258� Unsupported calls (please see below)
259. Calls supported with certain limitations (please see list below)
260
261The POSIX Compliancy Wrapper supports a subset of POSIX calls. In addition,
262there are also certain limitations with respect to some services. Below is the list of
263such limitations:
264
265
266LIMITATIONS
267
268Following calls are implemented with some limitations:
269
2701.) mq_open()
271
272 LIMITATIONS :
273 a.) The value of mode (mode_t) has no effect in this implementation.
274 b.) If pAttr is NULL, the message queue is created with
275 implementation-defined default message queue attributes.
276 The default message queue attributes selected are :
277
278 #define MQ_MAXMSG 125 [MQ_MAXMSG 1024 (POSIX value)]
279 #define MQ_MSGSIZE 500 [MQ_MSGSIZE 4096 (POSIX value)]
280 #define MQ_FLAGS 0
281
282 This is due to limitation of size of posix_region0_byte_pool (64KB ).
283
2842.) mq_send()
285
286 LIMITATIONS :
287 a.) In POSIX : If more than one mq_send() is blocked on a queue and
288 space becomes available in that queue, the message with the highest
289 priority will be unblocked. THIS FEATURE IS NOT IMPLEMENTED.
290
291 b.) If a message is sent (or received) to a queue with out opening the named
292 queue, in such a case mqdes (message queue descriptor) pointer is
293 invalid and may result in erratic behavior.
294
2953.) mq_receive()
296
297 LIMITATIONS :
298 a.) If a receive (or send) message from queue with out it being opened, erratic
299 behavior may ensue.
300
3014.) ULONG sem_close()
302
303 LIMITATIONS :
304 a.) This routine does not deallocate any system resources.
305
3065.) POSIX SEMAPHORE
307
308 LIMITATIONS :
309 a.) If any operation (eg. sem_post, sem_wait, sem_trywait, sem_getvalue ) is done on a
310 semaphore before creating or opening (sem_open()) the named semaphore, erratic
311 behavior may result.
312
3136.) ULONG sem_trywait(sem_t * sem)
314
315 LIMITATIONS :
316
317 a.) EDEADLKA :->[ This is a return value when deadlock condition is detected; i.e., two separate
318 processes are waiting for an available resource to be released via a
319 semaphore "held" by the other process.] This is not implemented.
320
321 b.) EINTR :->[ This is a return value when sem_wait() was interrupted by a signal.]
322 This is not implemented.
3237.) Thread Cancelation
324
325pthread cancelation cleanup handlers are not supported which means
326pthread_cleanup_push( ) and pthread_cleanup_pop( ) functions are not
327implemented.
328
329When the pthread_cancel( ) function is called the target thread is canceled
330with immediate effect. (provided cancelability is enabled for the target
331pthread)
332
333The cancelation processing in the target thread shall run asynchronously
334with respect to the ailing thread returning from pthread_cancel( ).
335
3368.) Attributes for Condition Variable
337 No attributes are supported for condition variable in this implementation.
338
3399.) pthreads suspended by nanosleep() and sleep() calls can not be awakened
340by signals, once in the suspension both these calls will complete the
341suspension period.
342
34310.) pthread_once (pthread_once_t * once_control, VOID (*init_routine) (VOID))
344There is no provision if the init_routine contains a cancellation point.
345
346
3476.0 Demonstration System
348
349The file posix_demo.c contains a demonstration system that utilizes POSIX
350calls. This Demo application will demonstrate some of the basic POSIX
351calls. This demo application should be used as an example of how to integrate the POSIX
352Compliancy Wrapper into your application.
353
354
3557.0 Future POSIX Compliancy Wrapper Phases
356
357Please get in touch with us for next phases of this POSIX Compliancy
358Wrapper.
359
360
361
362
363