This section describes the system calls and C language interface to the following system components:
The calls for each component are arranged alphabetically in separate subsections. Each subsection begins with an intro page that contains an alphabetical listing of the calls for that particular component.
A comprehensive list containing all of the system calls described in this section, with page numbers, is provided on pages 1-3 through 1-6.
See the section, ``About This Manual" for a description of the notation conventions and general headings used in reference pages.
intro - Introduction to pSOS+ System Calls
The first part of Section 1 contains descriptions of the following pSOS+ system calls:
as_catch - Specify an asynchronous signal routine (ASR)
#include <psos.h>
unsigned long as_catch(
void (* start_addr) (), /* ASR address */
unsigned long mode /* ASR attributes */
)
This system call allows a task to specify an Asynchronous Signal Routine (ASR) to handle asynchronous signals. as_catch() supplies the starting address of the task's ASR, and its initial execution mode. If the input ASR address is zero, then the caller is deemed to have an invalid ASR, and any signals sent to it will be rejected.
A task's ASR gains control much like an ISR. If a task has pending signals (sent via as_send()), then the next time the task is dispatched to run, it will be forced to first execute the task's specified ASR. A task executes its ASR according to the mode supplied by the as_catch() call (e.g. Supervisor mode, Non-preemptible etc.). Upon entry to the ASR, all pending signals - including all those received since the last ASR invocation - are passed as an argument to the ASR. In addition, a stack frame is built to facilitate the return from the ASR.
The start_addr argument specifies the address of the ASR.
The mode argument specifies the ASR's primary attributes, and is formed by OR-ing the following symbolic constants (one from each pair), which are defined in <psos.h>.
One of the symbolic constants T_ISR and T_NOISR (defined in <psos.h>) must be ORed with the symbolic constants used to specify the ASR's interrupt mask level.
If the T_NOASR attribute is set, the ASR is prevented from being re-entered as a result of another as_send() call made to that task. If the T_ASR attribute is enabled, then the ASR should be programmed to be re-entrant.
This system call always returns 0.
This system call returns no errors.
None, since the actions performed by as_catch() are entirely confined to the local node, although asynchronous signals may be sent from remote nodes.
as_return - Return from an asynchronous signal routine (ASR)
#include <psos.h> unsigned long as_return();
This system call must be used by a task's ASR to exit, and return to the original flow of execution of the task. The purpose of this call is to allow the pSOS+ kernel to restore the task to its state before the ASR.
Prior to an as_return() call, CPU registers do not have to be restored by the ASR. They are saved by the pSOS+ kernel prior to an ASR and restored within the as_return() call. An ASR can, therefore, be written in high-level languages like C.
If successful, this system call never returns. An error code is generated on failure.
| HEX | MNEMONIC | DESCRIPTION | ||
|---|---|---|---|---|
| 0x3E | ERR_NOTINASR | Illegal, not called from an ASR. |
None, since its actions are confined entirely to the local node.
as_send - Send asynchronous signals to a task
#include <psos.h> unsigned long as_send( unsigned long tid, /* target task ID */ unsigned long signals /* bit-encoded signal list */ )
This system call sends asynchronous signals to a task. The purpose of these signals is to force a task to break from its normal flow of execution and execute its Asynchronous Signal Routine (ASR).
Asynchronous signals are like software interrupts, with ASRs taking on the role of ISRs. Unlike interrupts, which are serviced almost immediately, an asynchronous signal does not immediately affect the state of the task. An as_send() call is serviced only when the task is next dispatched to run (and that depends on the state of the task and its priority).
Each task has 32 signals. They are encoded bit-wise in a single long word. Bits 31 through 16 are reserved for internal system use, and bits 15 through 0 are available for user-specific purposes.
Like events, signals are neither queued nor counted. For example, if three identical signals are sent to a task before its ASR has a chance to execute, the three signals have the same effect as one.
The argument tid specifies the task to receive the signals. The argument signals contains the bit-encoded signals.
This system call returns 0 on success, or an error code on failure.
| HEX | MNEMONIC | DESCRIPTION |
|---|---|---|
| 0x05 | ERR_OBJDEL | Task has already been deleted. |
| 0x06 | ERR_OBJID | tid incorrect, validity check failed. |
| 0x3F | ERR_NOASR | Task has no valid ASR. |
If tid identifies a global task that resides on another processor node, the pSOS+ kernel internally makes an RSC to that remote node to send the asynchronous signal to the task.
de_close - Close an I/O device
#include <psos.h>
unsigned long de_close(
unsigned long dev, /* major/minor device number */
void *iopb, /* I/O parameter block address */
void *retval /* return value */
)
The de_close() call invokes the device close routine of a pSOS+ device driver specified by the dev argument. The functionality of the device close routine is device-specific. For example, an RS-232 device driver close-routine may signal a modem to hang up to signify the end of the connection.
The de_close() call, when used in conjunction with de_open(), can also be used to implement mutual exclusion. In this case, de_close() can be used to signal the end of a critical region for the device operation.
The argument dev specifies the major and minor device numbers, which are stored in the upper and lower 16 bits, respectively. The argument iopb points to an I/O parameter block, the contents of which are driver-specific. The argument retval points to a variable that receives a driver-specific value returned by the driver.
This call returns 0 on success, or an error code on failure. Besides the error codes listed below, other driver-specific errors may be returned.
| HEX | MNEMONIC | DESCRIPTION |
|---|---|---|
| 0101 | ERR_IODN | Illegal device (major) number |
| 0102 | ERR_NODR | No driver provided |
de_cntrl - Request special I/O device service
#include <psos.h>
unsigned long de_cntrl(
unsigned long dev, /* major/minor device number */
void *iopb, /* I/O parameter block address */
void *retval /* return value */
)
The de_cntrl() call invokes the device control routine of a pSOS+ device driver specified by the dev argument. The functionality of a device control routine depends entirely on the device driver implementation. It can include anything that cannot be categorized under the other five I/O services. de_cntrl() for a device can be used to perform multiple input and output sub-functions. In such cases, extra parameters in the I/O parameter block can designate the sub-function.
The argument dev specifies the major and minor device numbers, which are stored in the upper and lower 16 bits, respectively. The argument iopb points to an I/O parameter block, the contents of which are driver-specific. The argument retval points to a variable that receives a driver-specific value returned by the driver.
This call returns 0 on success or an error code on failure. Beside the error codes listed below, other driver-specific errors may be returned.
| HEX | MNEMONIC | DESCRIPTION |
|---|---|---|
| 0101 | ERR_IODN | Illegal device (major) number |
| 0102 | ERR_NODR | No driver provided |
Examples of functions that are often performed by de_cntrl() include the following:
de_init - Initialize an I/O device and its driver
#include <psos.h>
unsigned long de_init(
unsigned long dev, /* major/minor device number */
void *iopb, /* I/O parameter block */
void *retval, /* return value */
void **data_area /* device data area */
)
The de_init() call invokes the device init routine of the pSOS+ device drive specified by the dev argument.
The drive init routine can perform one-time device initialization functions such as:
The argument dev specifies the major and minor device numbers, which are stored in the upper and lower 16 bits, respectively. The argument iopb points to an I/O parameter block, the contents of which are driver-specific. The argument retval points to a variable that receives a driver-specific value returned by the driver.
data_area is no longer used, but it remains to support compatibility with older drivers and/or pSOS+ application code.
This call returns 0 on success, or an error code on failure. Besides the error codes listed below, other driver-specific error may be returned.
| HEX | MNEMONIC | DESCRIPTION |
|---|---|---|
| 0101 | ERR_IODN | Illegal device (major) number |
| 0102 | ERR_NODR | No driver provided |
#include <psos.h>
unsigned long de_open(
unsigned long dev, /* major/minor device number */
void *iopb, /* I/O parameter block address */
void *retval /* return value */
)
The de_open() call invokes the device open routine of a pSOS+ device driver specified by the dev argument.
The device open routine can be used to perform functions that need to be done before the I/O operations can be performed on the device. For example, an asynchronous serial device driver can reset communication parameters (such as baud rate, parity, and so on) to a known state for the channel being opened. Parameters are baud rate, parity, and so on.
A device driver can also assign specific duties to the open routine that are not directly related to data transfer or device operations. For example, a device driver can use de_open() to enforce exclusive use of the device during several read and/or write operations.
The argument dev specifies the major and minor device numbers, which are stored in the upper and lower 16 bits, respectively. The argument iopb points to an I/O parameter block, the contents of which are driver-specific. The argument retval points to a variable that receives a driver-specific value returned by the driver.
This call returns 0 on success, or an error code on failure. Besides the error codes listed below, other driver-specific errors may be returned.
| HEX | MNEMONIC | DESCRIPTION |
|---|---|---|
| 0101 | ERR_IODN | Illegal device (major) number |
| 0102 | ERR_NODR | No driver provided |
de_read - Read data from an I/O device
#include <psos.h>
unsigned long de_read(
unsigned long dev, /* major/minor device number */
void *iopb, /* I/O parameter block address */
void *retval /* return value */
)
The de_read() call is used to read data from a device. It invokes the device read routine of a pSOS+ device driver specified by the dev argument. This service normally requires additional parameters contained in the I/O parameter block, such as the address of a data area to hold the data and the number of data units to read.
The argument dev specifies the major and minor device numbers, which are stored in the upper and lower 16 bits, respectively. The argument iopb points to an I/O parameter block, the contents of which are driver-specific. The argument retval points to a variable that receives a driver-specific value returned by the driver. For example, it can hold the actual number of data units read.
This call returns 0 on success, or an error code on failure. Besides the error codes listed below, other driver-specific error may be returned.
| HEX | MNEMONIC | DESCRIPTION |
|---|---|---|
| 0101 | ERR_IODN | Illegal device (major) number |
| 0102 | ERR_NODR | No driver provided |
For many interrupt-driven devices, de_read() starts an I/O transaction and blocks the calling task. Most of the I/O transaction can actually be performed in the device's ISR. Upon completion of the transaction, the ISR unblocks the blocked task.
de_write - Write to an I/O device
#include <psos.h>
unsigned long de_write(
unsigned long dev, /* major/minor device number */
void *iopb, /* I/O parameter block address */
void *retval /* return value */
)
The de_write() call is used to write to a device. It invokes the device write routine of a pSOS+ device driver specified by the dev argument. This service normally requires the additional parameters contained in the I/O parameter block, such as the address of the user's output data and the number of data units to write.
The argument dev specifies the major and minor device numbers, which are stored in the upper and lower 16 bits, respectively. The argument iopb points to an I/O parameter block, the contents of which are driver-specific. The argument retval points to a variable that receives a driver-specific value returned by the driver (the actual number of data units written, for example).
This call returns 0 on success, or an error code on failure. Besides the error codes listed below, other driver-specific error may be returned.
| HEX | MNEMONIC | DESCRIPTION |
|---|---|---|
| 0101 | ERR_IODN | Illegal device (major) number. |
| 0102 | ERR_NODR | No driver provided. |
For many interrupt-driven devices, de_write() starts an I/O transaction and blocks the calling task. Most of the I/O transactions can actually be performed in the device's ISR. Upon completion of the transaction, the ISR unblocks the blocked task.
errno_addr - Obtain address of the calling task's errno variable
#include <psos.h> unsigned long *errno_addr();
This system call returns the address of the calling task's internal errno variable.
The pSOS+ kernel maintains an internal errno variable for every task. Whenever an error is detected by any pSOSystem component, the associated error code is stored into the running task's internal errno variable. The error code may then be retrieved by referencing the errno macro defined in the header file <psos.h> as follows:
Thus, a statement like the following expands to include a call to errno_addr().
This system call returns the address of the errno variable of the calling task.
ev_asend - (pSOS+m kernel only) Asynchronously send events to a task
#include <psos.h>
unsigned long ev_asend(
unsigned long tid, /* target task identifier */
unsigned long events /* bit-encoded events */
)
This system call asynchronously sends events to a task. It is identical to ev_send() except the call is made asynchronously. Refer to the description of ev_send() for further information.
The task ID of the target task is specified by the argument tid. The events to send are bit encoded in the argument events.
When called in a system running the pSOS+m kernel, this call always returns 0. The pSOS+ kernel (the single processor version) returns ERR_SSFN.
Should the call fail, if present, the node's MC_ASYNCERR routine is invoked and the following error codes may be reported:
| HEX | MNEMONIC | DESCRIPTION |
|---|---|---|
| 0x05 | ERR_OBJDEL | Task has been deleted. |
| 0x06 | ERR_OBJID | tid is incorrect, failed validity check. |
If an MC_ASYNCERR routine is not provided, the pSOS+m kernel generates a fatal error.
If the tid input argument identifies a global task residing on another processor node, then the pSOS+m kernel will internally make an RSC to that remote node to send the specified events to that task.
ev_receive - Wait for an event
#include <psos.h>
unsigned long ev_receive(
unsigned long events, /* bit-encoded events */
unsigned long flags, /* event processing attributes */
unsigned long timeout, /* timeout delay */
unsigned long *events_r /* events received */
)
This service call allows a task to wait for an event condition. The event condition is a set of events and an ANY/ALL waiting condition qualifier. Each task can wait on 32 events, which are bit-encoded in a long word. An ALL condition occurs when all of the specified events are received. An ANY condition occurs when any of the specified events is received.
If the selected event condition is satisfied by events already pending, ev_receive() clears those events and returns. Otherwise, the caller either returns immediately with an error, waits until the requisite new events have been received, or waits until a timeout occurs (if requested).
If successful, ev_receive() returns the actual event captured by the call in the location pointed to by events_r.
The argument events specifies the set of events.
The flags argument is formed by OR-ing the following symbolic constants (one from each pair), which are defined in <psos.h>.
If EV_NOWAIT is set, the timeout argument is ignored. If EV_WAIT is set, the timeout parameter specifies the timeout in units of clock ticks. When EV_WAIT is set, if the value of timeout is 0, ev_receive() waits forever.
A successful return with the EV_ALL attribute signifies that the events captured match the specified events. Similarly, a successful return with EV_ANY signifies that at least one specified event was captured.
An events argument equal to 0 is special. In this case, ev_receive() returns the pending events but leaves them pending. In this case, the other parameters are ignored.
This system call returns 0 on success, or an error code on failure.
None. The actions performed by ev_receive() take place only on the local node (whether or not events come from other nodes).
ev_send - Send events to a task
#include <psos.h>
unsigned long ev_send(
unsigned long tid, /* target task identifier */
unsigned long events /* bit-encoded events */
)
This system call sends events to a task. If the target task is not waiting for events, the newly sent events are simply made pending. If the task is waiting for events, and the wait condition is fully satisfied as a result of the new events, then the task is unblocked and readied for execution. Otherwise, the task continues to wait. In either case, any of the events sent that do not match those waited on are always left pending.
Each task has 32 events, which are encoded bit-wise in a single long word. Bits 31 through 16 are for internal system use, and bits 15 through 0 are for user-specific purposes. ev_send() can send up to 32 different events at one time.
Events are neither queued nor counted. For example, if three identical events are sent to a task before it issues a wait for that event, the three events have the same effect as one event.
The task identifier of the target task is specified by the argument tid. The events to send are bit-encoded in the argument events.
This system call returns 0 on success, or an error code on failure.
| HEX | MNEMONIC | DESCRIPTION |
|---|---|---|
| 0x05 | ERR_OBJDEL | Task has been deleted. |
| 0x06 | ERR_OBJID | tid is incorrect, failed validity check. |
| 0x65 | ERR_STALEID | Object's node has failed. |
If the tid input argument identifies a global task residing on another processor node, then the pSOS+ kernel internally makes an RSC to that remote node to send the input events to that task.
Callable from an ISR, KI or callout when the tid is not 0 and the targeted task is local to the node from on the ev_send() call was made.
k_fatal - Abort and enter fatal error handling mode
#include <psos.h>
void k_fatal(
unsigned long err_code, /* user's error code */
unsigned long flags /* fatal condition attributes */
)
This system call allows the user application to pass control to the user-defined fatal error handler in the event of a nonrecoverable failure. k_fatal() forces a nonrecoverable shutdown of the pSOS+ environment and never returns to the caller.
The argument err_code specifies a user-defined failure code that is passed to the fatal error handler. The failure code must be at least 0x10000.
The flags argument is ignored in the single-processor version of the pSOS+ kernel. See Multiprocessor Considerations for a complete description of this parameter. In a multiprocessor system, the flags argument is used to determine if the local node should be shutdown or a system-wide shutdown should occur. flags is formed by selecting one of the following symbolic constants, which are defined in <psos.h>.
If the value of flags is K_GLOBAL, a global shutdown packet is sent to the master, which then sends a shutdown packet to every other node in the system.
This call never returns to the caller.
In a multiprocessor system, k_fatal() can be used to implement a system-wide abort or shutdown. In this case, K_GLOBAL should be set. This causes a global shutdown packet to go to the master node, which sends a shutdown packet to every node in the system.
k_terminate - (pSOS+m kernel only) Terminate a node other than the master node
unsigned long k_terminate (
unsigned long node, /* Node to terminate */
unsigned long fcode, /* failure code */
unsigned long flags /* unused */
)
This system call allows the user application to shutdown a node that it believes has failed or is operating incorrectly. k_terminate() causes the specified node to receive a shutdown packet and all other nodes to receive notification of the specified node's failure.
node specifies the node number of the node to shutdown. It cannot be the master node. err_code specifies a user-defined failure code. It must be at least 0x10000. flags is unused.
This system returns 0 on success or an error code on failure.
| HEX | MNEMONIC | DESCRIPTION |
|---|---|---|
| 0x04 | ERR_NODENO | Node number out of range |
| 0x67 | ERR_MASTER | Cannot terminate master node |
m_ext2int - Convert an external address to an internal address
#include <psos.h>
unsigned long m_ext2int(
void *ext_addr, /* external reference */
void **int_addr /* local reference */
)
This system call converts an external address into an internal address corresponding to the calling node. A typical use for this conversion is by a node that has received an address from another node that resides in a dual-ported memory zone.
m_ext2int() is relevant only to systems with multiple processors connected by dual-ported memory on a memory bus. Other users can disregard this call.
The argument ext_addr specifies the external address. The resultant internal address is returned in the location pointed to by int_addr. If the external address is within a dual-ported zone whose p-port is tied to the calling node, then the internal address will be different. In all other cases, the internal and external addresses will be the same.
This system call always returns 0.
None. Although m_ext2int() is primarily used in multiprocessor systems, its action is restricted to the local node.
m_int2ext - Convert an internal address to an external address
unsigned long m_int2ext(
void *int_addr, /* local reference */
void **ext_addr /* external reference */
)
When a node on a multiprocessor system passes an address that resides within a dual-ported zone, it first must convert the address by calling m_int2ext(). This call applies to systems with multiple processors that are connected by dual-ported memory on a memory bus.
The argument int_addr specifies the internal address. The resultant external address is returned in the location pointed to by ext_addr.
If the internal address is within a dual-ported zone whose p-port is tied to the calling node, the external address is different. In all other cases, the internal and external addresses are the same.
Be careful about structures that straddle the boundary of a dual-port zone because the structure's address range could contain a discontinuity.
None. Although used in multiprocessor systems, m_int2ext() executes on the local node.
pt_create - Create a memory partition of fixed-size buffers
#include <psos.h>
unsigned long pt_create(
char name[4], /* partition name */
void *paddr, /* partition physical addr. */
void *laddr, /* partition logical address */
unsigned long length, /* partition length in bytes */
unsigned long bsize, /* buffer size in bytes */
unsigned long flags, /* buffer attributes */
unsigned long *ptid, /* partition identifier */
unsigned long *nbuf /* number of buffers created */
)
This service call allows a task to create a new memory partition, from which fixed-sized memory buffers may be allocated for use by the application. The pSOS+ kernel takes a portion from the top of this region to use as its Partition Control Block.
The argument name specifies the user-assigned name for the new partition. The physical memory address of the partition is defined by paddr. The logical address of the partition generated after MMU-translation is defined by laddr; it is ignored on non-MMU systems. The total partition length, in bytes, is defined by length. The size of the buffers are defined by bsize, and must be a power of 2, and equal to or greater than 4.
The flags argument is formed by OR-ing the following symbolic constants (one from each pair), which are defined in <psos.h>.
The partition ID of the named partition is returned in the variable pointed to by ptid. The number of actual buffers in the partition is returned in the variable pointed to by nbuf.
This call returns 0 on success, or an error code on failure.
pt_delete - Delete a memory partition
#include <psos.h>
unsigned long pt_delete (
unsigned long ptid /* partition identifier */
)
This system call deletes the memory partition with the specified ptid. Unless the PT_DEL attribute was specified when the partition was created, pt_delete() will return an error if any buffers allocated from the partition have not been returned.
The calling task does not have to be the creator (parent) of the partition to be deleted. However, a partition must be deleted from the node on which it was created.
This system call returns 0 on success, or an error code on failure.
Once created, a partition is generally used by multiple tasks for data buffers, which may be passed around between tasks, or even between nodes. There is rarely a reason for deleting a partition, even when it is no longer used, except to allow reuse of memory occupied by the partition.
If ptid identifies a global partition, pt_delete will notify the master node so that the partition may be removed from its Global Object Table. Thus, deletion of a global partition always causes activity on the master node.
pt_getbuf - Get a buffer from a partition
#include <psos.h> unsigned long pt_getbuf( unsigned long ptid, /* partition identifier */ void **bufaddr /* starting address of buffer */ )
This system call gets a buffer from a partition. If the partition is empty, then an error will be returned.
The argument ptid specifies the partition identifier. The starting address of the allocated buffer is returned in the variable pointed to by bufaddr.
This system call returns 0 on success, or an error code on failure.
If the input ptid identifies a global partition residing on another processor node, then the pSOS+ kernel will internally make an RSC to that remote node to allocate the buffer.
pt_ident - Obtain the identifier of the named partition
unsigned long pt_ident(
char name[4], /* partition name */
unsigned long node, /* node selector */
unsigned long *ptid /* partition identifier */
)
This system call allows the calling task to obtain the partition ID of a memory partition it only knows by name. This partition ID may then be used in all other operations relating to the memory partition.
Most system calls, except pt_create() and pt_ident(), reference a partition by its partition ID. pt_create() returns the partition ID to the partition creator. For other tasks, one way to obtain the partition ID is to use pt_ident().
The argument name specifies the name of a partition whose ID is returned in the variable pointed to by ptid. The argument node is a node selector. In a single node system, this argument must be 0. For multiprocessor systems, see Multiprocessor Considerations.
This system call returns 0 on success, or an error code on failure.
| HEX | MNEMONIC | DESCRIPTION |
|---|---|---|
| 0x04 | ERR_NODENO | Node specifier out of range. |
| 0x09 | ERR_OBJNF | Named partition not found. |
pt_retbuf - Return a buffer to the partition from which it came
#include <psos.h>
unsigned long pt_retbuf(
unsigned long ptid, /* partition identifier */
void *bufaddr /* starting address of the buffer */
)
This system call returns a buffer to the partition from which it was allocated. Since the pSOS+ kernel does not keep track of buffer ownership, it is possible for one task to get a buffer, and another task to return it.
The argument ptid specifies the partition ID of the buffer to return. The argument bufaddr specifies the buffer's address.
This system call returns 0 on success, or an error code on failure.
If the input ptid identifies a global partition residing on another processor node, then the pSOS+ kernel will internally make an RSC to that remote node to return the buffer.
pt_sgetbuf - Return a buffer with its physical and logical addresses
#include <psos.h>
unsigned long pt_sgetbuf(
unsigned long ptid, /* partition identifier */
void **paddr, /* physical address */
void **laddr /* logical address */
)
This system call gets a buffer from a partition. If the partition is empty, then an error will be returned.
On MMU-based systems, both physical and logical addresses are returned to simplify transfer of buffers between Supervisor and User mode programs. In non-MMU systems, the logical address is the same as the physical address, this call functions the same as the pt_getbuf() call.
This service is available in the non-MMU versions of the pSOS+ kernel for the sole purpose of allowing software designed for MMU-based systems to run, unmodified, on systems without MMU.
The argument ptid specifies the buffer's partition ID. The physical and logical addresses of the buffer are returned in the variables pointed to by paddr and laddr respectively.
This system call returns 0 on success, or an error code on failure.
If the input argument ptid identifies a global partition on another processor node, the pSOS+ kernel internally makes an RSC to that remote node to allocate the buffer.
q_asend - (pSOS+m kernel only) Asynchronously post a message to a message queue
#include <psos.h>
unsigned long q_asend(
unsigned long qid, /* queue identifier */
unsigned long msg_buf[4] /* message buffer */
)
This system call functions the same as q_send() except that it executes asynchronously. Refer to the description of q_send() for further information. For a detailed description of asynchronous services, refer to the pSOSystem Systems Concept manual.
The argument qid specifies the queue ID of the target queue. The message to send is contained in the argument msg_buf.
When called in a system running the pSOS+m kernel this call always returns 0. The pSOS+ kernel (the single processor version) returns ERR_SSFN.
Should the call fail, if present, the node's MC_ASYNCERR routine is invoked and the following error codes may be reported:
If an MC_ASYNCERR routine is not provided, the pSOS+m kernel generates a fatal error.
q_aurgent - (pSOS+m kernel only) Asynchronously post a message at the head of a queue's message queue
#include <psos.h>
unsigned long q_aurgent(
unsigned long qid, /* queue identifier */
unsigned long msg_buf[4] /* message buffer */
)
This system call functions the same as the q_urgent() call except that it executes asynchronously. Refer to the description of q_urgent() for further information.
The argument qid specifies the queue ID of the target queue. The message to send is contained in the argument msg_buf.
When called in a system running the pSOS+m kernel, this call always returns 0. The pSOS+ kernel (the single processor version) returns ERR_SSFN.
Should the call fail, if present, the node's MC_ASYNCERR routine is invoked and the following error codes may be reported:
If an MC_ASYNCERR routine is not provided, the pSOS+m kernel generates a fatal error.
q_avsend - (pSOS+m kernel only) Asynchronously post a variable length message to a message queue
#include <psos.h>
unsigned long q_avsend(
unsigned long qid, /* queue identifier */
void *msg_buf, /* message buffer */
unsigned long msg_len, /* length of message */
)
This system call functions the same as the q_vsend() call except that it executes asynchronously. Refer to the description of q_vsend() for further information.
The argument qid specifies the queue ID of the target queue. The message to send is contained in the argument msg_buf. msg_len specifies the length of the message. It must not exceed the queue's maximum message length.
When called in a system running the pSOS+m kernel, this call always returns 0. The pSOS+ kernel (the single processor version) returns ERR_SSFN.
Should the call fail, if present, the node's MC_ASYNCERR routine is invoked and the following error codes may be reported:
If an MC_ASYNCERR routine is not provided, the pSOS+m kernel generates a fatal error.
q_avurgent - (pSOS+m kernel only) Post a variable length message at the head of a message queue
#include <psos.h>
unsigned long q_avurgent(
unsigned long qid, /* queue identifier */
void *msg_buf, /* message buffer */
unsigned long msg_len, /* length of message */
)
This system call functions the same as q_vurgent except that q_avurgent executes asynchronously. Refer to the description of q_vurgent for further information. For a more detailed description of asynchronous services, refer to the pSOSystem System Concepts manual.
The argument qid identifies the queue. The argument msg_buf defines the message to send. The argument msg_len specifies the length of the message.
When called in system running pSOS+m, this call always returns 0. The pSOS+m kernel (the single processor version) returns ERR_SSFN.
The following error codes may be reported if a q_avurgent() call fails and the node's MC_ASYNCERR routine (if present) is invoked:
If an MC_ASYNCERR routine is not present, the pSOS+m kernel generates a fatal error.
q_broadcast - Broadcast identical messages to a message queue
#include <psos.h>
unsigned long q_broadcast(
unsigned long qid, /* queue identifier */
unsigned long msg_buf[4], /* msg. of 4 long words */
unsigned long *count /* # tasks receiving msg. */
)
This system call allows the caller to wake up all tasks that might be waiting at an ordinary message queue. If the task queue is empty, this call does nothing. If one or more tasks are waiting at the queue, q_broadcast() gives a copy of the input message to each such task and makes it ready to run. After a q_broadcast() call, no tasks will be waiting to receive a message from the specified queue.
The argument qid specifies the queue ID of the target queue. The argument msg_buf contains the message to send. The number of tasks readied by the broadcast is returned in the location pointed to by count.
This system call returns 0 on success, or an error code on failure.
q_create - Create a message queue
#include <psos.h>
unsigned long q_create(
char name[4], /* queue name */
unsigned long count, /* queue size */
unsigned long flags, /* queue attributes */
unsigned long *qid /* queue identifier */
)
This system call creates an ordinary message queue by allocating and initializing a Queue Control Block (QCB) according to the specifications supplied with the call.
Like all objects, a queue has a user-assigned name, and a pSOS-assigned queue ID returned by q_create(). Several flag bits specify the characteristics of the message queue. Tasks can wait for messages either by task priority or strictly FIFO, and a limit can be optionally set on the maximum number of messages that can be simultaneously posted at the queue.
The argument name specifies the user-assigned name of the new message queue. The flags argument is formed by OR-ing the following symbolic constants (one from each pair), which are defined in <psos.h>.
If Q_LIMIT is set, then the count argument specifies the maximum number of messages that can be simultaneously posted at the queue. If Q_PRIBUF is also set, then the argument count also specifies the number of buffers set aside from the system-wide pool of message buffers for the private use of this queue. If Q_NOLIMIT is set, count is ignored. The queue ID of the named queue is returned in the variable pointed to by qid.
This system call returns 0 on success, or an error code on failure.
q_delete - Delete a message queue
#include <psos.h> unsigned long q_delete( unsigned long qid /* queue identifier */ )
This system call deletes the ordinary message queue with the specified queue ID, and frees the QCB. q_delete() take cares of cleaning up the queue. If there are tasks waiting, they will be unblocked and given an error code. If some messages are queued there, the message buffers, along with any free private buffers are returned to the system-wide pool.
The calling task does not have to be the creator of the queue in order to be deleted. However, a queue must be deleted from the node on which it was created. The argument qid specifies the queue ID of the queue to delete.
This system call returns 0 on success, or an error code on failure.
If qid identifies a global queue, q_delete will notify the master node so that the queue may be removed from its Global Object Table. Thus, deletion of a global queue always causes activity on the master node.
q_ident - Obtain the identifier of the named message queue
#include <psos.h>
unsigned long q_ident(
char name[4], /* queue name */
unsigned long node, /* node selector */
unsigned long *qid /* queue identifier */
)
The intended purpose of this system call is to allow the calling task to obtain the queue ID of an ordinary message queue. However, since a variable length message queue is just a special type of message queue, q_ident() and q_vident() are functionally identical. Both return the queue ID of the first queue encountered with the specified name, whether it be ordinary or variable length.
Most system calls, except q_create()/q_vcreate() and q_ident()/q_vident(), reference a queue by its queue ID. For other tasks, one way to obtain the queue ID is to use q_ident()/q_vident(). Once obtained, the queue ID may then be used in all other operations relating to this queue.
The argument name specifies the name of the message queue whose ID is returned in the variable pointed to by qid. The argument node is a node selector. In a single node system, this argument must be 0. For multiprocessor systems, see Multiprocessor Considerations.
The system call returns 0 on success, or an error code on failure.
| HEX | MNEMONIC | DESCRIPTION |
|---|---|---|
| 0x04 | ERR_NODENO | Node specifier out of range. |
| 0x09 | ERR_OBJNF | Named queue not found. |
q_receive - Request a message from a message queue
#include <psos.h>
unsigned long q_receive(
unsigned long qid, /* queue identifier */
unsigned long flags, /* queue attributes */
unsigned long timeout, /* timeout in clock ticks */
unsigned long msg_buf[4] /* message buffer */
)
This system call allows a task or an ISR to obtain a message from an ordinary message queue.
The argument qid specifies the queue ID of the target queue. The argument flags specifies whether q_receive() will block waiting for a message. It should have one of the following values (defined in <psos.h>):
The argument timeout specifies a timeout interval, in units of clock ticks. If the queue is non-empty, this call always returns the first message there. If the queue is empty and the caller specified Q_NOWAIT, then q_receive() returns with an error code. If Q_WAIT is elected, the caller will be blocked until a message is posted to the queue, or if the timeout argument is used, until the timeout occurs whichever happens first. If timeout is zero and Q_WAIT is selected, then q_receive() will wait forever. The timeout argument is ignored if Q_NOWAIT is selected. The message received is returned in msg_buf.
This system call returns 0 on success, or an error code on failure.
If qid identifies a global queue residing on another processor node, the local kernel will internally make an RSC to that remote node to request a message from that queue. If the Q_WAIT attribute is elected, then the pSOS+m kernel on the target node must use an agent to wait for the message. If that node is temporarily out of agents, the call will fail. The number of agents on each node is defined by the mc_nagent entry in the Multiprocessor Configuration Table.
CALLABLE FROM ISR
q_send - Post a message to a message queue
#include <psos.h>
unsigned long q_send(
unsigned long qid, /* queue identifier */
unsigned long msg_buf[4] /* message buffer */
)
This system call is used to send a message to a specified ordinary message queue. If a task is already waiting at the queue, the message is passed to that task, which is then unblocked and made ready to run. If no task is waiting, the input message is copied into a message buffer from the system pool or, if the queue has private buffers, into a private message buffer, which is then put in the message queue behind any messages already posted to the queue.
The argument qid specifies the queue ID of the target queue. The message to send is contained in the argument msg_buf.
This system call returns 0 on success, or an error code on failure.
q_urgent - Post a message at the head of a message queue
#include <psos.h>
unsigned long q_urgent(
unsigned long qid, /* queue identifier */
unsigned long msg_buf[4] /* message buffer */
)
This system call is identical in all respects to q_send() with one and only one exception: if one or more messages are already posted at the target queue, then the new message will be inserted into the message queue in front of all such queued messages.
The argument qid specifies the queue ID of the target queue. The message to send is defined in the argument msg_buf.
This system call returns 0 on success, or an error code on failure.