To this for beginners at the fastest to understand real time operating system belongs µC/OS from Jean J. Labrosse ( see http://www.micrium.com ).
In the versions 1.xx it can administer up to 63 applikationtasks with ever different priorities and belongs to the real time operating systems with the lowest storage demand.
pC/OS was based on the original version µC/OS 1.00 from the Embedded Systems Programming Magazine(1992) developed further.

Since is exchanged by direct transfer of pointers in the original version data between the tasks, and consequently no guarantee for the free usability of the sending-buffers after transfer to another task exists and, much important, the recipient a pointer in the data field of another tasks gets (pointer-error / longitudinal mistake / manipulations among others) I altered the mechanisms for Message-Box and Queue accordingly in a way that the data about a kernel-internal Buffer now are handed over to the recipient. This means that the kernel copies to transferring data into an individual buffer and this copies also again itself with transfer to the recipient in the buffer prepared through the recipient. This admittedly entails a higher storage demand for Queue, secures the processes for it most extensive, however (for real-mode) of each other from.
Kernel constants were transferred in the CODE-Area for security reasons furthermore.
Furthermore I have add pipes, eventgroups, timerservice and dynamic memory management.

In order to declare these alterations unequivocally, I have altered the name, ajar at the always bigger nascent original "µC/OS", on pC/OS like "pico-C..".

Special to:  Priority Inversion, the problem and the solutions (actual only in german - sorry !)


known bug:
If a task with lower priority waits for a recource, and a task with higher priority this recource places, so the asleep Task is put into the ready-state. Since the task with higher priority further-runs, this cannot finish reading again the same recource since the lower task 'prematurely' comes with implementation with the return-code OS_TIMEOUT back otherwise.

Please note that some functions are declared under the same name as the original but with modified parameters or pointers.

User-Functions:


Task-Control:Description
OS_InitInitialization of the kernel
OS_StartBegin the kernel services
OS_TaskCreateGenerating of a task
OS_ChangePrioAlteration of the priority of the active task
OS_TaskChangePrioAlteration of the priority of a active/ready task
OS_TaskDeleteDeletion of a active/ready task
OS_TaskIdDeleteDeletion of a active/ready task by unique ID
OS_TaskGetStatusreturns the current status of the task
OS_TaskIdGetStatusreturns the current status of a task by unique ID
OS_TaskGetIDreturns the unique ID of a task
OS_TaskGetPrioreturns the priority of a task
OS_TaskIdDestroyDeletion of a task by unique ID, even if he waits for an IPC or a mutex has occupied & release all memory allocations
OS_TaskSuspendSuspending of a task
OS_TaskIdSuspendSuspending of a task by unique ID
OS_TaskResumeReactivation of a suspended task
OS_TaskIdResumeReactivation of a suspended task by unique ID
OS_TimeDlyPut current task for certain time sleeps
OS_TimeDlyResumeReactivation of an asleep task before course of the put in time
OS_TimeDlyIdResumeReactivation of an asleep task by unique ID before course of the put in time
OS_LockIt suppresses the Sheduler (no taskswitch)
OS_UnlockReactivation of the Sheduler (taskswitch at event or time)
OS_GetRevReturns pointer on kernel revision



Dynamic-Memory:Description
OS_MemoryInitGenerates of the memory pool
OS_MemAllocAllocation of memory
OS_MemFreeRelease of allocated memory
OS_MemFreeSizeIt returns the amount of free memory



Mailboxes:Description
OS_MboxInitInitialisation of a Mailbox
OS_MboxPostSend data to task with higher priority recipients of this Mailbox
OS_MboxPostAbbortAbborts waiting of a sending task (highest waiting prio) onto a mailbox
OS_MboxPendWait for data from a Mailbox
OS_MboxPendAbbortAbborts waiting of a receiving Tasks (highest waiting prio) on a Mailbox



Queues:Description
OS_QueueInitInitialsation of a Queue
OS_QueueInfoInformation about a Queue catches up with
OS_QueuePostSend data into a Queue
OS_QueueFrontPostSend data to the beginning of a Queue
OS_QueuePostAbbortAbborts waiting of a sending task (highest waiting prio) onto a queue
OS_QueuePendWait for data from a Queue
OS_QueuePendAbbortAbborts waiting of a receiving Tasks (highest waiting prio) on a Queue
OS_QueueClearDelete all data in a Queue



Pipes:Description
OS_PipeInitInitialisation of a Pipe
OS_PipeInfoInformation about a Pipe catches up with
OS_PipePostSend data into a Pipe
OS_PipeFrontPostSend data to the beginning of a Pipe
OS_PipePostAbbortAbborts waiting of a sending task (highest waiting prio) onto a pipe
OS_PipePendWait for data from a Pipe
OS_PipePendAbbortAbborts waiting of a receiving Tasks (highest waiting prio) on a Pipe
OS_PipeClearDelete all data in a Pipe



Semaphores:Description
OS_SemInitInitalisation of a Semaphore
OS_SemAcceptwait for event and returns number
OS_SemPostDecontrol of a busy Semaphores / places event
OS_SemPendCover one Semaphore / waits on event
OS_SemPendAbbortAbborts waiting of a Tasks (highest waiting prio) on a Semaphore
OS_SemClearClear the Semaphore-Counter



Mutexes:Description
OS_MutexCreateGenerating of a Mutex
OS_MutexPostDecontrol of a Mutex
OS_MutexPendCover the Mutex
OS_MutexPendAbbortAbborts waiting of a Tasks (highest waiting prio) on a Mutex



Event-Groups:Description
OS_EvgInitInitialisation of a Eventgroup
OS_EvgPostPlace one/many events of an Evengroup
OS_EvgPendWait for arriving an or several events of an Eventgroup
OS_EvgPendAbbortAbborts waiting of a task (highest waiting prio) onto a Eventgroup



Timer-Service:Description
OS_TimerCreateGenerating of a Timer
OS_TimerDeleteDelete of a generated Timer
OS_TimerStart(Re-)Start of a generated Timer
OS_TimerStopStop of a generated Timer
OS_TimerGetStatereturns the status of a generated Timer
OS_TimerGetRemainreturns the remaining time of a running Timer



System-Ticks:Description
OS_TimeSetSet ticker to value
OS_TimeGetreturns current ticker-value



Interrupts:Description
OS_IntEnterRegistration of a called ISR
OS_IntExitEnd of a called ISR



History:Description
OS_HistoryPostWrite entry in History
OS_HistoryReadreturn first History-entry and delete this in the table





Error-Codes:


Name

Decimal_Value

Description

OS_SUCCESS / OS_NO_ERR

0

no errors
OS_TIMEOUT

10

timeout condition occurs during waiting for a resource
OS_MBOX_FULL

20

Mailbox fully (with OS_NO_SUSP)
OS_MBOX_NODATA

21

no message in Mailbox (with OS_NO_SUSP)
OS_Q_FULL

30

Queue fully (with OS_NO_SUSP)
OS_Q_NODATA

31

no byte in Queue (with OS_NO_SUSP)
OS_Q_CLEAR

32

Queue was cleared during waiting
OS_PRIO_EXIST

40

under this priority, a other Task is registered
OS_TASK_NOT_EXIST

41

under this priority, no Task is registered
OS_SEM_ERR

50

internal error in Semaphore-handling
OS_SEM_NODATA

51

Semaphore occupy / no event (with OS_NO_SUSP)
OS_SEM_OVF

52

Error in the Semaphore-handling (Counter too big)
OS_MUX_ERR

55

Error in Mutex-handling
OS_MUX_NOACC

56

Mutex occupied (with OS_NO_SUSP)
OS_MUX_USED

57

to change Task have a Mutex occupied
OS_P_FULL

60

Pipe fully (with OS_NO_SUSP)
OS_P_NODATA

61

no package in Pipe (with OS_NO_SUSP)
OS_P_CLEAR

62

Pipe was cleared during waiting
OS_P_LEN_ERR

63

Package too long
OS_MEM_ERR

70

parameter error / internal error
OS_MEM_OVF

71

memeory overflow
OS_EVG_ERR

80

Error in Event-Group handling
OS_EVG_NOE

81

Event(s) appeared not (with OS_NO_SUSP)
OS_HIS_END

90

no (more) entry existing
OS_SUSPEND_IDLE

100

the Idle-Task cannot be suspended
OS_PRIO_INVALID

101

the value of priority is bigger OS_MIN_PRIO
OS_TIME_NOT_DLY

102

the task doesn't sleep
OS_TASK_SUSP_PRIO

103

under this priority, no Task is registered
OS_TASK_NOT_SUSP

104

the task is not suspended
OS_TASK_NOT_RDY

105

the task is not ready
OS_TMR_NO_TIME

106

no time given on TimerCreate
OS_TMR_NOT_EXIST

107

timer was not created / registered
OS_TMR_EXIST

108

timer was still created / registered






Configuration of the kernel



The pC/OS kernel can be configured in addition to the to-use hardware port some numbers of ways to configure Services/IPCs as well as to reduce the memory requirements - code-size for the compilers "unused code" may not clearly identify and RAM - available. These are in the file "OS_cfg.h" together.

components configurationdescription
OS_SYSTEM_TICKS_PER_SECsystem ticks per secound
OS_TIMER_TICKS_PER_SECtimer ticks per secound (see Timer-Service / TIMERS), can be tick faster than the kernel(system)-ticks
OS_TASK_EXT_ENinclude code for extended TASKS services
OS_TASK_DESTROY_ENinclude code for destroy pending/waiting TASKS, needs OS_TASK_EXT_EN too
OS_SEM_ENinclude code for SEMAPHORES
OS_SEM_EXT_ENinclude code for extended SEMAPHORES services
OS_MUX_ENinclude code for MUTEXES
OS_MBOX_ENinclude code for MAILBOXES
OS_Q_ENinclude code for QUEUES
OS_P_ENinclude code for PIPES
OS_EVG_ENinclude code for EVENTGROUPS
OS_TMR_ENinclude code for TIMERS
OS_MEM_ENinclude code for MEMORY-MANAGER
OS_HIS_ENinclude code for HISTORY
OS_STK_CHECK_ENcheck end-of-stack of old task during context switch
OS_STK_CHECK_FILLfill stack with 0xEF pattern to get the deep of use

user configurationdescription
OS_MAX_TASKSmax created tasks in hole system --> max 64 !
OS_MIN_PRIOlowest possible prio --> max 64 !
OS_IDLE_STK_SIZEidle stack size in OS_STK_TYPE with fix (OS_MIN_PRIO - 1) as prio for idle task
OS_TMR_PRIOtimer task prio, if OS_TMR_EN is not 0
OS_TMR_STK_SIZEtimer stack size in OS_STK_TYPE, if OS_TMR_EN is not 0
OS_MAX_HISTORYhistory entries, if OS_HIS_EN is not 0
OS_STK_RESERVEspace between real end-of-stack and check-point in OS_STK_TYPE, if OS_STK_CHECK_EN is not 0



to OS_MAX_TASKS and OS_MIN_PRIO:
If a system is needed with 5 tasks, 2 of which tasks are using a shared mutex, you need OS_MAX_TASKS = 7 (including a Mutex and Idle-Task) and OS_MIN_PRIO = 8 whereas the Idle-Task then gets the prio 7 and all other Tasks and the Mutex gets higher priorities (0..6). If the timer-service should used too, it must be this timer task additionally involved.




Managed / Unmanaged Interrupt Service Routinen (ISR)



The pC/OS kernel must be notified when an ISR is running and needs to consider when leaving this if a process change is "preemptive" required. There are, depending on the hardware and used implementation, two ways:

managed ISRthe IRQ entry / exit is central and informs the kernel (see eg. ARM7TDMI ports)
unmanaged ISReach ISR is independent and is jumped out directly from the vector table -> the kernel must be informed. (see eg. Cortex-Mx ports)


In managed-ISRs the central ISR entry / exit code informs the kernel, so that the ISR itself must not observed for the kernel. In unmanged ISR however, at first OS_IntEnter() is to call and at end / at last OS_IntExit() is to call !

managed ISRunmanaged ISR
PUBLIC OSirqISR CODE32 OSirqISR ; save registers ; register interrupt on kernel ; read Interrupt vector for ... ; ... this event (eg MyManaged_ISR) ; call handler (eg MyManaged_ISR) --> ; call OS_IntExit() ; restore registers END void MyManaged_ISR(void) { . . // my ISR code . } void MyUnManaged_ISR(void) { OS_IntEnter(); . . // my ISR code . OS_IntExit(); }



Task-Control




OS_Init



void OS_Init(void)

Initialize the Kernel and installs the Idle-Task. This function must be called before all other kernelservices at the system initialization once.


Parameters

none


Return Value

none


Example

void main(void) { . . OS_Init(); . . OS_Start(); }





OS_Start

void OS_Start(void)

Starts the kernel. This function activates the sheduler and never returns back to caller.


Parameters

none


Return Value

none


Example

void main(void) { . . OS_Init(); . . OS_Start(); }





OS_TaskCreate

U08 OS_TaskCreate(void (OS_FAR *task)(void *dptr), void *data, void *pstk, U08 prio)

Installs a new Task. This function initializes the Task-Control-Block and writes down the new Task with his Stack and the call parameters. This can from main() take place out in term during the initialization as well as another Task.
If the optional feature "OS_STK_CHECK_EN" (Stack-end check) is used, the kernel requires an additional pointer to the stack end.


Parameters

*dptrpointer to task-code
*datapointer to parameter of this task
*pstkpointer to stack of this task
*pstkendpointer to end-of-stack of this task
priopriority of this task

Return Value

OS_NO_ERRTask successfully positioned
OS_PRIO_EXISTunder this priority, already a Task exists
OS_PRIO_INVALIDthis priority is reserved for the Idle-Task or the value of priority is bigger than OS_MIN_PRIO

Example

OS_STK_TYPE Task1Stack[STK_SIZE]; U08 Task1Data; void OS_FAR Task1(void *data); // forward declaration . . void main(void) { U08 state; . . OS_Init(); . state = OS_TaskCreate(Task1, (void *)&Task1Data, (void *)&Task1Stack[STK_SIZE], 18); . OS_Start(); } . . void OS_FAR Task1(void *data) { . . while(1) { . . . } }





OS_ChangePrio

U08 OS_ChangePrio(U08 newp)

Change the priority of the current Tasks. This function can be used in order to change the priority of the tasks on reason of an event for example.


Parameters

newpnew priority of this task

Return Value

OS_NO_ERRPriority successfully changed
OS_PRIO_EXISTunder this priority, already a task exists
OS_PRIO_INVALIDthis priority is reserved for the Idle-Task or the value of priority is bigger than OS_MIN_PRIO
OS_MUX_USEDto change Task have a Mutex occupied

Example

void OS_FAR Task1(void *data) { U08 state; . . while(1) { . state = OS_ChangePrio(38); . } }





OS_TaskChangePrio

U08 OS_TaskChangePrio(U08 oldp, U08 newp)

Change the priority of a Tasks. This function can be used in order to change the priority of a running/ready tasks on reason of an event for example.
The priority of Tasks, waiting on a resource (Semaphore/Queue/Pipe/..) can not changed, because this state is visible for the kernel but not the exact resource itself.


Parameters

oldpactual/old priority of the task
newpnew priority of this task

Return Value

OS_NO_ERRPriority successfully changed
OS_PRIO_EXISTunder this priority, already a task exists
OS_PRIO_INVALIDthis priority is reserved for the Idle-Task or the value of priority is bigger than OS_MIN_PRIO
OS_TASK_NOT_RDYthe Task is not in RUNNING/READY-state and so the priority can not changed
OS_MUX_USEDto change Task have a Mutex occupied

Example

void OS_FAR Task1(void *data) { U08 state; . . while(1) { . state = OS_TaskChangePrio(38, 25); . } }





OS_TaskDelete

U08 OS_TaskDelete(U08 prio)

Delete the given task. This function can be used, about for example on reason of an event the task too ending/clearing. This task is distant from the Task-Control-Table afterwards. Allocated resources of the tasks are not released automatically on that occasion.
In order to later be able to execute this task again, it must be positioned again by means of OS_TaskCreate regularly.
Tasks, waiting on a resource (Semaphore/Queue/Pipe/..) can not be deleted, because this state is visible for the kernel but not the exact resource itself.


Parameters

priopriority of the task to delete

Return Value

OS_NO_ERRTask deleted
OS_TASK_NOT_EXISTunder this priority, no task exists
OS_TASK_NOT_RDYthe Task is not in RUNNING/READY-state and so the task can not be deleted
OS_MUX_USEDto delete Task have a Mutex occupied

Example

void OS_FAR Task1(void *data) { U08 state; . . while(1) { . state = OS_TaskDelete(OS_PRIO_SELF); . } }





OS_TaskIdDelete

U08 OS_TaskIdDelete(U08 id)

Delete the given task by unique ID. This function can be used, about for example on reason of an event the task too ending/clearing. This task is distant from the Task-Control-Table afterwards. Allocated resources of the tasks are not released automatically on that occasion.
In order to later be able to execute this task again, it must be positioned again by means of OS_TaskCreate regularly.
Tasks, waiting on a resource (Semaphore/Queue/Pipe/..) can not be deleted, because this state is visible for the kernel but not the exact resource itself.


Parameters

idunique ID of the task to delete

Return Value

OS_NO_ERRTask deleted
OS_TASK_NOT_EXIST>under this ID, no task exists
OS_TASK_NOT_RDYthe Task is not in RUNNING/READY-state and so the task can not be deleted
OS_MUX_USEDto delete Task have a Mutex occupied

Example

void OS_FAR Task1(void *data) { U08 state; . . while(1) { . state = OS_TaskIdDelete(3); . } }





OS_TaskGetStatus

U08 OS_TaskGetStatus(U08 prio)

Returns the current status of the given task.


Parameters

priopriority of the task

Return Value

statussee "TASK STATUS", Bitmask

Example

void OS_FAR Task1(void *data) { U08 status; . . while(1) { . status = OS_TaskGetStatus(6); . } }





OS_TaskIdGetStatus

U08 OS_TaskIdGetStatus(U08 id)

Returns the current status of the given task by unique ID.


Parameters

idunique ID of the task

Return Value

statussee "TASK STATUS", Bitmask

Example

void OS_FAR Task1(void *data) { U08 status; . . while(1) { . status = OS_TaskIdGetStatus(2); . } }





OS_TaskGetID

U08 OS_TaskGetID(U08 prio)

Returns the unique-ID to the specified tasks. These can later be used to e.g. a task - even if his priority have changed or has just a mutex in use - a violent end (OS_TaskDestroy()).


Parameters

priocurrent priority of the task

Return Value

idthe unique-ID of this task

Example

U08 idT1; void OS_FAR Task1(void *data) { . idT1 = OS_TaskGetID(OS_PRIO_SELF); . while(1) { . . } }





OS_TaskGetPrio

U08 OS_TaskGetPrio(U08 id)

Returns the priority to the specified tasks by unique ID.


Parameters

idunique ID of the task

Return Value

priothe priority of this task

Example

U08 prioT1; void OS_FAR Task1(void *data) { . prioT1 = OS_TaskGetPrio(2); . while(1) { . . } }





OS_TaskIdDestroy

U08 OS_TaskIdDestroy(U08 id)

Removes the specified task completely independently of his status. This feature can be used to e.g. on basis of an event the task is to cancel. This task is then from the Task-Control-Table, from possibly registered IPCs (Semaphore/MBox/Queue/Pipe/..) and the Memory Manager completely removed.
If the tasks at this stage, a mutex has occupied, it will be released and a user-callback function is called to make any necessary reinitialization of the affected hardware, etc. (see OSMutexReInitResource () in "pC_OS_userCB.c"). But this can be done only for one mutex (the last). If the task have two mutexes occupied, it is only the last released!
In order to later be able to execute this task again, it must be positioned again by means of OS_TaskCreate regularly.
ATTENTION:
During this task will be removed from the Task-Control-Table and from the IPCs all interrupts are blocked because a suitable event for this task could result in a access/update conflict. During the subsequent clean up the memory-manager the interrupts are allowed again but sheduling is suppressed to prevent a simultaneous re-booting this task using OS_TaskCreate() (priority of this task).


Parameters

idunique-ID of the task to destroy

Return Value

OS_NO_ERRtask completely removed
OS_TASK_NOT_EXISTthe specified task does not exist
OS_TASK_NOT_RDYthe task could not be completely removed from the IPCs or a mutex
OS_MEM_ERRduring deallocating the memory allocations of this task an error occurs

Example

void OS_FAR Task1(void *data) { U08 state; . . while(1) { . state = OS_TaskIdDestroy(2); . } }





OS_TaskSuspend

U08 OS_TaskSuspend(U08 prio)

Suspends a task from the implementation through the kernel. This function can be used in order to deactivate a task for a time on reason of an event for example.


Parameters

priopriority of task to suspending

Return Value

OS_NO_ERRTask successfully suspended
OS_SUSPEND_IDLEthe Idle-Task cannot be suspended
OS_PRIO_INVALIDthe value of priority is bigger than OS_MIN_PRIO
OS_TASK_SUSP_PRIOunder this priority, no Task is registered
OS_MUX_USEDto suspend Task have a Mutex occupied

Example

void OS_FAR Task1(void *data) { U08 state; . . while(1) { . state = OS_TaskSuspend(24); . } }





OS_TaskIdSuspend

U08 OS_TaskIdSuspend(U08 id)

suspends a task given by unique ID from the implementation through the kernel. This function can be used in order to deactivate a task for a time on reason of an event for example.


Parameters

idunique ID of task to suspending

Return Value

OS_NO_ERRTask successfully suspended
OS_SUSPEND_IDLEthe Idle-Task cannot be suspended
OS_TASK_SUSP_PRIOunder this ID, no Task is registered
OS_MUX_USEDto suspend Task have a Mutex occupied

Example

void OS_FAR Task1(void *data) { U08 state; . . while(1) { . state = OS_TaskIdSuspend(4); . } }





OS_TaskResume

U08 OS_TaskResume(U08 prio)

Reactivate a suspended Task. This function can be used in order to activate a suspended task again on reason of an event for example.


Parameters

priopriority of suspended task

Return Value

OS_NO_ERRTask successfully reactivated
OS_TASK_NOT_SUSPthe Task is not suspended
OS_PRIO_INVALIDthe value of priority is bigger than OS_MIN_PRIO
OS_TASK_NOT_EXISTunder this priority, no Task is registered
OS_MUX_USEDto resume Task have a Mutex occupied

Example

void OS_FAR Task1(void *data) { U08 state; . . while(1) { . state = OS_TaskResume(24); . } }





OS_TaskIdResume

U08 OS_TaskIdResume(U08 id)

Reactivate a suspended Task by given unique ID. This function can be used in order to activate a suspended task again on reason of an event for example.


Parameters

idunique ID of suspended task

Return Value

OS_NO_ERRTask successfully reactivated
OS_TASK_NOT_SUSPthe Task is not suspended
OS_TASK_NOT_EXISTunder this ID, no Task is registered
OS_MUX_USEDto resume Task have a Mutex occupied

Example

void OS_FAR Task1(void *data) { U08 state; . . while(1) { . state = OS_TaskIdResume(4); . } }





OS_TimeDly

void OS_TimeDly(U16 ticks)

If puts the current task for kernel-ticks sleeps. This function can be used in order to let pass a defined time on reason of an event for example. ATTENTION! With the parameter OS_SUSPEND (0), the Task for always is deactivated and can never be activated again.


Parameters

tickskernel-ticks as sleeping-time ( 1...65535 )

Return Value

none

Example

void OS_FAR Task1(void *data) { . . while(1) { . OS_TimeDly(200); . } }





OS_TimeDlyResume

U08 OS_TimeDlyResume(U08 prio)

Breaks off the wait of a tasks prematurely. This function can be used in order to prematurely activate an asleep task again on reason of an event for example.


Parameters

priopriority of sleeping task

Return Value

OS_NO_ERRTask successfully wakened
OS_TIME_NOT_DLYthe Task doesn't sleep
OS_PRIO_INVALIDthe value of priority is bigger than OS_MIN_PRIO
OS_TASK_NOT_EXISTunder this priority, no Task is registered

Example

void OS_FAR Task1(void *data) { U08 state; . . while(1) { . state = OS_TimeDlyResume(24); . } }





OS_TimeDlyIdResume

U08 OS_TimeDlyIdResume(U08 id)

Breaks off the wait of a tasks prematurely by unique ID. This function can be used in order to prematurely activate an asleep task again on reason of an event for example.


Parameters

idunique ID of sleeping task

Return Value

OS_NO_ERRTask successfully wakened
OS_TIME_NOT_DLYthe Task doesn't sleep
OS_TASK_NOT_EXISTunder this ID, no Task is registered

Example

void OS_FAR Task1(void *data) { U08 state; . . while(1) { . state = OS_TimeDlyIdResume(4); . } }





OS_Lock

void OS_Lock(void)

If turns off the sheduler. This function can be used, about for example atomic (not under-breakable) to be able to execute processes, without task-switches. Interrupts still are served.


Parameters

none

Return Value

none

Example

void OS_FAR Task1(void *data) { . . while(1) { . OS_Lock(); . . // not under-breakable part . OS_Unlock(); . } }





OS_Unlock

void OS_Unlock(void)

If switches on the sheduler again. This function is used, about for example atomic (not under-breakable) to complete processes and to make a taskswitch again possible.


Parameters

none

Return Value

none

Example

void OS_FAR Task1(void *data) { . . while(1) { . OS_Lock(); . . // not under-breakable part . OS_Unlock(); . } }





OS_GetRev

U08 OS_FAR *OS_GetRev(void)

Returns a pointer on the kernelrevision (NULL-terminated ASCII-array).


Parameters

none

Return Value

*pointerpointer to the address of array

Example

void OS_FAR Task1(void *data) { U08 OS_FAR *Revision; . . while(1) { . Revision = OS_GetRev(); . } }





Dynamic-Memory




OS_MemoryInit

U08 OS_MemoryInit(OS_MEM OS_HUGE *mp, U32 size)

Initialize the dynamic memory management. This function must be called for the dynamic memory management at the system initialization once. The functions of the vigorous memory management can be used also without current kernel. ATTENTION! It is executed no checkup of the storage area.


Parameters

*mpstartaddress of memory-pool
sizesize of memory-pool in bytes

Return Value

OS_NO_ERRMemory pool positioned
OS_MEM_ERRone of the parameters is ZERO

Example for LARGE memory in NEAR-model void main(void) { U08 state; . . // Memory: 512k - 64k(near) state = OS_MemoryInit((OS_MEM OS_HUGE *)(0x10000000), 458750); . . } Example for model-known memory U08 memorypool[MEMSIZE]; void main(void) { U08 state; . state = OS_MemoryInit((OS_MEM OS_HUGE *)(memorypool), MEMSIZE); . . }





OS_MemAlloc

U08 OS_MemAlloc(U08 OS_HUGE **MemPtr, U32 size)

Allocation of a required memory area.


Parameters

*MemPtrpointer of pointer to get address of memory-area
sizesize of needed memory in bytes

Return Value

OS_NO_ERRmemory successfully allocated
OS_MEM_ERRsize is ZERO or bigger as storage area of the processor
OS_MEM_OVFnot sufficiently free memory

Example

void OS_FAR Task1(void *data) { U08 OS_HUGE *Addr_p; U08 state; . . while(1) { . state = OS_MemAlloc(&Addr_p, 3800); . } }





OS_MemFree

U08 OS_MemFree(OS_MEM OS_HUGE *MemPtr)

Release of an allocated memory area.


Parameters

*MemPtrpointer to address of memory-area

Return Value

OS_NO_ERRmemory successfully released
OS_MEM_ERRPointer is ZERO or not a valid allocation found

Example

void OS_FAR Task1(void *data) { U08 OS_HUGE *Addr_p; U08 state; . . while(1) { . state = OS_MemAlloc(&Addr_p, 3800); . . state = OS_MemFree((OS_MEM OS_HUGE *)Addr_p); . } }





OS_MemFreeSize

U32 OS_MemFreeSize(void)

It returns the amount of free memory.


Parameters

none

Return Value

sizefree size in memory-pool in bytes

Example

void OS_FAR Task1(void *data) { U08 OS_HUGE *Addr_p; U32 fsize; U08 state; . . while(1) { . state = OS_MemAlloc(&Addr_p, 3800); . . fsize = OS_MemFreeSize(); . } }





Mailboxes




OS_MboxInit

U08 OS_MboxInit(OS_MBOX *pmbox)

Initialization of a Mailbox. Through a mailbox any kind of data can pass by a pointer. On this, the recipient receives a pointer in the data field of the sender!


Parameters

*pmboxpointer to Mailbox

Return Value

OS_NO_ERRMailbox initialized

Example

OS_MBOX MailBox1; void main(void) { U08 state; . . OS_Init(); . state = OS_MboxInit(&MailBox1); . }





OS_MboxPend

U08 OS_MboxPend(OS_MBOX *pmbox, void OS_FAR *msg, U16 timeout)

Waits for a message from a mailbox. With OS_NO_SUSP, it immediately is come back even if no news was available and becomes with OS_SUSPEND as long as waited until a message is available, if necessary unending.


Parameters

*pmboxpointer to Mailbox
*msgpointer to receiving parameter (U32)
timeoutkernel-ticks as waiting-time ( 1...65534 )

Return Value

OS_NO_ERRMessage from Mailbox gotten
OS_MBOX_NODATAno message in Mailbox (with OS_NO_SUSP)
OS_TIMEOUTno message in Mailbox (after waits)

Example

OS_MBOX MailBox1; void OS_FAR Task1(void *data) { U08 state; U32 Message; . . while(1) { . state = OS_MboxPend(&MailBox1, &Message, 200); . } }





OS_MboxPendAbbort

U08 OS_MboxPendAbbort(OS_MBOX *pmbox)

Abborts waiting of a receiving Tasks (highest waiting prio) on a Mailbox. It is only the waiting task with the highest priority quasi "premature" to TimeOut forwarded.


Parameters

*pmboxpointer to Mailbox

Return Value

OS_NO_ERRpending of a task abborted
OS_TASK_NOT_EXISTno pending task on this Maibox

Example

OS_MBOX MailBox1; void OS_FAR Task1(void *data) { U08 state; . . while(1) { . state = OS_MboxPendAbbort(&MailBox1); . } }





OS_MboxPost

U08 OS_MboxPost(OS_MBOX *pmbox, void OS_FAR *msg, U16 timeout)

Sends a message into a Mailbox. With OS_NO_SUSP, it immediately is come back even if the Mailbox was full and becomes with OS_SUSPEND as long as waited until the message can be written down, if necessary unending.


Parameters

*pmboxpointer to Mailbox
*msgpointer to message (U32)
timeoutkernel-ticks as waiting-time ( 1...65534 )

Return Value

OS_NO_ERRMessage in Mailbox sent
OS_MBOX_FULLMailbox fully (with OS_NO_SUSP)
OS_TIMEOUTMailbox fully (after waits)

Example

OS_MBOX MailBox1; void OS_FAR Task1(void *data) { U08 state; U32 Message; . . while(1) { . Message =0x3076; state = OS_MboxPost(&MailBox1, &Message, OS_SUSPEND); . } }





OS_MboxPostAbbort

U08 OS_MboxPostAbbort(OS_MBOX *pmbox)

Abborts waiting of a sending Tasks (highest waiting prio) on a Mailbox. It is only the waiting task with the highest priority quasi "premature" to TimeOut forwarded.


Parameters

*pmboxpointer to Mailbox

Return Value

OS_NO_ERRposting of a task abborted
OS_TASK_NOT_EXISTno posting task on this Maibox

Example

OS_MBOX MailBox1; void OS_FAR Task1(void *data) { U08 state; . . while(1) { . state = OS_MboxPostAbbort(&MailBox1); . } }





Queues




OS_QueueInit

U08 OS_QueueInit(OS_Q *pq, void OS_HUGE *buffer, U16 size)

Initialize a Queue. A Queue serves the byte-expels transfer of data at another process of the FIFO-prinzip. Within this Queue can <size> byte through the kernel buffer <*buffer> at other processes is handed over. The buffer can be generated through direct declaration ( UBYTE buffer[size] ) or through dynamic allocation. For the dynamic allocation in systems with segment-based memory management, the type declaration is OS_HUGE necessary in order to be able to go down well away with an area over segment borders.


Parameters

*pqpointer to Queue
*bufferpointer to kernel-buffer
sizesize of kernel-buffer in bytes

Return Value

OS_NO_ERRQueue initialized

Example

OS_Q Queue1; U08 Q_Data1[256]; void main(void) { U08 state; . . OS_Init(); . state = OS_QueueInit(&Queue1, &Q_Data1[0], 256); . }





OS_QueueInfo

U08 OS_QueueInfo(OS_Q *pq, U16 *size, U16 *used, U08 *prio)

Retrieval of the status of a Queue. Through this retrieval, miscellaneous parameters their initialization as well as their filling stand can be determined. Furthermore, the priority of the waiting tasks can be determined.


Parameters

*pqpointer to Queue
*sizepointer to variable will get the size
*usedpointer to variable will get the used-bytes at this time
*priopointer to variable will get the priority of waiting Task (if zero - no Task is waiting)

Return Value

OS_NO_ERRno mistake (for expansions)

Example

OS_Q Queue1; void OS_FAR Task1(void *data) { U08 state; U16 size; U16 used; U08 prio; . . while(1) { . state = OS_QueueInfo(&Queue1, &size, &used, &prio); . } }





OS_QueuePend

U08 OS_QueuePend(OS_Q *pq, U08 OS_FAR *msg, U16 timeout)

Wait on one byte from a Queue. With OS_NO_SUSP, it immediately is come back even if no bytes were available and become with OS_SUSPEND as long as waited until one byte is available, if necessary unending.


Parameters

*pqpointer to Queue
*msgpointer to receiving Byte
timeoutkernel-ticks as waiting-time ( 1...65534 )

Return Value

OS_NO_ERRByte from Queue gotten
OS_Q_NODATAno byte in Queue (with OS_NO_SUSP)
OS_TIMEOUTno byte in Queue (after waits)

Example

OS_Q Queue1; void OS_FAR Task1(void *data) { U08 state; U08 Receive; . . while(1) { . state = OS_QueuePend(&Queue1, &Receive, 100); . } }





OS_QueuePendAbbort

U08 OS_QueuePendAbbort(OS_Q *pq)

Abborts waiting of a receiving Tasks (highest waiting prio) on a Queue. It is only the waiting task with the highest priority quasi "premature" to TimeOut forwarded.


Parameters

*pqpointer to Queue

Return Value

OS_NO_ERRpending of a task abborted
OS_TASK_NOT_EXISTno pending task on this Queue

Example

OS_Q Queue1; void OS_FAR Task1(void *data) { U08 state; . . while(1) { . state = OS_QueuePendAbbort(&Queue1); . } }





OS_QueuePost

U08 OS_QueuePost(OS_Q *pq, U08 msg, U16 timeout)

Sends one byte into a Queue. With OS_NO_SUSP, it immediately is come back even if the Queue was full and becomes with OS_SUSPEND as long as waited until the byte can be written down, if necessary unending.


Parameters

*pqpointer to Queue
msgbyte to send
timeoutkernel-ticks as waiting-time ( 1...65534 )

Return Value

OS_NO_ERRByte in Queue sent
OS_Q_FULLQueue fully (with OS_NO_SUSP)
OS_TIMEOUTQueue fully (after waits)

Example

OS_Q Queue1; void OS_FAR Task1(void *data) { U08 state; U08 Message; . . while(1) { . Message = 0x6A; state = OS_QueuePost(&Queue1, Message, 5000); . } }





OS_QueueFrontPost

U08 OS_QueueFrontPost(OS_Q *pq, U08 msg, U16 timeout)

Sends one byte at the beginning of a Queue. Consequently, this byte first is finished reading again by the recipient (cuts in line). With OS_NO_SUSP, it immediately is come back even if the Queue was full and becomes with OS_SUSPEND as long as waited until the byte can be written down, if necessary unending.


Parameters

*pqpointer to Queue
msgbyte to send
timeoutkernel-ticks as waiting-time ( 1...65534 )

Return Value

OS_NO_ERRByte in Queue sent
OS_Q_FULLQueue fully (with OS_NO_SUSP)
OS_TIMEOUTQueue fully (after waits)

Example

OS_Q Queue1; void OS_FAR Task1(void *data) { U08 state; U08 Message; . . while(1) { . Message = 0x2D; state = OS_QueueFrontPost(&Queue1, Message, OS_NO_SUSP); . } }





OS_QueuePostAbbort

U08 OS_QueuePostAbbort(OS_Q *pq)

Abborts waiting of a sending Tasks (highest waiting prio) on a Queue.
It is only the waiting task with the highest priority quasi "premature" to TimeOut forwarded.


Parameters

*pqpointer to Queue

Return Value

OS_NO_ERRposting of a task abborted
OS_TASK_NOT_EXISTno posting task on this Queue

Example

OS_Q Queue1; void OS_FAR Task1(void *data) { U08 state; . . while(1) { . state = OS_QueuePostAbbort(&Queue1); . } }





OS_QueueClear

U08 OS_QueueClear(OS_Q *pq)

Deletes the content of a Queue and reactivates a waiting posting-process. This function can be used to reactivate the datatransfer after a hang-on. The deleted data get lost on that occasion.


Parameters

*pqpointer to Queue

Return Value

OS_NO_ERRcontent of Queue deleted

Example

OS_Q Queue1; void OS_FAR Task1(void *data) { U08 state; . . while(1) { . . state = OS_QueueClear(&Queue1); . } }





Pipes




OS_PipeInit

U08 OS_PipeInit(OS_P *pp, void OS_HUGE *buffer, U16 size, U08 deep)

Initialize a Pipe. A Pipe serves transfer of data of the package manners at another process of the FIFO-prinzip. Within this Pipe can at max <deep> package with ever at max <size> byte one packet through the kenrnel-buffer <*buffer> at another process is handed over. The Buffer can be generated through direct declaration ( UBYTE Buffer[(size+2)*deep] ) or through dynamic memory allocation. For the dynamic allocation in systems with segment-based memory management, the type declaration is OS_HUGE necessary in order to be able to go down well away with an area over segment borders. The additional length of 2 bytes per package is required for the storage of the package length.


Parameters

*pppointer to Pipe
*bufferpointer to kernel-buffer
sizemax size of data-bytes per paket
deepmax pakets in pipe

Return Value

OS_NO_ERRPipe initialized

Example

OS_P Pipe1; U08 P_Data1[(MAXPAKET+2)*8]; void main(void) { U08 state; . . OS_Init(); . state = OS_PipeInit(&Pipe1, P_Data1, MAXPAKET+2, 8); . }





OS_PipeInfo

U08 OS_PipeInfo(OS_P *pp, U16 *size, U08 *deep, U08 *used, U08 *prio)

Retrieval of the status of a Pipe. Through this retrieval, miscellaneous parameters of their initialization as well as their filling stand can be determined. Furthermore, the priority of the waiting Tasks can be determined.


Parameters

*pppointer to Pipe
*sizepointer to variable will get the size per paket
*deeppointer to variable will get the max pakets in pipe
*usedpointer to variable will get the used-pakets at this time
*priopointer to variable will get the priority of waiting Task (if zero - no Task is waiting)

Return Value

OS_NO_ERRno mistake (for expansions)

Example

OS_P Pipe1; void OS_FAR Task1(void *data) { U08 state; U16 size; U08 deep; U08 used; U08 prio; . . while(1) { . state = OS_PipeInfo(&Pipe1, &size, &deep, &used, &prio); . } }





OS_PipePend

U08 OS_PipePend(OS_P *pp, U08 OS_HUGE *msg, U16 *lng, U16 timeout)

Waits on a data package from a Pipe. The receiver-buffer must be included sufficiently big in order to be able to pick up the package. Since the receiver-buffer can also be dynamically allocated, the type declaration is OS_HUGE necessary on the other hand in order to be able to go down well away with an area over segment borders. With OS_NO_SUSP, it immediately is come back even if no package was available and becomes with OS_SUSPEND as long as waited until one package is available, if necessary unending.


Parameters

*pppointer to Pipe
*msgpointer to receiving array
*lngpointer to variable will get the lenght of paket
timeoutkernel-ticks as waiting-time ( 1...65534 )

Return Value

OS_NO_ERRPackage from Pipe gotten
OS_P_NODATAno package in Pipe (with OS_NO_SUSP)
OS_TIMEOUTno package in Pipe (after waits)

Example

OS_P Pipe1; void OS_FAR Task1(void *data) { U08 state; U16 rLenght; U08 Receive[1024]; . . while(1) { . state = OS_PipePend(&Pipe1, Receive, &rLenght, OS_SUSPEND); . } }





OS_PipePendAbbort

U08 OS_PipePendAbbort(OS_P *pp)

Abborts waiting of a receiving Tasks (highest waiting prio) on a Pipe. It is only the waiting task with the highest priority quasi "premature" to TimeOut forwarded.


Parameters

*pppointer to Pipe

Return Value

OS_NO_ERRpending of a task abborted
OS_TASK_NOT_EXISTno pending task on this Pipe

Example

OS_P Pipe1; void OS_FAR Task1(void *data) { U08 state; . . while(1) { . state = OS_PipePendAbbort(&Pipe1); . } }





OS_PipePost

U08 OS_PipePost(OS_P *pp, U08 OS_HUGE *msg, U16 lenght, U16 timeout)

Sends one package into a Pipe. So the transmitter-buffer also dynamically allocated can be, the type declaration is OS_HUGE necessary on the other hand in order to be able to go down well away with an area over segment borders. With OS_NO_SUSP, it immediately is come back even if the Pipe was full and becomes with OS_SUSPEND as long as waited until the package can be written down, if necessary unending.


Parameters

*pppointer to Pipe
*msgpointer to data-paket
lenghtlenght of data-paket
timeoutkernel-ticks as waiting-time ( 1...65534 )

Return Value

OS_NO_ERRPackage in Pipe sent
OS_P_FULLPipe fully (with OS_NO_SUSP)
OS_P_LEN_ERRPackage too long
OS_TIMEOUTPipe fully (after waits)

Example

OS_P Pipe1; void OS_FAR Task1(void *data) { U08 state; U08 Message[]={"Hello World!"}; . . while(1) { . . state = OS_PipePost(&Pipe1, Message, strlen(Message), 500); . } }





OS_PipeFrontPost

U08 OS_PipeFrontPost(OS_P *pp, U08 OS_HUGE *msg, U16 lenght, U16 timeout)

Sends one package at the beginning of a Pipe. Consequently, this package first is finished reading again by the recipient (cuts in line). Since the transmitter-buffer can also be dynamically allocated, the type declaration is OS_HUGE necessary on the other hand in order to be able to go down well away with an area over segment borders. With OS_NO_SUSP, it immediately is come back even if the Pipe was full and becomes with OS_SUSPEND as long as waited until the package can be written down, if necessary unending.


Parameters

*pppointer to Pipe
*msgpointer to data-paket
lenghtlenght of data-paket
timeoutkernel-ticks as waiting-time ( 1...65534 )

Return Value

OS_NO_ERRPackage in Pipe sent
OS_P_FULLPipe fully (with OS_NO_SUSP)
OS_P_LEN_ERRPackage too long
OS_TIMEOUTPipe fully (after waits)

Example

OS_P Pipe1; void OS_FAR Task1(void *data) { U08 state; U08 Message[]={"Hallo Welt !"}; . . while(1) { . . state = OS_PipeFrontPost(&Pipe1, Message, strlen(Message), OS_NO_SUSP); . } }





OS_PipePostAbbort

U08 OS_PipePostAbbort(OS_P *pp)

Abborts waiting of a sending Tasks (highest waiting prio) on a Pipe. It is only the waiting task with the highest priority quasi "premature" to TimeOut forwarded.


Parameters

*pppointer to Pipe

Return Value

OS_NO_ERRposting of a task abborted
OS_TASK_NOT_EXISTno posting task on this Pipe

Example

OS_P Pipe1; void OS_FAR Task1(void *data) { U08 state; . . while(1) { . state = OS_PipePostAbbort(&Pipe1); . } }





OS_PipeClear

U08 OS_PipeClear(OS_P *pp)

Deletes the content of a Pipe and reactivates a waiting transmitter-process. This function can be used to reactivate the datatransfer after a hang-on. The deleted packages get lost on that occasion.


Parameters

*pppointer to Pipe

Return Value

OS_NO_ERRPipe-content deleted

Example

OS_P Pipe1; void OS_FAR Task1(void *data) { U08 state; . . while(1) { . . state = OS_PipeClear(&Pipe1); . } }





Semaphores




OS_SemInit

U08 OS_SemInit(OS_SEM *psem, U16 cnt)

Initialize a Semaphore. One semaphores serves the process-syncronisation. Two variations of the utilization belong semaphores to it to one.
- binary: for example the syncronisation of accesses on common recources/variables
- counting: Attendants on entering of a signal, to the control of the sequence of processes.

With a binary semaphore, a state-machine can become protected before simultaneous accesses of different processes (Read/Write), for example. So, inconsistent conditions or data are avoided. Can appear however in some cases Priority Inversion, occupied i.e. this a low Task the recource, a higher Task therefore must wait and then for example through an INT a middle Task (and its heirs) whom lower Task interrupts for an uncertain time. In such a case, it is initialized the semaphores with 1 as cnt, the access asked by means of OS_SemPend and released again by means of OS_SemPost.

With a counting semaphore, arriving is signalled by events. So, a process can wait for a signal to pause about the sequence of processes. By means of OS_SemAccept, also the number of the meanwhile entered events can be determined on that occasion. In such a case, it is initialized the semaphores with 0 as cnt, waited on the event by means of OS_SemPend or OS_SemAccept and reported the event by means of OS_SemPost.


Parameters

*psempointer to Semaphore

Return Value

OS_NO_ERRSemaphore initialized

Example

OS_SEM State1; void main(void) { U08 state; . . OS_Init(); . state = OS_SemInit(&State1, 1); . }





OS_SemPend

U08 OS_SemPend(OS_SEM *psem, U16 timeout)

Reserve one on the protected recource semaphore and consequently the access as well as wait for an event. With OS_NO_SUSP, it immediately is come back even if was not freely the semaphores as well as no event was available and becomes with OS_SUSPEND as long as waited until the semaphores the event could be reserved as well as could happen, if necessary unending.


Parameters

*psempointer to Semaphore
timeoutkernel-ticks as waiting-time ( 1...65534 )

Return Value

OS_NO_ERRSemaphore reserve / event was available
OS_SEM_NODATASemaphore occupy / no event (with OS_NO_SUSP)
OS_TIMEOUTSemaphore occupy / no event (after waits)

Example

OS_SEM State1; void OS_FAR Task1(void *data) { U08 state; . . while(1) { . state = OS_SemPend(&State1, OS_SUSPEND); . . } }





OS_SemPendAbbort

U08 OS_SemPendAbbort(OS_SEM *psem)

Abborts waiting of a Tasks (highest waiting prio) on a Semaphore. It is only the waiting task with the highest priority quasi "premature" to TimeOut forwarded.


Parameters

*psempointer to Semaphore

Return Value

OS_NO_ERRpending of a task abborted
OS_TASK_NOT_EXISTno pending task on this Semaphore

Example

OS_SEM State1; void OS_FAR Task1(void *data) { U08 state; . . while(1) { . state = OS_SemPendAbbort(&State1); . } }





OS_SemAccept

U08 OS_SemAccept(OS_SEM *psem, U16 *cnt, U16 timeout)

It is used as Event-Counter with utilization of the semaphores. The Semaphore-counter is not influenced on that occasion. If the counter bigger than 0 the current counter will return. With OS_NO_SUSP, it immediately is come back even if the semaphoren-counter 0 is and becomes with OS_SUSPEND as long as waited until the event once appeared, if necessary unending.


Parameters

*psempointer to Semaphore
*cntpointer to variable will get the counter-value
timeoutkernel-ticks as waiting-time ( 1...65534 )

Return Value

OS_NO_ERREvent min. 1 times happened
OS_SEM_NODATACounter immediately 0 (with OS_NO_SUSP)
OS_TIMEOUTCounter immediately 0 (after waits)

Example

OS_SEM Event1; void OS_FAR Task1(void *data) { U08 state; U16 EventCnt; . . while(1) { . state = OS_SemAccept(&Event1, &EventCnt, 500); . } }





OS_SemPost

U08 OS_SemPost(OS_SEM *psem)

Gives a retiring semaphore and consequently the access to the protected recource again freely as well as signals an event.


Parameters

*psempointer to Semaphore

Return Value

OS_NO_ERRSemaphores released / event reported
OS_SEM_OVFError in the Semaphore-handling (Counter too big)

Example

OS_SEM State1; void OS_FAR Task1(void *data) { U08 state; . . while(1) { . . state = OS_SemPost(&State1); . } }





OS_SemClear

U08 OS_SemClear(OS_SEM *psem)

Deletes the Counter of the semaphore. This function can be used to reset a counting-semaphore or for error-handling to restart the semaphore-handling. With application of binary semaphore to the control of accesses on a protected recource must be released the semaphore in the connection with application to the mistake-handling by OS_SemPost so much times, how simultaneously processes can access the recource.


Parameters

*psempointer to Semaphore

Return Value

OS_NO_ERRcount of semaphore reset to 0

Example

OS_SEM State1; void OS_FAR Task1(void *data) { U08 state; . . while(1) { . state = OS_SemClear(&State1); . } }





Mutexes




OS_MutexCreate

U08 OS_MutexCreate(OS_MUX *pmux, U08 prio)

Aims as well as initializing of a Mutex (Mutual-Exclusion). A Mutex serves the syncronisation of accesses to common recources/variables. With a Mutex, state-machines are protected from simultaneous accesses of different processes (Read/Write), for example. The second process must wait, until the first process finished his access (Read/Write). So, inconsistent conditions or data are avoided. In contrast to the utilization of semaphores, the effect of the Priority Inversion cannot kick open on that occasion here. The priority of the Mutex must be included higher, as the highest priority of the Tasks accessing it. The Mutex is written down as not current Task, so under the same priority no other Task can run.


Parameters

*pmuxpointer to Mutex

Return Value

OS_NO_ERRMutex written down and initialized

Example

OS_MUX Mutex1; void main(void) { U08 state; . . OS_Init(); . state = OS_MutexCreate(&Mutex1, 10); . }





OS_MutexPend

U08 OS_MutexPend(OS_MUX *pmux, U16 timeout)

Reserve a Mutex and consequently the access on the protected recource. With OS_NO_SUSP, it immediately is come back even if the Mutex was not free and becomes with OS_SUSPEND as long as waited until the Mutex could be reserved, if necessary unending.


Parameters

*pmuxpointer to Mutex
timeoutkernel-ticks as waiting-time ( 1...65534 )

Return Value

OS_NO_ERRMutex reserved
OS_MUX_NOACCMutex is occupied (with OS_NO_SUSP)
OS_TIMEOUTMutex is occupied (after waits)
OS_MUX_ERRError in Mutex-handling

Example

OS_MUX Mutex1; void OS_FAR Task1(void *data) { U08 state; . . while(1) { . state = OS_MutexPend(&Mutex1, OS_SUSPEND); . . } }





OS_MutexPendAbbort

U08 OS_MutexPendAbbort(OS_MUX *pmux)

Abborts waiting of a Tasks (highest waiting prio) on a Mutex.
It is only the waiting task with the highest priority quasi "premature" to TimeOut forwarded.


Parameters

*pmuxpointer to Mutex

Return Value

OS_NO_ERRpending of a task abborted
OS_TASK_NOT_EXISTno pending task on this Mutex

Example

OS_MUX Mutex1; void OS_FAR Task1(void *data) { U08 state; . . while(1) { . state = OS_MutexPendAbbort(&Mutex1); . } }





OS_MutexPost

U08 OS_MutexPost(OS_MUX *pmux)

Gives a reserved Mutex free and again the access on the protected recource.


Parameters

*pmuxpointer to Mutex

Return Value

OS_NO_ERRMutex released
OS_MUX_ERRError in Mutex-handling

Example

OS_MUX Mutex1; void OS_FAR Task1(void *data) { U08 state; . . while(1) { . . state = OS_MutexPost(&Mutex1); . } }





Event-Groups




OS_EvgInit

U08 OS_EvgInit(OS_EVG *pevg)

Initialize an Eventgroup. An Eventgroup consists individually can be processed of 32 single-events, that summarized in an ULONG, as also grouped. Each Event within the group can report the appearance of an event, however any statement about it doesn't meet, how often the event appeared in the meantime. In order to also be able to count events, you must be used semaphores as Counting-Semaphore for every individual event. (semaphore with 0 initialize, at appearance of the event "OS_SemPost" and when wait "OS_SemAccept")


Parameters

*pevgpointer to Eventgroup

Return Value

OS_NO_ERREvent-group initialized

Example

OS_EVG Events1; void main(void) { U08 state; . . OS_Init(); . state = OS_EvgInit(&Events1); . }





OS_EvgPost

U08 OS_EvgPost(OS_EVG *pevg, U32 events, U08 mode)

Report the appearance an as well as several Events of an Eventgroup. The bit mask is interpreted as OR of the Events on that occasion. I.e. all Events, that are set in the bit mask, are reported. Mode is used the utilization of this function for the erasure of Events.


Parameters

*pevgpointer to Eventgroup
eventsbit-mask of events
modemode of usement "OS_EVG_OR / OS_EVG_CLR"

Return Value

OS_NO_ERREvent(s) reported

Example

OS_EVG Events1; void OS_FAR Task1(void *data) { U08 state; . . while(1) { . state = OS_EvgPost(&Events1,~0x00101000, OS_EVG_CLR); // clear this events state = OS_EvgPost(&Events1, 0x01000100, OS_EVG_OR); // set this events . } }





OS_EvgPend

U08 OS_EvgPend(OS_EVG *pevg, U32 *events, U08 mode, U16 timeout)

Waits on one as well as several Events of an Eventgroup. The bit mask is interpreted modes as connection of the Events on that occasion together with him. I.e., already an Event, that is set in the bit mask, is enough with OS_EVG_OR for the function and with OS_EVG_AND, all Events, that are set in the bit mask, had to arrive. For a special case events of an Eventgroup can wake up multiple tasks at once. For this the Eventgroup differs on EvgPend and EvgPost between "OS_EVG_OR_C / OS_EVG_AND_C" for normal use (consuming event) or just "OS_EVG_OR / OS_EVG_AND" to wake up multiple tasks. But the events are then manually to delete again by a task. After returning the bit mask contains the occurred events that triggered the return. With OS_NO_SUSP, it immediately is come back even if no Event appeared and becomes with OS_SUSPEND as long as waited until the Event(s) appeared, if necessary indefinitely.


Parameters

*pevgpointer to Eventgroup
*eventspointer to bit-mask of events waiting for, returns the events on return
modemode of usement "OS_EVG_OR_C / OS_EVG_AND_C"
timeoutkernel-ticks as waiting-time ( 1...65534 )

Return Value

OS_NO_ERREvent(s) appeared
OS_EVG_NOEEvent(s) not appeared (with OS_NO_SUSP)
OS_TIMEOUTEvent(s) not appeared (after waits)

Example

OS_EVG Events1; void OS_FAR Task1(void *data) { U32 event; U08 state; . . while(1) { . event = 0x00100100; state = OS_EvgPend(&Events1, &event, OS_EVG_OR_C, OS_SUSPEND); . } }





OS_EvgPendAbbort

U08 OS_EvgPendAbbort(OS_EVG *pevg)

Abborts waiting of a task (highest waiting prio) onto a Eventgroup. It is only the waiting task with the highest priority quasi "premature" to TimeOut forwarded.


Parameters

*pevgpointer to Eventgroup

Return Value

OS_NO_ERRpending of a task abborted
OS_TASK_NOT_EXISTno pending task on this eventgroup

Example

OS_EVG Events1; void OS_FAR Task1(void *data) { U08 state; . . while(1) { . state = OS_EvgPendAbbort(&Events1); . } }





Timer-Service




OS_TimerCreate

U08 OS_TimerCreate(OS_TMR *ptmr, U32 time, void(*tFct)(void *), void *tArg, U08 mode)

Creating / initialize a timer.
A timer can e.g. for subsequent purposes:
• timeouts within protocol layers and applications such as TCP / IP, X25, HTTP, FTP, ...
• prevent the "starvation" of tasks by defining a timeout and corresponding measures such as priority raising or other
• Periodic management of services
• soft-deadline / watchdog of services

As mode subsequent details can be made:
• OS_TMR_ENABLE - starts the Timer immediately
• OS_TMR_RONCE - Timer is of type "run-once", this means single timeout and after it is automatically disabled, but remains registered
• OS_TMR_CYCL - Timer is of type "cyclic / periodic" this means the timer will automatically restarted after each timeout
• OS_TMR_CLR - Timer is of type "run-once auto-erase," this means the timer is single timeout and is automatically deleted and must be created new for further use

It is OS_TMR_CLR the scheme goes before OS_TMR_CYCL and this before OS_TMR_RONCE.

The registered callback function should be as short as possible. For information-sharing an argument can be used.


Parameters

*ptmrpointer to Timer
timetimeout of this timer (in timer-ticks)
tFctaddress of timeout-callback function
tArgargument of timeout-callback function
modemode of this timer (run-once / cyclic / auto-clear)

Return Value

OS_NO_ERRTimer registered and initialized
OS_TMR_NO_TIMEno valid time a parameter given (time == 0)
OS_TMR_EXISTTimer was still registered and initialized

Example

OS_TMR Timer1; void TCP_To_CB(void *session) { OS_QueuePost(&TCPIP_To_Q, (U08)session, OS_NO_SUSP); } U08 TCP_send(void) { U08 state; U08 session; . . state = OS_TimerCreate(&Timer1, 30, TCP_To_CB, &session, OS_TMR_ENABLE | OS_TMR_CLR); . }





OS_TimerDelete

U08 OS_TimerDelete(OS_TMR *ptmr)

Deactivate and delete a Timer.


Parameters

*ptmrpointer to Timer

Return Value

OS_NO_ERRTimer deleted
OS_TMR_NOT_EXISTthe Timer was not registered

Example

OS_TMR Timer1; void OS_FAR Task1(void *data) { U08 state; . . while(1) { . state = OS_TimerDelete(&Timer1); . . } }





OS_TimerStart

U08 OS_TimerStart(OS_TMR *ptmr, U32 time)

Starts a deactivated, restart a run-once or restart a running Timer.


Parameters

*ptmrpointer to Timer
timenew timeout (if not zero) of this timer (in timer-ticks)

Return Value

OS_NO_ERRTimer (re-)started
OS_TMR_NOT_EXISTthe Timer is not registered

Example

OS_TMR Timer1; void OS_FAR Task1(void *data) { U08 state; . . while(1) { . state = OS_TimerStart(&Timer1, 0); . . } }





OS_TimerStop

U08 OS_TimerStop(OS_TMR *ptmr)

Stops / deactivat a running Timer.


Parameters

*ptmrpointer to Timer

Return Value

OS_NO_ERRTimer stopped
OS_TMR_NOT_EXISTthe Timer is not registered

Example

OS_TMR Timer1; void OS_FAR Task1(void *data) { U08 state; . . while(1) { . . state = OS_TimerStop(&Timer1); . } }





OS_TimerGetState

U08 OS_TimerGetState(OS_TMR *ptmr)

Returns the status of a created timer.
The following information is provided:
• OS_TMR_ENABLE - the Timer is actually running
• OS_TMR_RONCE - Timer is of type "run-once", this means single timeout and after it is automatically disabled, but remains registered
• OS_TMR_CYCL - Timer is of type "cyclic / periodic" this means the timer will automatically restarted after each timeout
• OS_TMR_CLR - Timer is of type "run-once auto-erase," this means the timer is single timeout and is automatically deleted and must be created new for further use

If in the returns status not OS_TMR_ENABLE but OS_TMR_CLR, the timer was never created or the timer was "run-once auto-erase" and the time had expired.


Parameters

*ptmrpointer to Timer

Return Value

statusstatus of the timers (see "modi" on OS_TimerCreate)

Example

OS_TMR Timer1; void OS_FAR Task1(void *data) { U08 state; . . while(1) { . . state = OS_TimerGetState(&Timer1); if(state & OS_TMR_ENABLE) { . . } . } }





OS_TimerGetRemain

U32 OS_TimerGetRemain(OS_TMR *ptmr)

Returns the remaining time (in timer-ticks) of a running timer.
Is the returned time equal to 0, the timer was expired or was never activated by OS_TimerCreate.


Parameters

*ptmrpointer to Timer

Return Value

timeremaining time in timer-ticks

Example

OS_TMR Timer1; void OS_FAR Task1(void *data) { U32 rtime; . . while(1) { . . rtime = OS_TimerGetRemain(&Timer1); . } }





System-Ticks




OS_TimeSet

void OS_TimeSet(U32 ticks)

Places the kernel-internal Tick-Counter on handed over value.


Parameters

ticksnew value of tick-counter

Return Value

none

Example

void OS_FAR Task1(void *data) { . . while(1) { . OS_TimeSet(24837); . } }





OS_TimeGet

U32 OS_TimeGet(void)

It returns the current value of the kernel-internal Tick-Counter.


Parameters

none

Return Value

ticksactual value of tick-counter

Example

void OS_FAR Task1(void *data) { U32 time; . . while(1) { . time = OS_TimeGet(); . } }





Interrupts




OS_IntEnter

void OS_IntEnter(void)

Register an Interrupt-Level. No contextswitch are generated by it. This function is necessary for C-Code ISRs.


Parameters

none

Return Value

none

Example

void OS_FAR ISR1(void) { OS_IntEnter(); . . . OS_IntExit(); }





OS_IntExit

void OS_IntExit(void)

Unregister an Interrupt-Level. Contextswitches are generated again by it. This function is necessary for C-Code ISRs.


Parameters

none

Return Value

none

Example

void OS_FAR ISR1(void) { OS_IntEnter(); . . . OS_IntExit(); }





History




OS_HistoryPost

U08 OS_HistoryPost(U32 param1, U32 param2)

Writes down an entry into the History-Table of the kernel. Additional to the two parameters still becomes the priority of the Tasks and the Tick-Counter, as time stamps, written down.


Parameters

param1first 32-bit parameter for table
param2secound 32-bit parameter for table

Return Value

OS_NO_ERREntry written

Example

OS_Q Queue5; void OS_FAR Task2(void *data) { U08 state; U08 Message; . . while(1) { . Message = 0x2D; state = OS_QueueFrontPost(&Queue5, Message, 200); if(state != OS_NO_ERR) OS_HistoryPost((U32)state, 0x0205); . } }





OS_HistoryRead

U08 OS_HistoryRead(U32 *param1, U32 *param2, U08 *prio, U32 *time)

Reads next entry from the History-Table of the kernel and deletes this on that occasion.


Parameters

*param1pointer to variable will get the first 32-bit parameter
*param2pointer to variable will get the secound 32-bit parameter
*priopointer to variable will get priority of task who has this written
*timepointer to variable will get time-stamp of this entry

Return Value

OS_NO_ERREntry read
OS_HIS_ENDno entry existing

Example

void OS_FAR Task3(void *data) { U08 state; U32 Hpara1; U32 Hpara2; U08 Tprio; U32 stamp; . . while(1) { . state = OS_HistoryRead(&Hpara1, &Hpara2, &Tprio, &stamp); . } }