To find out more generally about MicroC/OS, read the book listed below by Labrosse. There is also a partial API summary by Nancy Minderman at the University of Alberta and a terse summary from Micrium. There is a very complete list of functions from Departamento de Arquitectura de Computadores (DAC) en la Escola Politècnica Superior de Castelldefels (EPSC) (campus de la Universitat Politècnica de Catalunya). There is a good MicroC/OS summary at Zworld, but you will have to filter out the device-specific material.
MicroC/OS allows you to define several functions in C, each of which can execute as an independent thread or task. Each task runs at a different priority, and thinks that it owns the CPU. Lower priority tasks can be prempted by higher priority tasks at any time. Higher priority tasks use operating system services (such as a delay or event) to allow lower priority tasks to execute. There are operating system services provided for task managment, inter-task communication, memory managment, and for timing.
MicroC/OS services include:
Interrupt service routines can be integrated into MicroC/OS programs as long as the OS is informed of the interrupt. ISRs should be short and essentially just signal a normal (high priority) task to execute. See example 3 below.
Examples:
sof
and ptf
files define the system. Out0
to a DDS (direct digital synthesis) unit for sine wave production. In0
is connected to the DE2 switches and the 8-bit In1
connected to the pushbuttons. See NiosII C examples, example #3 for more information on the DDS. Note that in system.h
(generated by the library builder) that the names of the i/o ports are UPPERCASED. After the workspace is defined in the IDE, the system library properties need to be set up for the RTOS as shown below. Clicking the RTOS Options
button allows you to choose exactly what OS modules you want to include. The default is to include every module, which results in a minimum 120 kByte executable. The Altera Tutorial gives more detail on setting up the system library. main
defines OS data structures and tasks. OS data structures (in this example, a message queue and a semaphore) used by more than one task need to be global. OSTimeDlyHMSM
causes Task 1 to block for a time interval, but does not affect the execution of other tasks. OSQPend
causes Task 2 to wait for a message in the queue, while OSSemPend
causes Task 2 to wait for a signal from Task 1. If a task does not call an OS service which causes it to wait, then no lower priority task will ever execute! OSTimeDly
set to 7 mSec), task 4 never gets a chance to run because task processing, context switches and OS overhead is eating the cpu.
stdio.h
. Using it is just a matter of opening a device using fopen
and writing to it using fprintf
. The device driver recognizes ansi escape codes to control the cursor position. This GCC program is a modification of example 1. Task 1 can clear the LCD when KEY1 is pushed and Task 3 prints its stack size to stdout
and the OS tick time to the LCD. The LCD file device is opened in main
. The frequency accuracy of the DDS was reduced to increase its dynamic range in frequency. As shown, the DDS can reproduce sine waves from DC to over one MHz with an accuracy of about .012 Hz at low frequencies and an accuracy limited by the crystal at high frequencies. OSIntEnter()
or OSIntExit()
in the ISR because the interrupt handler is aware of the operating system and handles it. The details can be found in the main interrupt handler, alt_irq_handler()
(To find the source file, open the tabs in the left-most IDE panel: syslib / DeviceDrivers[nios] / altera_hal / HAL / src)
. More details on saving context are in alt_irq_entry.S
(To find the source file, open the tabs: syslib / DeviceDrivers[nios] / altera_nios2 / HAL / src
). The whole project is zipped here. properties
. From there, choose NiosII complier options. With optimization set to -O0
(the default setting), reducing the number of ticks to timeout for timer1 to 0x1800 causes the system to crash. Setting the number of ticks to timeout for timer1 to 0x2000 allows multitasking of all four tasks to work. Setting the number of ticks to timeout for timer1 to 0x1d00 allows task 4 and task 1 to run, but not the lower priority tasks 2 and 3. With optimization set to -O3
(the highest) and no debugging, multitasking works with a setting of 0x1900, but fails at 0x1800. Thus, it looks like it takes about 6100 cycles for the ISR handling, internal timer0 functions, and context switching, so we can sustain (with these simple tasks) perhaps 7800 interrupts/second in MicroC/OS. Very fast functions, such as DDS, should be put in hardware, but button push detection and other sporadic events can be interrupt-driven. References
Micrium is the MicroC/OS vendor
MicroC/OS-II The Real Time Kernel, by Jean Labrosse, RD books, second edition, 2002
MicroC/OS function summary and API (linked from http://www.ece.ualberta.ca/~cmpe401/fall2004/labs/docs/uC_Functions.html)
MicroC/OS info from EPSC
Copyright Cornell University June 2006