To this for beginners at the the fastest to understand real time operating system belongs µC/OS from Jean J. Labrosse. It can administer up to 63 applikationtasks with ever different priorities and belongs to the real time operating systems with the lowest storage demand.
Since the original version from the Embedded System Programming Magazine(1992) FREE is, I deposited these for interrests to download.

Since the company Micrium the source-code distribution license conditions also for the original version from the Embedded Programming Magazine(1992) altered, I can only put a link to the download-side of the magazine here.

Embedded Systems Programming Magazine(1992) - code area


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 and dynamic memory management.
In order to declare these alterations unequivocally, I have the name, ajar at the always bigger nascent original "µC/OS", on pC/OS like "pico-C.." altered.


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


To final clarify the status of the pC/OS Kernel based on the µC/OS 1.00,
I picked out the old "V1.00 is FREE" confirmation email from Jean Labrosse.



pCOS_183a.zip
download pC/OS 1.83a (as ZIP)


Releases:

1.00a

Messagebox and Queue altered as well as Pipe, Eventgroup and dyn. Memory management added.
* Port for Am188ES created

1.00b

Revision info, Tick-counter, Task-Suspension, Task-Delete, History-Table and OS_QueueFrontPost added (Task-Suspension and Task-Delete from 1.09 imports)
Some of bow fix from 1.01 to 1.09 taken over.

1.00c

Acceleration of the Pipe, with taskswitch on reason of the data transfer and if Pipe become copy the data of the sending-buffer empty in the receiver-buffer.
Implementation of a wait for stations, OS_..... Post.
Not implements attendants for stations and recipients by means of OS_NO_SUSP.
To aim, of Queue and Pipe, specifically: Pointers on Kernel-buffer, revises.

1.00d

correct implementation "timeout" in OS_....Post functions and OS_QueueClear added.

1.00e

Adaptation the Task-Initialistion and some parameter to the utilization of the µC/OS-I Port's.
OS_QueueInfo and OS_PipeInfo added.

1.00f

Bug fix within the Event-Groups.
OS_SemAccept added.

1.00g

Dual-Source for MSC-8.00 and Keil-C51 generated. OS_CFG implemented. Bugfix in Semaphores.
* Port for 8051 added

1.00h

MUTEXes added, Eventgroups correct implemented and code-cleanup. Cleanup of the ports.
* Port for Rabbit 2000/3000 added
* Port for Philips-XA added

1.40a

Name on pC/OS altered and revision number revises, some C-fixes.
* Port for ATMega128 added
* Port for AT91SAM7Sxx added

1.41a

Implementation of OS_STK_TYPE for processor conform stack incl. update of all existing ports.
Keil-version of AT91SAM7Sxx-port (instable) added

1.50c

Complete update to U08..U32 types.
Implementation of OS_PACKED, OS_PACKED_ATTR and align(x)-corrections.
small correction in OS_TaskSuspend().
* Port for LPC214x added
* Port for LPC236x added
* Port for STR711 added

1.52b

Split MIN_PRIO and MAX_TASKS to reduce RAM on smaller max-tasks, using "NULL" as pointer, add unique task-ID for other modules on use of prio-changes and to reduce RAM on this modules.
* Port for Cortex-M3 LM3S811 added

1.60c

add temporary reg-holder for disabling/enabling interrupts inside of a ISR as protection again neested ints, if this is undesirable
* Port for Cortex-M3 STM32 added

1.61a

the memory-manager now works altimes MPU-spezific aligned

1.65b

timer-service implemented, his timers can run periodical or run-once.
some new API-functiones added

1.66c

some checks added in TIMERS, OS_TimerGetState() and OS_TimerGetRemain() implemented

1.67a

reducing RAM consumption on prio-tables of IPC-recources (SEM/EVG/MUX/Queue/Pipe/..)
* Port for PIC32 added
* Port for MSP430 added

1.68a

OS_EvgPendAbbort() added
* Port for AVR32 added

1.70b

optional debug stack-end check added, kernel configuration restructured

1.71a

additional optional stack-fill to stack-end check feature added

1.80c

some fixes in all ...Abbort() functions, some additional checks for "mutex in use", OS_TaskGetID() and OS_TaskGetStatus() added, with new OS_TaskDestroy() now tasks - waiting on a resource - can deleted too, source file splitted for better handling
* Port for ATMega32 added

1.81b

through an extension in the optional function OS_TaskDestroy() a mutex protected recourse can now be re-initialized, even if a user management included based on the unique task ID (for example a filesystem)

1.82a

OS_TaskDestroy() renamed to OS_TaskIdDestroy(), OS_TaskGetPrio(), OS_TimeDelayIdResume(), OS_TaskIdDelete(), OS_TaskIdGetStatus(), OS_TaskIdSyspend() and OS_TaskIdResume() added plus some additional checks for prio and/or id

1.83a

small fix for OS_TaskIdDestroy() in OSIntExit(), if the current running task destroyed by an ISR
* Port for Cortex-M0 LPC11xx added
* Port for Cortex-M3 LPC13xx added
* Port for Cortex-M3 LPC17xx added
* Port for Cortex-M3 AT91SAM3xxx added



With waits for "OS_.... Post" and "OS_.... Pend" - functions heeding is that can be done with a wait or even suspension out with a call of a transmitter-/receiver functions from an ISR NEVER, since the ISR stops this, and consequently nothing more runs. An examination of this condition is integrated.

known bugs:
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.

Kernelservices of the pC/OS version 1.83a (abbreviation)

This here presented function overview only serves as short overview.
For detailed information, you please look in Reference-Manual about pC/OS.


Task-Control:

 

OS_Init

Initialization of the kernel

OS_Start

Begin the kernelservices

OS_TaskCreate

Generating of a task

OS_ChangePrio

Alteration of the priority of the active task

OS_TaskChangePrio

Alteration of the priority of a active/ready task

OS_TaskDelete

Deletion of a active/ready task

OS_TaskIdDelete

Deletion of a active/ready task via unique ID

OS_TaskGetStatus

returns the current status of a task

OS_TaskIdGetStatus

returns the current status of a task via unique ID

OS_TaskGetID

returns the unique ID of a task

OS_TaskGetPrio

returns the priority of a task

OS_TaskIdDestroy

Deletion of a tasks via unique ID, even if it waits for an IPC or a mutex has locked & release all memory allocations

OS_TaskSuspend

Suspending of a task

OS_TaskIdSuspend

Suspending of a task via unique ID

OS_TaskResume

Reactivation of a suspended task

OS_TaskIdResume

Reactivation of a suspended task via unique ID

OS_TimeDly

Put current task for certain time sleeps

OS_TimeDlyResume

Reactivation of an asleep task before course of the put in time

OS_TimeDlyIdResume

Reactivation of an asleep task via unique ID before course of the put in time

OS_Lock

If suppresses of the Sheduler (no taskswitch)

OS_Unlock

In again circuit of the Sheduler (taskswitch at event or time)

OS_GetRev

If pointer returns on kernel revision

 

Dynamic-Memory:

 

OS_MemoryInit

Generates of the memory pool

OS_MemAlloc

Allocation of memory

OS_MemFree

Release of allocated memory

 

Mailboxes:

 

OS_MboxInit

Initialisation of a mailbox

OS_MboxPost

Send data to task with higher priority recipients of this mailbox

OS_MboxPostAbbort

Abborts waiting of a sending task (highest waiting prio) onto a mailbox

OS_MboxPend

Wait for data from a mailbox

OS_MboxPendAbbort

Abborts waiting of a receiving task (highest waiting prio) onto a mailbox

 

Queues:

 

OS_QueueInit

Initialsation of a queue

OS_QueueInfo

Information about a queue catches up with

OS_QueuePost

Send data into a queue

OS_QueueFrontPost

Send data to the beginning of a queue

OS_QueuePostAbbort

Abborts waiting of a sending task (highest waiting prio) onto a queue

OS_QueuePend

Wait for data from a queue

OS_QueuePendAbbort

Abborts waiting of a receiving task (highest waiting prio) onto a queue

OS_QueueClear

Delete all data in a queue

 

Pipes:

 

OS_PipeInit

Initialisation of a pipe

OS_PipeInfo

Information about a pipe catches up with

OS_PipePost

Send data into a pipe

OS_PipeFrontPost

Send data to the beginning of a pipe

OS_PipePostAbbort

Abborts waiting of a sending task (highest waiting prio) onto a pipe

OS_PipePend

Wait for data from a pipe

OS_PipePendAbbort

Abborts waiting of a receiving task (highest waiting prio) onto a pipe

OS_PipeClear

Delete all data in a pipe

 

Semaphores:

 

OS_SemInit

Initalisation of a semaphore

OS_SemAccept

wait for event and returns number

OS_SemPost

Decontrol of a busy semaphores / places event

OS_SemPend

Cover one semaphore / waits on event

OS_SemPendAbbort

Abborts waiting of a task (highest waiting prio) onto a semaphore

OS_SemClear

Clear the semaphore-counter

 

Mutexes:

 

OS_MutexCreate

Generating of a mutex

OS_MutexPost

Decontrol of a mutex

OS_MutexPend

Cover the mutex

OS_MutexPendAbbort

Abborts waiting of a task (highest waiting prio) onto a mutex

 

Event-Groups:

 

OS_EvgInit

Initialisation of a Eventgroup

OS_EvgPost

Place one/many events of an Evengroup

OS_EvgPend

Wait for arriving an or several events of an Eventgroup

OS_EvgPendAbbort

Abborts waiting of a task (highest waiting prio) onto a Eventgroup

 

Timer-Service:

 

OS_TimerCreate

Generating of a Timer

OS_TimerDelete

Deleting of a generated Timer

OS_TimerStart

(Re-)Start of a generated Timer

OS_TimerStop

Stop of a generated Timer

OS_TimerGetState

returns the status of a generated Timer

OS_TimerGetRemain

returns the remaining time of a running Timer

 

System-Ticks:

 

OS_TimeSet

Set ticker to value

OS_TimeGet

returns current ticker-value

 

Interrupts:

 

OS_IntEnter

Registration of a called ISR

OS_IntExit

End of a called ISR

 

History:

 

OS_HistoryPost

Write entry in History

OS_HistoryRead

First History-entry give and delete this in the table

 

Error-Codes:

Name

Decimal_Value

OS_SUCCESS / OS_NO_ERR

0

OS_TIMEOUT

10

OS_MBOX_FULL

20

OS_MBOX_NODATA

21

OS_Q_FULL

30

OS_Q_NODATA

31

OS_Q_CLEAR

32

OS_PRIO_EXIST

40

OS_TASK_NOT_EXIST

41

OS_SEM_ERR

50

OS_SEM_NODATA

51

OS_SEM_OVF

52

OS_MUX_ERR

55

OS_MUX_NOACC

56

OS_MUX_USED

57

OS_P_FULL

60

OS_P_NODATA

61

OS_P_CLEAR

62

OS_P_LEN_ERR

63

OS_MEM_ERR

70

OS_MEM_OVF

71

OS_EVG_ERR

80

OS_EVG_NOE

81

OS_HIS_END

90

OS_SUSPEND_IDLE

100

OS_PRIO_INVALID

101

OS_TIME_NOT_DLY

102

OS_TASK_SUSP_PRIO

103

OS_TASK_NOT_SUSP

104

OS_TASK_NOT_RDY

105

OS_TMR_NO_TIME

106

OS_TMR_NOT_EXIST

107


Tip to ASM-ISR's:

To integrate assembler-ISR's in to pC/OS manually, following start code must be implemented with in jump into the ISR: (example x86)

EXTRN C OSIntEnter : NEAR EXTRN C OSIntExit : NEAR ... ISR: pusha ; save all used register push es call OSIntEnter ; C-function to register INT-level ...

and at the end of the ISR:

... call OSIntExit ; C-function to unregister INT-Level ; and perform a context-switch is needed pop es ; restore all used register popa iret ; return