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.
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.
Releases:
1.00a | Messagebox and Queue altered as well as Pipe, Eventgroup and dyn. Memory management added. |
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) |
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. |
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. |
1.00f | Bug fix within the Event-Groups. |
1.00g | Dual-Source for MSC-8.00 and Keil-C51 generated. OS_CFG implemented. Bugfix in Semaphores. |
1.00h | MUTEXes added, Eventgroups correct implemented and code-cleanup. Cleanup of the ports. |
1.40a | Name on pC/OS altered and revision number revises, some C-fixes. |
1.41a | Implementation of OS_STK_TYPE for processor conform stack incl. update of all existing ports. |
1.50c | Complete update to U08..U32 types. |
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. |
1.60c | add temporary reg-holder for disabling/enabling interrupts inside of a ISR as protection again neested ints, if this is undesirable |
1.61a | the memory-manager now works altimes MPU-spezific aligned |
1.65b | timer-service implemented, his timers can run periodical or run-once. |
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/..) |
1.68a | OS_EvgPendAbbort() 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 |
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 |
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)
and at the end of the ISR: