pC/OS
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.
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 und Keil-C51 generated. OS_CFG implemented. Bugfix in Semaphores. * Port for 8051 added |
1.00h | MUTEXes added, Eventgruppen 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 STR71x 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 Luminary 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 alltimes 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 PIC32MX 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 NXP LPC11xx added * Port for Cortex-M3 NXP LPC13xx added * Port for Cortex-M3 NXP LPC17xx added * Port for Cortex-M3 Microchip/Atmel AT91SAM3xxx added |
1.83b | mini fix in OSTCBInit(..) for missing compiler switch |
1.84a | change events param in eventgroups to pointer for better handling of OR mode (with return), small fix in Pipe for fast data switching * Port for Cortex-M4 ST STM32F4xx added |
1.85b | correction in eventgroups for multiple pending tasks on one eventgroup |
1.86a | OS_ID_SELF added for OS_TaskIdDelete() and OS_TaskGetPrio() * Port for Cortex-M0 Microchip/Atmel SAMD21 added |
1.87b | an interrupt and during sheduling is switched off a sender can't use the fast mode on OS_Pipe...Post since data source can't be guarantied * Ports for Cortex-M23 and Cortex-M33 (ARMv8M baseline & mainline) added (w/o active TZ support) * Port for Cortex-M3 TI Luminary LM3S9B92 added * Port for Cortex-M0 Nuvoton NUC123 added * Port for Cortex-M0 Freescale MKL25Z128 added * Port for Cortex-M0 Freescale MKL26Z64 added * Port for Cortex-M4 Freescale MK20DX256 added * Port for Cortex-M4 Freescale MK60DN512 added * Port for Cortex-M4 Freescale MK66FX1M added * Port for Cortex-M0 Infineon XMC1100 added * Ports for Cortex-M0..7 ST STM32F0xx..7xx renewed * Port for RISC-V SiFive FE310 added * Port for ARC-EM from Synopsys added (w/o active SecureShield support) * Port for Cortex-M3 Silicon Labs EFM32 added * Ports for MIPS32 M4K Microchip PIC32MX renewed * Port for MIPS32 M51xx Microchip PIC32MZ added * Ports for Renesas RX210 & RX62N added * Port for Renesas V850 added * Port for Renesas RL78 added * Ports for Cortex-M23 Microchip/Atmel SAML10 & SAML11 added * Port for Cortex-M4 Microchip/Atmel SAMD51 added * Port for Cortex-M23 Nuvoton M2351 added * Port for Cortex-R4 TI TMS570LS04 added * Port for Cortex-M23 GigaDevices GD32E230K added |
1.88c | the IPC 'Pipe' now can use the memory manager internally as message storage instead of the fix created array, but warning - it requires additional time and can result in some side-effects * Port for Cortex-M7 Microchip/Atmel SAMS70 added * Port for Cortex-M4 ST STM32L4xx added * Port for Cortex-M4 Nordic Semiconductor nRF52832 added * Port for powerPC NXP/Freescale MPC57xx added |
1.90b | SmartMessageQueue as an alternative to MessageBox added. The SmartMessageQueue transfers messages as pure pointers. If the pointer points to an allocated memory block, the ownership of this block is also transferred. If the pointer does not point to an allocated memory block, the risk remains with the user as a unspezific pointer is passed directly. * Port for Cortex-M4F Ambiq Micro Apollo3 added |
1.91c | fix in Memory-Manager for Malloc & Free of kernel requests * Port for Cortex-M3 GigaDevices GD32F103 added * Port for RISC-V GigaDevices GD32VF103C added * Port for Cortex-M33 ST STM32L5xx added * Port for Cortex-M33 NXP LPC55S69 added |
1.94b | task initialization restructured and some minor corrections added. |
1.95c | Dual-Core AMP-Pipe as inter-core messaging pipe (Inter Core Communication) added. * Port for dual-core Cortex-M7/M4 STM STM32H745 added * Port for dual-core Cortex-M4/M0 NXP LPC4337 added * Port for Cortex-M4 STM STM32G4xx added * Port for PIC32MM added * Port for PIC24FJ added * Port for Cortex-M7 STM STM32H750 added * Port for Cortex-M33 GigaDevice GD32E50x added * Ports for Cortex-M4 GigaDevice GD32F303 & GD32F407 added * Port for Cortex-M4 Artery AT32F403A added * Port for Cortex-M0 STM STM32G0xx added * Ports for RISC-V WCH CH32V103 & CH32V307 added * Port for Cortex-M0 Synwit Tech SWM181 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.95c (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: | Description |
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 | It suppresses of the Sheduler (no taskswitch) |
OS_Unlock | In again circuit of the Sheduler (taskswitch at event or time) |
OS_GetRev | It returns pointer to kernel revision |
Semaphores: | Description |
OS_SemInit | Initalisation of a semaphore |
OS_SemAccept | wait for event and returns number |
OS_SemPost | Release of a busy semaphores / places event |
OS_SemPend | Cover one semaphore / waits on event |
OS_SemPendAbbort | Cover one semaphore / waits on event |
OS_SemClear | Clear the semaphore-counter |
Mutexes: | Description |
OS_MutexCreate | Generating of a mutex |
OS_MutexPost | Release of a mutex |
OS_MutexPend | Cover the mutex |
OS_MutexPendAbbort | Abborts waiting of a task (highest waiting prio) onto a mutex |
Event-Groups: | Description |
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 |
Mailboxes: | Description |
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: | Description |
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 |
SmartMessageQueue: | Description |
OS_SMQueueInit | Initialsation of a SmartMessageQueue |
OS_SMQueueInfo | Information about a SmartMessageQueue catches up with |
OS_SMQueueClear | Delete all messages in a SmartMessageQueue |
OS_SMQueuePost | Send a message into a SmartMessageQueue |
OS_SMQueueFrontPost | Send a message to the beginning of a SmartMessageQueue |
OS_SMQueuePostAbbort | Abborts waiting of a sending task (highest waiting prio) onto a SmartMessageQueue |
OS_SMQueuePend | Wait for a message from a SmartMessageQueue |
OS_SMQueuePendAbbort | Abborts waiting of a receiving task (highest waiting prio) onto a SmartMessageQueue |
Pipes: | Description |
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 |
inter-core AMP-Pipes: | Description |
OS_IccInit | Initialisation of the AMP-Pipe pair |
OS_IccInfo | Information about the AMP-Pipe pair catches up with |
OS_IccPost | Send data to the other core |
OS_IccPend | wait for data from the other core |
OS_IccClear | Delete all data of the AMP-Pipe towards the other core |
Timer-Service: | Description |
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: | Description |
OS_TimeSet | Set ticker to value |
OS_TimeGet | returns current ticker-value |
Interrupts: | Description |
OS_IntEnter | Registration of a called ISR |
OS_IntExit | End of a called ISR |
Dynamic-Memory: | Description |
OS_MemoryInit | Generates of the memory pool |
OS_MemAlloc | Allocation of memory |
OS_MemFree | Release of allocated memory |
OS_MemFreeSize | It returns the amount of free memory |
OS_MemVerifyPtr | checks, if pointer points inside of the memory pool |
History: | Description |
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_SUCCESS / OS_NO_ERR | 0 |
OS_PARAM_ERR | 1 |
OS_TIMEOUT | 10 |
OS_PRIO_EXIST | 11 |
OS_TASK_NOT_EXIST | 12 |
OS_TASK_SUSP_PRIO | 13 |
OS_TASK_NOT_SUSP | 14 |
OS_TASK_NOT_RDY | 15 |
OS_SUSPEND_IDLE | 16 |
OS_PRIO_INVALID | 17 |
OS_TIME_NOT_DLY | 18 |
OS_SEM_ERR | 30 |
OS_SEM_NODATA | 31 |
OS_SEM_OVF | 32 |
OS_MUX_ERR | 40 |
OS_MUX_NOACC | 41 |
OS_MUX_USED | 42 |
OS_MBOX_FULL | 50 |
OS_MBOX_NODATA | 51 |
OS_Q_FULL | 60 |
OS_Q_NODATA | 61 |
OS_Q_CLEAR | 62 |
OS_SMQ_ERR | 70 |
OS_SMQ_FULL | 71 |
OS_SMQ_NODATA | 72 |
OS_SMQ_CLEAR | 73 |
OS_P_FULL | 80 |
OS_P_NODATA | 81 |
OS_P_CLEAR | 82 |
OS_P_LEN_ERR | 83 |
OS_EVG_ERR | 90 |
OS_EVG_NOE | 91 |
OS_TMR_NO_TIME | 110 |
OS_TMR_NOT_EXIST | 111 |
OS_TMR_EXIST | 112 |
OS_MEM_ERR | 120 |
OS_MEM_OVF | 121 |
OS_HIS_END | 130 |
OS_ICC_ERR | 140 |
OS_ICC_NODATA | 141 |
OS_ICC_LEN_ERR | 142 |
OS_ICC_FULL | 143 |
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)
und am Ende der ISR: