mirror of
https://github.com/VincentWei/MiniGUI.git
synced 2025-12-15 00:45:35 +08:00
921 lines
40 KiB
C
921 lines
40 KiB
C
///////////////////////////////////////////////////////////////////////////////
|
||
//
|
||
// IMPORTANT NOTICE
|
||
//
|
||
// The following open source license statement does not apply to any
|
||
// entity in the Exception List published by FMSoft.
|
||
//
|
||
// For more information, please visit:
|
||
//
|
||
// https://www.fmsoft.cn/exception-list
|
||
//
|
||
//////////////////////////////////////////////////////////////////////////////
|
||
/**
|
||
* \file psos.h
|
||
* \author Wei Yongming <vincent@minigui.org>
|
||
* \date 2007/05/28
|
||
*
|
||
* \brief This header contains the declaration of pSOS+ system calls, the definition
|
||
* of related structures, and the error codes.
|
||
*
|
||
\verbatim
|
||
|
||
This file is part of MiniGUI, a mature cross-platform windowing
|
||
and Graphics User Interface (GUI) support system for embedded systems
|
||
and smart IoT devices.
|
||
|
||
Copyright (C) 2008~2020, Beijing FMSoft Technologies Co., Ltd.
|
||
|
||
This program is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
This program is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU General Public License for more details.
|
||
|
||
You should have received a copy of the GNU General Public License
|
||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||
|
||
Or,
|
||
|
||
As this program is a library, any link to this program must follow
|
||
GNU General Public License version 3 (GPLv3). If you cannot accept
|
||
GPLv3, you need to be licensed from FMSoft.
|
||
|
||
If you have got a commercial license of this program, please use it
|
||
under the terms and conditions of the commercial license.
|
||
|
||
For more information about the commercial license, please refer to
|
||
<http://www.minigui.com/blog/minigui-licensing-policy/>.
|
||
|
||
\endverbatim
|
||
*/
|
||
|
||
/*
|
||
* $Id: psos.h 7183 2007-05-16 08:19:34Z weiym $
|
||
*
|
||
* MiniGUI for Linux/uClinux, eCos, uC/OS-II, VxWorks,
|
||
* pSOS, ThreadX, NuCleus, OSE, and Win32.
|
||
*/
|
||
|
||
#ifndef _PSOS_H
|
||
#define _PSOS_H
|
||
|
||
#ifdef __cplusplus
|
||
extern "C" {
|
||
#endif /* __cplusplus */
|
||
|
||
/* Timed out; returned only if a timeout was requested. */
|
||
#define ERR_TIMEOUT 0x01
|
||
/* Illegal system service function number. */
|
||
#define ERR_SSFN 0x03
|
||
/* Node specifier out of range. */
|
||
#define ERR_NODENO 0x04
|
||
/* object has been deleted. */
|
||
#define ERR_OBJDEL 0x05
|
||
/* object_id is incorrect; failed validity check */
|
||
#define ERR_OBJID 0x06
|
||
/* object type doesn't match object ID; failed validity check.*/
|
||
#define ERR_OBJTYPE 0x07
|
||
/* Node's object table full. */
|
||
#define ERR_OBJTFULL 0x08
|
||
/* Named object not found. */
|
||
#define ERR_OBJNF 0x09
|
||
/* Informative; files may be corrupted on restart. */
|
||
#define ERR_RSTFS 0x0D
|
||
/* Exceeds node's maximum number of tasks. */
|
||
#define ERR_NOTCB 0x0E
|
||
/* Insufficient space in Region 0 to create stack. */
|
||
#define ERR_NOSTK 0x0F
|
||
/* Stack too small. */
|
||
#define ERR_TINYSTK 0x10
|
||
/* Priority out of range. For mu, the MU_PRIO_PROTECT flag has been specified.
|
||
* The priority must be more than 0 and less than 256. */
|
||
#define ERR_PRIOR 0x11
|
||
/* Task already started. */
|
||
#define ERR_ACTIVE 0x12
|
||
/* Cannot restart; this task never was started. */
|
||
#define ERR_NACTIVE 0x13
|
||
/* Task already suspended. */
|
||
#define ERR_SUSP 0x14
|
||
/* The task was not suspended. */
|
||
#define ERR_NOTSUSP 0x15
|
||
/* Cannot change priority; new priority out of range. */
|
||
#define ERR_SETPRI 0x16
|
||
/* Register number out of range. */
|
||
#define ERR_REGNUM 0x17
|
||
/* pHILE+ resources in use. */
|
||
#define ERR_DELFS 0x18
|
||
/* pREPC+ resources in use. */
|
||
#define ERR_DELLC 0x19
|
||
/* pNA+ resources in use. */
|
||
#define ERR_DELNS 0x1A
|
||
|
||
/* error cods for region manager are omitted ... */
|
||
/* error cods for partition manager are omitted ... */
|
||
|
||
/* Could not send a notification event. Error occurred while sending notification of message availability. */
|
||
#define ERR_NOTIFY 0x3D
|
||
/* Exceeds node's maximum number of semaphores. */
|
||
#define ERR_NOSCB 0x41
|
||
/* No semaphore: this error code returns only if SM_NOWAIT was selected. */
|
||
#define ERR_NOSEM 0x42
|
||
/* Semaphore deleted while task waiting. */
|
||
#define ERR_SKILLD 0x43
|
||
/* Informative only; there were sm_delete tasks waiting. */
|
||
#define ERR_TATSDEL 0x44
|
||
/* Maximum number of tokens are already available for a semaphore that was created with the SM_BOUNDED flag. */
|
||
#define ERR_BOUND 0x45
|
||
/* ZERO bound count is invalid. */
|
||
#define ERR_INVBOUND 0x46
|
||
|
||
/* error cods for timer are omitted ... */
|
||
|
||
/* object not created from this node. */
|
||
#define ERR_ILLRSC 0x53
|
||
/* Cannot wait; the remote node is out of Agents. */
|
||
#define ERR_NOAGNT 0x54
|
||
/* object does not exist any more. */
|
||
#define ERR_STALEID 0x65
|
||
/* Remote node is no longer in service. */
|
||
#define ERR_NDKLD 0x66
|
||
/* Exceeds node's maximum number of mutexes. */
|
||
#define ERR_NOMUCB 0x70
|
||
/* The MU_GLOBAL flag cannot be specified with the MU_PRIO_INHERIT flag. */
|
||
#define ERR_NOGLOBAL 0x71
|
||
/* Informative only: there were tasks waiting. */
|
||
#define ERR_TATMUDEL 0x72
|
||
/* The mutex is not owned by the calling task. */
|
||
#define ERR_NOTOWNED 0x73
|
||
/* The mutex is already locked by the calling task and it was created with MU_NORECURSIVE flag. */
|
||
#define ERR_NORECURSIVE 0x74
|
||
/* Some other task has already locked the mutex; this error is returned only if MU_NOWAIT flag has been specified. */
|
||
#define ERR_MULOCKED 0x75
|
||
/* Mutex deleted while the task was waiting on it. */
|
||
#define ERR_MUKILLED 0x76
|
||
/* MU_FIFO flag cannot be specified with MU_PRIO_INHERIT or MU_PRIO_PROTECT. */
|
||
#define ERR_NOFIFO 0x77
|
||
/* Task was created with T_NORELMU flag set and currently owns some mutexes. */
|
||
#define ERR_OWNMUTX 0x79
|
||
/* Task<73><6B>s current priority exceedsthe ceiling priority of the guarding mutex. */
|
||
#define ERR_OUTCEIL 0x7A
|
||
/* Expected mutex object; failed validity. The mutex is not of priority protected type. */
|
||
#define ERR_MUTYPE 0x8A
|
||
|
||
/* other error cods are omitted ... */
|
||
|
||
/* system calls for ASR management */
|
||
#define T_PREEMPT 0x00000001 /* ASR is preemptible. */
|
||
#define T_NOPREEMPT 0x00000002 /* ASR is non-preemptible. */
|
||
#define T_TSLICE 0x00000010 /* ASR can be time-sliced. */
|
||
#define T_NOTSLICE 0x00000020 /* ASR cannot be time-sliced. */
|
||
#define T_ASR 0x00000100 /* ASR nesting enabled. */
|
||
#define T_NOASR 0x00000200 /* ASR nesting disabled. */
|
||
#define T_USER 0x00001000 /* ASR runs in user mode. */
|
||
#define T_SUPV 0x00002000 /* ASR runs in supervisor mode. */
|
||
#define T_ISR 0x00010000 /* Interrupts are enabled while ASR runs. */
|
||
#define T_NOISR 0x00020000 /* Interrupts are disabled while ASR runs. */
|
||
|
||
/*
|
||
* 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
|
||
* (for example, Non-preemptible, Time-slicing enabled, 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.
|
||
*
|
||
* as_catch() replaces any previous ASR for the calling task. Therefore, a
|
||
* task can have only one ASR at any time. An ASR must exit using the
|
||
* as_return() system call.
|
||
*/
|
||
unsigned long as_catch (
|
||
void (* start_addr) (unsigned long), /* ASR address */
|
||
unsigned long mode /* ASR attributes */
|
||
);
|
||
|
||
/*
|
||
* This system call registers a set of bit-encoded events for the calling
|
||
* task that are used to notify the posting of asynchronous signals to
|
||
* the task. The event notification mechanism provides a way for a task to
|
||
* synchronously wait for asynchronous signals via an ev_receive() call.
|
||
*/
|
||
unsigned long as_notify (
|
||
unsigned long events /* bit-encoded events */
|
||
);
|
||
|
||
/*
|
||
* 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 enable the pSOS+ kernel to restore the task to its state before
|
||
* the ASR. as_return() cannot be called except from an ASR.
|
||
*/
|
||
unsigned long as_return (void);
|
||
|
||
/*
|
||
* This system call sends asynchronous signals to a task. Additionally,
|
||
* if signal notification via event has been requested, the notification
|
||
* events are also posted to the 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 an interrupt, which is 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. These signals are encoded bit-wise in a single
|
||
* long word.
|
||
*
|
||
* 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.
|
||
*/
|
||
unsigned long as_send (
|
||
unsigned long tid, /* target task ID */
|
||
unsigned long signals /* bit-encoded signal list */
|
||
);
|
||
|
||
/* system calls for task management */
|
||
|
||
/*
|
||
* This system call adds a task variable to a task. t_addvar() allocates to the specified
|
||
* task a storage area which is used to hold a private copy of the specified variable.
|
||
*/
|
||
unsigned long t_addvar (
|
||
unsigned long tid, /* task identifier */
|
||
void **tv_addr, /* address of variable */
|
||
void *tv_value /* initial value for task variable */
|
||
);
|
||
|
||
#define T_GLOBAL 0x0001
|
||
#define T_LOCAL 0x0002
|
||
#define T_FPU 0x0010
|
||
#define T_NOFPU 0x0020
|
||
|
||
|
||
/*
|
||
* This service call enables a task to create a new task. t_create() allocates to the
|
||
* new task a Task Control Block (TCB) and a memory segment for its stack(s). The
|
||
* task stack sizes and scheduling priority are established with this call. t_create()
|
||
* leaves the new task in a dormant state; the t_start() call must be used to place
|
||
* the task into the ready state for execution.
|
||
*/
|
||
unsigned long t_create (
|
||
char name[4], /* task name */
|
||
unsigned long prio, /* task priority */
|
||
unsigned long sstack, /* task supervisor stack size */
|
||
unsigned long ustack, /* task user stack size */
|
||
unsigned long flags, /* task attributes */
|
||
unsigned long *tid /* task identifier */
|
||
);
|
||
|
||
/*
|
||
* This service call enables a task to delete itself or another task. The pSOS+ kernel
|
||
* first dispatches any task deletion callouts, registered via the co_register() pSOS+
|
||
* service, in the reverse order of registration. When all of the deletion callouts have
|
||
* finished, the pSOS+ kernel halts the task and reclaims its TCB, stack segment and
|
||
* any allocated timers.
|
||
* The calling task does not have to be the creator (parent) of the task to be deleted.
|
||
* However, a task must be deleted from the node on which it was created.
|
||
*/
|
||
unsigned long t_delete (
|
||
unsigned long tid /* task identifier */
|
||
);
|
||
|
||
/*
|
||
* This system call removes a task variable from a task. t_delvar() deallocates the
|
||
* private storage allocated for the task variable.
|
||
*/
|
||
unsigned long t_delvar (
|
||
unsigned long tid, /* task identifier */
|
||
void **tv_addr /* address of variable*/
|
||
);
|
||
|
||
/*
|
||
* This system call enables the caller to obtain the contents of a task's notepad register.
|
||
* Each task has 16 such software registers, held in the task's TCB. The purpose
|
||
* of these registers is to furnish every task with a set of named, permanent variables.
|
||
* Eight of these registers are reserved for system use. Eight are free to be used for application
|
||
* specific purposes.
|
||
*/
|
||
unsigned long t_getreg (
|
||
unsigned long tid, /* task identifier */
|
||
unsigned long regnum, /* register number */
|
||
unsigned long *reg_value /* register contents */
|
||
);
|
||
|
||
/*
|
||
* This system call enables the calling task to obtain the task ID of a task it knows only
|
||
* by name. This task ID can then be used in all other operations relating to the task.
|
||
* Most system calls, except t_create() and t_ident(), reference a task by its task
|
||
* ID. t_create() returns the task ID to a task's creator. For other tasks, one way to
|
||
* obtain the task ID is to use t_ident().
|
||
*/
|
||
unsigned long t_ident (
|
||
char name[4], /* task name */
|
||
unsigned long node, /* node number */
|
||
unsigned long *tid /* task ID */
|
||
);
|
||
|
||
#define TS_DEBUG 0x8000 /* Blocked by debugger */
|
||
#define TS_SUSP 0x4000 /* Suspended */
|
||
#define TS_TIMING 0x1000 /* Being timed */
|
||
#define TS_PAUSE 0x0800 /* Task paused */
|
||
#define TS_ABSTIME 0x0400 /* Timed for absolute time */
|
||
#define TS_VWAIT 0x0200 /* Waiting for events */
|
||
#define TS_SWAIT 0x0080 /* Waiting for semaphore */
|
||
#define TS_MWAIT 0x0040 /* Waiting for memory */
|
||
#define TS_QWAIT 0x0020 /* Waiting for message */
|
||
#define TS_RWAIT 0x0010 /* Waiting for reply packet */
|
||
#define TS_MUWAIT 0x0008 /* Waiting for mutex */
|
||
#define TS_CVWAIT 0x0004 /* Waiting for condition variable */
|
||
#define TS_CWAIT 0x0001 /* Waiting for component resource */
|
||
#define TS_READY 0x0000 /* Task is in Ready State */
|
||
|
||
struct tinfo {
|
||
char name[4]; /* Task name */
|
||
unsigned long flags; /* Task attributes */
|
||
void (*iip)(void); /* Task's initial starting addr. */
|
||
unsigned long next; /* ID of the next waiting task */
|
||
unsigned short status; /* Task status.*/
|
||
unsigned char cpriority; /* Task's current priority.*/
|
||
unsigned char bpriority; /* Task's base priority */
|
||
unsigned char ipriority; /* Task's initial priority */
|
||
unsigned char evwantcond; /* Task's event wait condition */
|
||
unsigned short mode; /* Task's current mode.*/
|
||
unsigned short imode; /* Task's initial mode */
|
||
unsigned short amode; /* Task's ASR mode.*/
|
||
unsigned long tslice_quantum; /* Per task's time slice in ticks*/
|
||
long tslice_remain; /* Remainder time slice in ticks.*/
|
||
unsigned long wtobid; /* Object where task is blocked */
|
||
unsigned long evwait; /* Events - task waiting for.*/
|
||
unsigned long evcaught; /* Events caught */
|
||
unsigned long evrcvd; /* Events received */
|
||
unsigned long ss_size; /* Supervisor stack size */
|
||
unsigned long us_size; /* User stack size */
|
||
unsigned long *ssp; /* Current supervisor stack */
|
||
/* pointer */
|
||
unsigned long *issp; /* Initial supervisor stack pointer */
|
||
unsigned long *usp; /* Current user stack pointer */
|
||
unsigned long *iusp; /* Initial user stack pointer */
|
||
unsigned long imask; /* Interrupt priority level */
|
||
void (*asr_addr)(void); /* Task's ASR address */
|
||
unsigned long signal; /* Asynchronous signals pending */
|
||
unsigned long xdate; /* Timer expiry date */
|
||
unsigned long xtime; /* Timer expiry time */
|
||
unsigned long xticks; /* Timer expiry ticks */
|
||
unsigned long nrnunits; /* No. of region units wanted */
|
||
void **tsdp; /* Task_specific_Data pointer */
|
||
unsigned long co_toproc; /* Callouts to process */
|
||
unsigned long co_inprog; /* Callouts in progress */
|
||
unsigned long evasr_ntfy; /* ev used for ASR notification */
|
||
};
|
||
|
||
/*
|
||
* This system call returns information of a specified task. The information includes
|
||
* the static information that was specified at object creation time and certain internal
|
||
* state information which is not static.
|
||
*/
|
||
unsigned long t_info (
|
||
unsigned long tid, /* Task ID */
|
||
struct tinfo *buf /* Object Information buffer */
|
||
);
|
||
|
||
#if 0
|
||
#define T_PREEMPT 0x0001 /* Task is preemptible. */
|
||
#define T_NOPREEMPT 0x0002 /* Task is non-preemptible. */
|
||
#define T_TSLICE 0x0004 /* Task can be time-sliced. */
|
||
#define T_NOTSLICE 0x0008 /* Task cannot be time-sliced. */
|
||
#define T_ASR 0x0010 /* Task's ASR is enabled. */
|
||
#define T_NOASR 0x0020 /* Task's ASR is disabled. */
|
||
#define T_USER 0X0040 /* Task runs in user mode. */
|
||
#define T_SUPV 0x0080 /* Task runs in supervisor mode. */
|
||
#define T_ISR 0x0100 /* Hardware interrupts are enabled while the task runs. */
|
||
#define T_NOISR 0x0200 /* Hardware interrupts are disabled while the task runs. */
|
||
#endif
|
||
|
||
/*
|
||
* This system call enables a task to modify certain execution mode fields. These are
|
||
* preemption on/off, roundrobin on/off, asynchronous signal handling on/off, and
|
||
* interrupt control.
|
||
* Preemption has precedence over timeslicing. Therefore, if preemption is off, timeslicing
|
||
* does not occur whether or not it is set.
|
||
* The calling task can be preempted as a result of this call, if its preemptibility is
|
||
* turned from off to on and a higher priority task is ready to run.
|
||
* To obtain a task's current execution mode without changing it, use a mask of 0.
|
||
*/
|
||
unsigned long t_mode (
|
||
unsigned long mask, /* attributes to be changed */
|
||
unsigned long new_mode, /* new attributes */
|
||
unsigned long *old_mode /* prior mode */
|
||
);
|
||
|
||
/*
|
||
* This system call forces a task to resume execution at its original start address regardless
|
||
* of its current state or place of execution. If the task was blocked, the
|
||
* pSOS+ kernel forcibly unblocks it. The task's priority and stacks are set to the original
|
||
* values that t_create() specified. Its start address and execution mode are reset
|
||
* to the original values established by t_start(). Any pending events, signals, or
|
||
* armed timers are cleared. Thereafter, pSOS+ posts any "task restart callouts" that
|
||
* are dispatched in the order they were registered when the task is scheduled to run.
|
||
* All of the "task restart callouts" so dispatched run to completion before the task regains
|
||
* control at its starting address.
|
||
* The t_restart() call accepts a new set of up to four arguments, which, among
|
||
* other things, can be used by the task to distinguish between the initial startup and
|
||
* subsequent restarts.
|
||
* The calling task does not have to be the creator (or parent) of the task it restarts.
|
||
* However, a task must be restarted from the node on which it was created.
|
||
*/
|
||
unsigned long t_restart (
|
||
unsigned long tid, /* task identifier */
|
||
unsigned long targs[4] /* startup arguments */
|
||
);
|
||
|
||
/*
|
||
* This system call removes the suspension of a task. If the task was suspended while
|
||
* in the ready state, t_resume() releases it to be scheduled for execution. If the task
|
||
* was both suspended and blocked (for example, waiting for a message), t_resume()
|
||
* removes only the suspension. This leaves the task in the blocked state.
|
||
*/
|
||
unsigned long t_resume (
|
||
unsigned long tid /* task identifier */
|
||
);
|
||
|
||
/*
|
||
* This system call enables the calling task to optionally obtain and modify either its
|
||
* own or another task's base scheduling (software) priority. If oldprio is a non-NULL
|
||
* address, the previous base scheduling priority is returned in the variable pointed to
|
||
* by oldprio, regardless of the task's current priority. If the calling task issues
|
||
* t_setpri() for a target task (self or another) with a valid non-0 value of newprio,
|
||
* then the target task (whether it is running or not running) shall resume execution
|
||
* after all other runnable tasks of equal or greater priority have been scheduled to
|
||
* run.
|
||
*/
|
||
unsigned long t_setpri (
|
||
unsigned long tid, /* task identifier */
|
||
unsigned long newprio, /* new priority */
|
||
unsigned long *oldprio /* previous priority */
|
||
);
|
||
|
||
/*
|
||
* This system call enables the caller to modify the contents of a task's notepad register.
|
||
* Each task has 16 such software registers, held in the task's TCB. The purpose
|
||
* of these registers is to furnish every task with a set of named, permanent variables.
|
||
* Eight of these registers are reserved for system use, and eight are free to be used for
|
||
* application-specific purposes.
|
||
*/
|
||
unsigned long t_setreg (
|
||
unsigned long tid, /* task identifier */
|
||
unsigned long regnum, /* register number */
|
||
unsigned long reg_value /* register value */
|
||
);
|
||
|
||
/*
|
||
* This system call places a newly created task into the ready state to await scheduling
|
||
* for execution. Thereafter, pSOS+ posts any "task startup callouts" that are dispatched
|
||
* in the order they were registered when the task is scheduled to run. All of
|
||
* the "task startup callouts" so dispatched run to completion before the task regains
|
||
* control at its starting address. The calling task does not have to be the creator (or
|
||
* parent) of the task to be started. However, a task must be started from the node on
|
||
* which it was created.
|
||
*/
|
||
unsigned long t_start (
|
||
unsigned long tid, /* task identifier */
|
||
unsigned long mode, /* initial task attributes */
|
||
void (*start_addr) (unsigned long), /* task address */
|
||
unsigned long targs[4] /* startup task arguments */
|
||
);
|
||
|
||
/*
|
||
* This system call suspends execution of a task until a t_resume() call is made for
|
||
* the suspended task. The calling task suspends either itself or another task. The
|
||
* t_suspend() call prevents the specified task from contending for CPU time but
|
||
* does not directly prevent contention for any other resource.
|
||
*/
|
||
unsigned long t_suspend (
|
||
unsigned long tid /* task identifier */
|
||
);
|
||
|
||
/*
|
||
* This system call enables the calling task to obtain and optionally modify its own or
|
||
* another task's timeslice quantum. It allows applications to control how much execution
|
||
* time is distributed among tasks with the same priority. It also returns the previous
|
||
* timeslice quantum.
|
||
*/
|
||
unsigned long t_tslice (
|
||
unsigned long tid, /* task identifier */
|
||
unsigned long new_tslice, /* new timeslice value*/
|
||
unsigned long *old_tslice /* old timeslice value */
|
||
);
|
||
|
||
|
||
/* system calls for mutext */
|
||
|
||
#define MU_GLOBAL 0x0001 /* Mutex is globally addressable by other nodes of a multiprocessor system. The single-processor version of the pSOS+ kernel ignores MU_GLOBAL. */
|
||
#define MU_LOCAL 0x0002 /* Mutex can be addressed only by the local node where it was created. */
|
||
#define MU_RECURSIVE 0x0004 /* Mutex can be acquired in a recursive fashion. */
|
||
#define MU_NORECURSIVE 0x0008 /* Mutex cannot be acquired in a recursive fashion. */
|
||
#define MU_FIFO 0x0010 /* The waiting tasks are queued in the FIFO order. This flag can be specified with MU_PRIO_NONE flag, but not with MU_PRIO_INHERIT or MU_PRIO_PROTECT. */
|
||
#define MU_PRIOR 0x0020 /* The waiting tasks are queued in decreasing order of their current priority. */
|
||
#define MU_PRIO_NONE 0x0100 /* Mutex does not protect against unbounded priority inversion. */
|
||
#define MU_PRIO_INHERIT 0x0200 /* Mutex uses the priority inheritance protocol to prevent unbounded priority inversion. */
|
||
#define MU_PRIO_PROTECT 0x0400 /* Mutex uses the priority protect protocol to prevent unbounded priority inversion. */
|
||
|
||
/*
|
||
* This system call creates a mutex and initializes it according to the specifications
|
||
* supplied with the call.
|
||
*/
|
||
unsigned long mu_create (
|
||
char name[4], /* user assigned name */
|
||
unsigned long flags, /* mutex attributes */
|
||
unsigned long ceiling, /* ceiling priority */
|
||
unsigned long *muid /* newly created mutex id */
|
||
);
|
||
|
||
/*
|
||
* This system call deletes a mutex with the specified mutex ID and frees the associated
|
||
* kernel resources. This call can be made only from the node where the specified
|
||
* mutex was created.
|
||
* The mu_delete() system call can be invoked by any task, and not necessarily the
|
||
* task that originally created the mutex. In the event that there are other tasks waiting
|
||
* to acquire that mutex, the tasks are unblocked and an error code is returned to
|
||
* them.
|
||
*/
|
||
unsigned long mu_delete (
|
||
unsigned long muid /* MUTEX identifier */
|
||
);
|
||
|
||
/*
|
||
* This system call enables the calling task to obtain the mutex ID of a mutex it only
|
||
* knows by name. This mutex ID can be used in all other operations relating to the
|
||
* mutex.
|
||
* The pSOS+ kernel does not check for duplicate names. If multiple mutexes with the
|
||
* same name exist, either on the local node, or on a remote note in a multi-processor
|
||
* system, a mu_ident() call may return the ID of any one mutex with the specified
|
||
* name. It can't be ascertained which ID is returned, though, to a certain extent it depends
|
||
* on the standard search order followed by pSOS+ kernel, as defined in the
|
||
* pSOSystem System Concepts manual.
|
||
*/
|
||
unsigned long mu_ident (
|
||
char name[4], /* mutex name */
|
||
unsigned long node, /* node number */
|
||
unsigned long *muid /* mutex identifier */
|
||
);
|
||
|
||
struct muinfo {
|
||
char name[4]; /* Name of the Mutex */
|
||
unsigned long flags; /* Mutex attributes */
|
||
unsigned long wqlen; /* No. of waiting tasks */
|
||
unsigned long wtid;/* ID of the first waiting task */
|
||
unsigned long count; /* Mutex reference count */
|
||
unsigned long ownid; /* ID of mutex owner */
|
||
unsigned long node; /* Owner task's node number */
|
||
unsigned long ceilprio; /* ceiling priority for MU_PROTECT mutexes */
|
||
unsigned long phpwt; /* Highest of all waiting task priorities */
|
||
};
|
||
|
||
/*
|
||
* This system call provides information of a specified Mutex object. The information
|
||
* includes the static information that was specified at object creation time and certain
|
||
* internal state information which is not static.
|
||
*/
|
||
unsigned long mu_info (
|
||
unsigned long muid, /* Mutex ID */
|
||
struct muinfo *buf /* Object Information buffer */
|
||
);
|
||
|
||
#define MU_WAIT 0x01 /* If the mutex is locked, block until it is available. */
|
||
#define MU_NOWAIT 0x02 /* Return with error if the mutex is locked. */
|
||
|
||
/*
|
||
* This system call allows a task to lock a mutex specified by the muid argument. If the
|
||
* mutex is not locked by another task, the mutex is put in the locked state, and the
|
||
* calling task becomes the owner of the mutex. If the mutex was created with the
|
||
* MU_RECURSIVE attribute set (see mu_create on page 2-87), a task can invoke
|
||
* mu_lock() multiple times to acquire the same mutex in a recursive fashion. The
|
||
* same number of mu_unlock() calls must then be made by the same task to release
|
||
* the mutex. A mutex created with the MU_NORECURSIVE flag can be locked only once
|
||
* by any task. If the task calls mu_lock again while it is holding the mutex, the call
|
||
* will return with an error.
|
||
* If the mutex is locked by another task then, depending on the flags argument, the
|
||
* calling task is either put in the blocked state and is queued in the wait queue associated
|
||
* with the mutex, or an error is returned.
|
||
*/
|
||
unsigned long mu_lock (
|
||
unsigned long muid, /* mutex identifier */
|
||
unsigned long flags, /* call attributes */
|
||
unsigned long timeout /* timeout interval */
|
||
);
|
||
|
||
/*
|
||
* This system call enables the calling task to optionally obtain and modify a mutex's
|
||
* ceiling priority. The call only operates on mutexes that have been created with the
|
||
* MU_PRIO_PROTECT flag. If oldprio is a non-NULL address, the previous ceiling priority
|
||
* is returned in the variable pointed to by oldprio.
|
||
* The mu_setceil() call either locks the mutex if it is unlocked, or blocks until it
|
||
* can successfully lock the mutex; then it changes the priority ceiling of the mutex
|
||
* and releases the mutex. If the calling task already owns the mutex when it invokes
|
||
* the mu_setceil() call with a valid non-0 value of newprio, then the task's current
|
||
* priority may change according to the priority protect protocol.
|
||
*/
|
||
unsigned long mu_setceil (
|
||
unsigned long muid, /* mutex identifier */
|
||
unsigned long newprio, /* new ceiling priority */
|
||
unsigned long *oldprio /* previous ceiling priority */
|
||
);
|
||
|
||
/*
|
||
* This system call allows a task to unlock a mutex specified by the muid argument. If
|
||
* the caller currently owns the mutex then mu_unlock() call decreases the recursive
|
||
* level associated with the mutex. If the recursive level reaches zero, the mutex is unlocked
|
||
* and the calling task loses ownership of the mutex. An error is returned if the
|
||
* calling task does not currently own the mutex.
|
||
* For mutexes which have not been created with the MU_PRIO_PROTECT flag, when
|
||
* the calling task loses the ownership of the mutex, and if any tasks are waiting to
|
||
* lock the mutex, the ownership of the mutex is transferred to the waiting task at the
|
||
* head of the mutex's wait queue. It is unblocked, and made ready-to-run.
|
||
* For mutexes which have been created with the MU_PRIO_PROTECT flag, when the
|
||
* calling task loses ownership of the mutex, there could be tasks waiting at the mutex's
|
||
* wait queue, on one of two action types. If the task at the head of the queue is
|
||
* waiting to lock the mutex, the ownership of the mutex is transferred to the waiting
|
||
* task, and its priority is raised if necessary. It is unblocked, and made ready-to-run.
|
||
* If the task at the head of the queue is waiting to change the ceiling priority of the
|
||
* mutex, the ceiling priority is modified, the task is unblocked and made ready-torun;
|
||
* and the next task in the waiting queue is checked. This process of determining
|
||
* the requested action type associated with a waiting task goes on till either the queue
|
||
* is empty, or a task which can successfully lock the mutex is found.
|
||
*/
|
||
unsigned long mu_unlock (
|
||
unsigned long muid /* mutex identifier */
|
||
);
|
||
|
||
/*
|
||
* This system call is used to asynchronously release a semaphore token. It is identical
|
||
* to sm_v() except the call is made asynchronously. Refer to the description of
|
||
* sm_v() for further information. This call is only supported by the pSOS+m kernel
|
||
* (the multiprocessor version).
|
||
*/
|
||
unsigned long sm_av (
|
||
unsigned long smid /* semaphore identifier */
|
||
);
|
||
|
||
#define SM_GLOBAL 0x0001 /* Semaphore can be addressed by other nodes. */
|
||
#define SM_LOCAL 0x0002 /* Semaphore can be addressed by local node only. */
|
||
#define SM_PRIOR 0x0004 /* Tasks are queued by priority. */
|
||
#define SM_FIFO 0x0008 /* Tasks are queued by FIFO. */
|
||
#define SM_UNBOUNDED 0x0010 /* Semaphore count is not bounded. */
|
||
#define SM_BOUNDED 0x0020 /* Semaphore count is bounded. When the SM_BOUNDED flag is specified the count parameter specifies the initial semaphore token count, as well as the upper bound of available tokens. */
|
||
|
||
/*
|
||
* This system call creates a semaphore by allocating and initializing a Semaphore
|
||
* Control Block (SMCB) according to the specifications supplied with the call.
|
||
* Like all objects, a semaphore has a user-assigned name, and a pSOS+-assigned
|
||
* semaphore ID returned by sm_create(). Several flag bits specify the characteristics
|
||
* of the semaphore, including whether tasks will wait for the semaphore by task
|
||
* priority or strictly FIFO.
|
||
*/
|
||
unsigned long sm_create (
|
||
char name[4], /* semaphore name */
|
||
unsigned long count, /* number of tokens */
|
||
unsigned long flags, /* semaphore attributes */
|
||
unsigned long *smid /* semaphore identifier */
|
||
);
|
||
|
||
/*
|
||
* This system call deletes the semaphore with the specified semaphore ID, and frees
|
||
* the SMCB to be reused. sm_delete() takes care of cleaning up the semaphore. If
|
||
* there are tasks waiting, they will be unblocked and given an error code.
|
||
* The calling task does not have to be the creator (parent) of the semaphore to be deleted.
|
||
* However, a semaphore must be deleted from the node on which it was created.
|
||
*/
|
||
unsigned long sm_delete (
|
||
unsigned long smid /* semaphore ID */
|
||
);
|
||
|
||
/*
|
||
* This system call enables the calling task to obtain the semaphore ID of a semaphore
|
||
* it only knows by name. The semaphore ID can then be used in all other operations
|
||
* relating to this semaphore.
|
||
* Most system calls, except sm_create() and sm_ident(), reference a semaphore
|
||
* by the semaphore ID. sm_create() returns the semaphore ID to the semaphore
|
||
* creator. For other tasks, one way to obtain the semaphore ID is to use sm_ident().
|
||
*/
|
||
unsigned long sm_ident (
|
||
char name[4], /* semaphore name */
|
||
unsigned long node, /* node selector */
|
||
unsigned long *smid /* semaphore ID */
|
||
);
|
||
|
||
struct sminfo {
|
||
char name[4]; /* Name of semaphore */
|
||
unsigned long flags; /* Semaphore attributes */
|
||
unsigned long wqlen; /* No. of waiting tasks */
|
||
unsigned long wtid; /* ID of the first waiting task */
|
||
unsigned long count; /* Semaphore count */
|
||
unsigned long maxcount; /* Limit for bounded semaphores */
|
||
unsigned long tid_ntfy; /* Task to notify of availability */
|
||
unsigned long ev_ntfy; /* Ev to post to notify availability */
|
||
};
|
||
|
||
/*
|
||
* This system call returns information of a specified Semaphore object. The information
|
||
* includes the static information that was specified at object creation time and
|
||
* certain internal state information which is not static.
|
||
*/
|
||
unsigned long sm_info (
|
||
unsigned long smid, /* Semaphore ID */
|
||
struct sminfo *buf /* Object Information buffer */
|
||
);
|
||
|
||
/*
|
||
* This system call registers a set of bit-encoded events and a task ID for the given
|
||
* semaphore. Once so registered, a notification is sent to the task whenever a semaphore
|
||
* token becomes available, via an implicit call of the form: ev_send(tid,
|
||
* events). The task can choose to receive the notification via ev_receive() call.
|
||
*/
|
||
unsigned long sm_notify (
|
||
unsigned long smid, /* ID of target semaphore */
|
||
unsigned long tid, /* ID of task to be notified */
|
||
unsigned long events /* bit-encoded events */
|
||
);
|
||
|
||
#define SM_WAIT 0x01 /* Block until semaphore is available. */
|
||
#define SM_NOWAIT 0x02 /* Return with error code if semaphore is unavailable. */
|
||
|
||
/*
|
||
* This system call enables a task or an ISR to acquire a semaphore token. A calling
|
||
* task can specify whether or not it wants to wait for the token. If the semaphore token
|
||
* count is positive, then this call returns the semaphore token immediately. If the
|
||
* semaphore token count is zero and the calling task specified SM_NOWAIT, then
|
||
* sm_p() returns with an error code. If SM_WAIT is elected, the task will be blocked
|
||
* until a semaphore token is released, or if the timeout argument is specified, until
|
||
* timeout occurs, whichever occurs first.
|
||
*/
|
||
unsigned long sm_p (
|
||
unsigned long smid, /* semaphore identifier */
|
||
unsigned long flags, /* attributes */
|
||
unsigned long timeout /* timeout */
|
||
);
|
||
|
||
/*
|
||
* This system call is used to release a semaphore token. If a task is already waiting at
|
||
* the semaphore, it is unblocked and made ready to run. If there is no task waiting,
|
||
* then the semaphore token count is simply incremented by 1.
|
||
* If, as a result of this call, a semaphore token becomes available, and a set of task
|
||
* and events had been registered via a prior call to sm_vnotify() to notify the availability
|
||
* of the semaphore token, pSOS+ also performs an ev_send() operation to
|
||
* send the registered events to the registered task.
|
||
*/
|
||
unsigned long sm_v (
|
||
unsigned long smid /* semaphore identifier */
|
||
);
|
||
|
||
/*
|
||
* This system call asynchronously removes all tasks from a condition-variable<6C><65>s wait
|
||
* queue. It is identical to cv_broadcast() except that the call is made asynchro-
|
||
* nously. Refer to the description of cv_broadcast() for further information.
|
||
*/
|
||
unsigned long cv_abroadcast (
|
||
unsigned long cvid /* condition variable identifier */
|
||
);
|
||
|
||
/*
|
||
* This system call asynchronously removes the task at the head of a condition-
|
||
* variable<6C><65>s queue. It is identical to cv_signal() except that the call is made asyn-
|
||
* chronously. Refer to the description of cv_signal() for further information.
|
||
*/
|
||
unsigned long cv_asignal (
|
||
unsigned long cvid /* condition variable ID */
|
||
);
|
||
|
||
/*
|
||
* This system call removes all the tasks from a condition variable<6C><65>s wait queue. If the
|
||
* mutex guarding the condition variable is unlocked, the task at the head of the wait
|
||
* queue is given ownership of the guarding mutex and unblocked. The remaining
|
||
* tasks, including the task at the head of the wait queue if the guarding mutex is
|
||
* locked, are placed in the guarding mutex<65><78>s wait queue.
|
||
* If there are no tasks waiting, then cv_broadcast() does not do anything.
|
||
*/
|
||
unsigned long cv_broadcast (
|
||
unsigned long cvid /* condition variable identifier */
|
||
);
|
||
|
||
/*
|
||
* This system call creates a condition variable and initializes it according to the
|
||
* specifications supplied with the call.
|
||
* Like all objects, a condition variable has a user-assigned name and a pSOS-
|
||
* assigned condition variable ID returned by cv_create(). Several flag bits specify
|
||
* the characteristics of the condition variable. Tasks can wait at the condition variable
|
||
* either by task priority or strictly FIFO.
|
||
*/
|
||
unsigned long cv_create (
|
||
char name[4],
|
||
unsigned long flags,
|
||
unsigned long *cvid
|
||
);
|
||
|
||
/*
|
||
* This system call deletes a condition variable specified by its ID (cvid) and frees the
|
||
* associated kernel resources. If there are tasks waiting at the condition variable, the
|
||
* tasks are unblocked and given an error code.
|
||
* The calling task does not have to be the creator of the condition variable to be de-
|
||
* leted. However, a condition variable must be deleted from the node on which it was
|
||
* created.
|
||
*/
|
||
unsigned long cv_delete (
|
||
unsigned long cvid /* condition variable identifier */
|
||
);
|
||
|
||
/*
|
||
* This system call enables the calling task to obtain the ID of a condition variable it
|
||
* only knows by name. This condition variable ID can be used in all other operations
|
||
* relating to the condition variable.
|
||
* The pSOS+ kernel does not check for duplicate names. If multiple condition vari-
|
||
* ables with the same name exist, either on the local node, or on a remote note in a
|
||
* multi-processor system, a cv_ident() call may return the ID of any one condition
|
||
* variable with the specified name. It can<61><6E>t be ascertained which ID is returned,
|
||
* though; to a certain extent it depends on the standard search order followed by
|
||
* pSOS+ kernel, as defined in the pSOSystem System Concepts manual.
|
||
*/
|
||
unsigned long cv_ident (
|
||
char name[4], /* condition variable name */
|
||
unsigned long node, /* node number */
|
||
unsigned long *cvid /* condition variable identifier */
|
||
);
|
||
|
||
#if 0
|
||
/*
|
||
* This system call returns object information for a given condition variable object. The
|
||
* information includes the static information that was specified at object creation
|
||
* time and certain internal state information which is not static.
|
||
*/
|
||
unsigned long cv_info (
|
||
unsigned long cvid,
|
||
struct cvinfo *buf
|
||
);
|
||
#endif
|
||
|
||
/*
|
||
* This system call removes the task at the head of a condition variable<6C><65>s wait queue
|
||
* from that queue. If the mutex guarding the condition variable is unlocked, the task
|
||
* is given ownership of the guarding mutex and unblocked. If the mutex is already
|
||
* locked, then the task is placed in the guarding mutex<65><78>s wait queue according to the
|
||
* queueing policy of the mutex.
|
||
* If there are no tasks waiting at the condition variable, this call does nothing.
|
||
*/
|
||
unsigned long cv_signal (
|
||
unsigned long cvid /* condition variable identifier */
|
||
);
|
||
|
||
/*
|
||
* This system call is used by a task to wait on a condition variable. The guarding mu-
|
||
* tex must be owned by the caller. If tasks are waiting at the condition variable, then
|
||
* muid must specify the mutex already guarding the condition variable. Otherwise,
|
||
* any mutex may be specified.
|
||
* cv_wait() unlocks the guarding mutex and blocks the calling task. Unless a time-
|
||
* out occurs, the calling task waits at the condition variable until removed from the
|
||
* wait queue by a cv_signal() or a cv_broadcast() call. When removed, owner-
|
||
* ship of the guarding mutex is given to the task if the guarding mutex is currently
|
||
* unlocked. Otherwise, the task waits for ownership of the guarding mutex according
|
||
* to the queueing policy of the mutex.
|
||
*/
|
||
unsigned long cv_wait (
|
||
unsigned long cvid, /* condition variable identifier */
|
||
unsigned long muid, /* mutex identifier */
|
||
unsigned long timeout /* timeout interval */
|
||
);
|
||
|
||
/*
|
||
* 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 can then be
|
||
* retrieved by referencing the errno macro de????ed in the header ????e <psos.h> as
|
||
* follows:
|
||
* #define errno (*(errno_addr())
|
||
* For example, the following statement expands to include a call to errno_addr():
|
||
* if (errno == ERR_NOMGB)
|
||
*/
|
||
|
||
unsigned long *errno_addr (void);
|
||
|
||
#ifdef __cplusplus
|
||
}
|
||
#endif /* __cplusplus */
|
||
|
||
#endif /* _PSOS_H */
|
||
|