Professional Documents
Culture Documents
0 Aims
To implement concurrent tasks using the uC/OS-II real time kernel running on the NIOS
II processor.
Understand and measure the overhead in running a timer interrupt in a real time kernel.
Display the processor utilization, current time in hours minutes and seconds, and a
graduated LED brightness using pulse width modulation.
1 Equipment
DE2 board.
Quartus/Nios II development software containing the uC/OS-II real time kernel.
2 Preliminary Work
Print and read this document and bring it to the lab. During the lab, ensure you write answers
3 Method
3.1 Hardware Definition
Download and install the Quartus project available on the unit website as a Quartus Archive
File by double clicking the file with extension .qar - Quartus should run and ask where to
install the project. A static RAM SOPC module needs to be installed separately as follows:
Download the ZIP file static_ram.zip from the unit webpage lab section. Ensure that SOPC
is not running and then unzip the static RAM SOPC module into your project directory. You
should be able to see a new folder named static_ram in your project directory now. If you
now run SOPC from Quartus and open the RTSLab1.sopc file, the following modules should
be available:
You must upgrade the SRAM module as follows: In the Component Library window on the
left hand side of SOPC, click on the + next to DE2 Board and right click on the Static RAM
and upgrade, accepting the default values. Right click on the static_ram_0 in the Module list
of SOPC (main window) and Replace with version 1.01. Unfortunately this procedure
must be followed every time SOPC is opened. If you fail to do this you will end up with
unknown port errors in the Quartus compilation.
This hardware configuration will be the basis for the real time laboratories.
Generate the SOPC system (bottom right button of SOPC screen), then compile the Quartus
project, and download the hardware configuration to the DE2 board.
The IDE should look like the following screen shot. To compile the hello_ucosii.c program,
Build All (click on the 010 button or use Project Menu-> build all).
Once the compiler has finished with no errors, you can run the program. Ensure that you
have first downloaded the processor configuration from Quartus.
To run the program, use the run -> Run menu or the green circle with white triangle tool,
and select Nios II Hardware-> hello_uscosii_0 as shown below:
Click Run and the program should download and run. If you receive a communication error
here, ensure that you have first downloaded the processor configuration from Quartus. This
error can also occur if no clock is connected to the processor in Quartus or there are no pin
assignments in the Quartus project.
You should observe that there are two tasks running from the console messages.
Which task runs at the higher priority?
Change the priority of task1 to match task2 in the OSTaskCreateExt() kernel call.
Run the modified code. Document your findings and then restore the original priorities.
Can two tasks share the same priority in uC/OS-II? Try it! Hint: modify the demonstration
code to check the error codes returned when call kernel functions such as OSTaskCreateExt.
This can be done as follows:
int error_code;
error_code = OSTaskCreateExt( task1, etc.);
if (error_code != 0) printf(Error creating task1 with error code %d\n, error_code);
You can look up the error codes by opening the includes.h file by double clicking on this
filename in the Outline window on the right hand side, and then double clicking on the
ucos_ii.h file from the Outline window again once includes.h is opened. You will notice that
all the #define symbols defined in the header file opened are listed in this Outline window.
Click on some of the OS_ERR_... ones.
Can two tasks share the same priority in uC/OS-II?
Do you think other real time kernels can run two tasks with the same priority?
Identify the time delay call to the kernel in each task. What is its purpose? Look up the
function in the uC/OS-II Real Time Kernel Reference Manual on the unit website under the
resources section. Leave this open for the rest of the lab so you can check what each kernel
function does and its error codes.
Change the delay in task2 to 10 seconds and test the change.
Remove the time delay call in the lower priority task loop comment it out using // at the
beginning of the line. Does the higher priority task still run? (Hint: Reduce the delay in the
higher priority task to 10 msec and simplify the output from the lower priority task to one .
to help decipher all the output).
Restore the previously commented line of code and now comment out the delay call in the
higher priority task. What happens now when you run the code?
Explain your findings to the demonstrator and get all the previous answers checked.
IdleCountWith100_ISRs =
IdleCountWith1000_ISRs =
Estimate the percentage execution overhead for a 1 msec timer interrupt. To do this first
work out how many IdleCount increments would occur for just one ISR and call it ISRinc.
Hint: you should realise that this is the difference/900. Now how many idle counts would
occur in a full second without any ISRs running? (Hint: add 100* ISRinc to
IdleCountWith100_ISRs). The % overhead with a 1 msec timer interrupt is then
1000*ISRinc/ (idle counts in a full second) * 100. Write your answer here:
1
2
After OSStatInit() has returned, further tasks are usually created to implement the system.
If you restart SOPC, you may need to upgrade the SRAM module again as described above in section 3.1
What if the clock update was given to a lower priority task and a higher priority task used a
high percentage of the processor time? Can you demonstrate your answer by using a couple
of nested for loops in a higher priority task to burn CPU cycles. (The high priority task must
still contained a delay call).
accumulator += brightness;
if (accumulator >= 32)
{
/* output a 1 to the LED here */
accumulator -= 32; /* take off the 32 corresponding to a 1 LED output */
} else
{
/* output a 0 to the LED here */
..
}
OSTimeDly(1); // delay a timer tick and give other tasks a chance to run
} // while (1)
Implement this algorithm and vary the brightness of the LED from off to full in a linear ramp
upwards and then downwards once every 10 seconds (that is in a triangular wave pattern).
Note the idle time of the real time system now. Show your demonstrator.
4 Conclusions
This lab has introduced the real time kernel uC/OS-II and you should understand the fixed
priority scheduling, task creation and delay kernel functions. The overhead in using a real
time kernel timer interrupt should have been noted as only a few percent of execution time in
the lab results.
The work in this lab will be applied to later labs in the design and implementation of a simple
alarm clock, where the alarm will consist of a wave pattern of LEDs. We will introduce
inter-process communication mechanisms in these later labs.