
This page presents the FreeRTOS demo for the NEC 78K0R 16bit microcontroller.
The demo project contains configurations for both the 78K0R/KG3 and 78K0R/KE3L target boards. A MINICUBE2 is used to interface between the IAR Embedded Workbench and the target boards. The MINICUBE2 is used for both flash programming and debugging.
The 78K0R target boards allow for easy evaluation of the microcontroller by including the microcontroller itself along with the necessary reset, clock, power and debug circuitry on a board that routes all the microcontroller pins to connector mounting points along the edge of the PCB.
See also the FAQ My application does not run, what could be wrong?
The IAR Embedded Workbench workspace for the NEC 78K0R demo is called RTOSDemo.eww and can be located within the FreeRTOS\Demo\NEC_78K0R_IAR directory.
The button is used to generate interrupts on INTP0.
The demo project creates 22 tasks before starting the scheduler. Most of these tasks consist of the 'standard demo' tasks - the purpose of these tasks is to both demonstrate the RTOS API and test the RTOS port. They do not in themselves perform any other useful function.
The following demo specific tasks are created in addition to the standard demo tasks:
Two register test tasks are created. These fill the microcontroller registers with known values, then continuously check that each register still contains its expected value - each task using different values. As the tasks run with very low priority they will get pre-empted regularly. A register test task finding an unexpected value in one of its registers is indicative of an error in the pre-emption context switching mechanism.
Most FreeRTOS demos demonstrate context switching from within an interrupt using a serial port loopback 'com test'. The 78K0R target board does not include an RS232 port so context switching from within interrupts is instead demonstrated using the interrupts generated by the button that is mounted directly onto the target board.
Both the button push ISR and corresponding task are very basic. The ISR simply 'gives' a semaphore each time the button is pushed. The task simply blocks on the semaphore, then toggles an LED each time the semaphore is given by the ISR - effectively synchronising the task with the interrupt.
When executing correctly the demo will behave as follows:

There are also two constants that are specific to the NEC 78K0R port and demo:
This must be set to match the selected compiler options. If the compiler options are set to use the 'near' code model and the 'near' data model then configMEMORY_MODE must be set to 0. If the compiler options are set to use the 'far' code model and the 'far' data model then configMEMORY_MODE must be set to 1. These are the only tested combinations of settings.
Set configCLOCK_SOURCE to 0 to use an external clock source, or 1 to use the high speed internal clock source (typically 8MHz). Ensure configCPU_CLOCK_HZ is also set correctly when altering any clock configuration.
Each port #defines 'portBASE_TYPE' to equal the most efficient data type for that processor. This port defines portBASE_TYPE to be of type short.
Note that vPortEndScheduler() has not been implemented.
Often you will require an interrupt service routine to cause a context switch. For example a serial port character being received may unblock a high priority task that was blocked waiting for the character to arrive. If the unblocked task has a higher priority than the current task then the ISR should return directly to the unblocked task. Limitations in the IAR inline assembler necessitate such interrupt service routines include an assembly file wrapper. The simple button push interrupt is included in this demo to demonstrate the mechanism. The example is replicated below.
First the assembly file wrapper.
; ISR_Support.h defines the portSAVE_CONTEXT and portRESTORE_CONTEXT
; macros.
#include "ISR_Support.h"
PUBLIC vButtonISRWrapper
EXTERN vButtonISRHandler
RSEG CODE:CODE
; The wrapper is the interrupt entry point.
vButtonISRWrapper:
; The ISR must start with a call to the portSAVE_CONTEXT() macro to save
; the context of the currently running task.
portSAVE_CONTEXT
; Once the context is saved the C portion of the handler can be called.
; This is where the interrupting peripheral is actually serviced.
call vButtonISRHandler
; Finally the ISR must end with a call to portRESTORE_CONTEXT() followed by
; a reti instruction to return from the interrupt to whichever task is
; now the task selected to run (which may be different to the task that
; was running before the interrupt started).
portRESTORE_CONTEXT
reti
The C portion of the interrupt handler is just a standard C function.
/* This standard C function is called from the assembly wrapper above. */
void vButtonISRHandler( void )
{
short sHigherPriorityTaskWoken = pdFALSE;
/* The code in this handler is just a copy of the button push interrupt code
for demonstration only. */
/* 'Give' the semaphore to unblock the button task. */
xSemaphoreGiveFromISR( xButtonSemaphore, &sHigherPriorityTaskWoken );
/* If giving the semaphore unblocked a task, and the unblocked task has a
priority that is higher than the currently running task, then
sHigherPriorityTaskWoken will have been set to pdTRUE. Passing a pdTRUE
value to portYIELD_FROM_ISR() will cause this interrupt to return directly
to the higher priority unblocked task. */
portYIELD_FROM_ISR( sHigherPriorityTaskWoken );
}
The kernel also requires exclusive use of the BRK software interrupt instruction.