| Latest News Items: FAT file system released - Tick suppression demo'ed SAM4L MCU & RX100 MCUs - embTCP released for PIC32 |
|
|||||||||||||||||
Renesas RX200 Demo
|
|||||||||||||||||
| Build configuration | Description |
| Blinky | This is a very simple example that creates two tasks and one queue. The tasks communicate with each other via the queue, and an LED is toggled on each successful queue receive. The main() function used by the Blinky build configuration is defined in main-blinky.c. The main() function used by the other two build configurations is defined in main-full.c. |
| Debug | This is a very comprehensive demo that creates nearly 50 tasks before starting the RTOS scheduler, then continuously dynamically creates and deletes another two tasks as the application executes. It also creates many queues and different types of semaphore. The tasks consist mainly of the standard demo tasks - which don't perform any particular functionality other than testing the port and demonstrating how the FreeRTOS API can be used. Information on additional tasks that are created is provided immediately below this table. The Debug build configuration includes standard demo tasks that demonstrate interrupt nesting, but does not include the high frequency timer interrupt. |
| Debug_with_optimisation | This is similar to the Debug build configuration, but includes the high frequency timer interrupt. The build configuration also has compiler optimisation turned up to maximum. |
The Debug and Debug_with_optimisation build configurations create the following tasks, timers, and tests, in addition to the standard demo tasks:
The Check timer is an example of a very simple watchdog type timer. It monitors all the other standard demo tasks, and the register test tasks (described below), and provides visual feedback of the system status using an LED.
The period of the check timer is initially set to five seconds. The check timer callback function checks that all the standard demo tasks, and the register test tasks, are not only still executing, but are executing without reporting any errors, then toggles an LED.
If the check timer discovers that a task has either stalled, or reported an error, then it changes its own period from the initial five seconds, to just 200ms. Therefore, if the LED toggles every five seconds, no issues have been discovered, whereas, if the LED toggles every 200ms, an issue has been discovered in at least one task.
The check timer uses LED marked LED3 on the RSK silkscreen.
These two tasks test the RTOS kernel context switch mechanism by first filling each RX200 register with a known and unique value, then repeatedly checking that the value originally written to the register is maintained in the register, for the lifetime of the task. The tasks execute at the lowest possible priority (the idle priority), so are preempted frequently. The nature of these tasks necessitates that they are written in assembly.
This test configures a timer to generate an interrupt at 20KHz. The interrupt priority is above configMAX_SYSCALL_INTERRUPT_PRIORITY, so will never be disabled by the RTOS kernel. The jitter experienced in the interrupt timing is measured and stored in a variable that can be inspected using the debugger.
This demo defines three IRQ interrupt handlers that are triggered by button presses, a task that controls the top line of the LCD, a task that controls the bottom line of the LCD, and a queue that is used to communicate between the interrupt handlers and one of the tasks.
The task that controls the top line of the LCD simply scrolls a message back and forth, with the scroll direction changing each time the message reaches the end of the LCD.
The task that controls the bottom line of the LCD acts just like the one controlling the top line, until button SW2 is pressed. Pressing button SW2 causes and interrupt to be generated. The interrupt handler uses the queue to send a command to the task instructing it to halt or restart the scrolling motion. While the scrolling is halted, the interrupts generated by pressing buttons SW3 and SW1 result in commands being sent to the task, on the same queue, instructing the task to nudge the message left and right respectively, one character at a time.
When executing, the demo application will behave as follows:
Sets the frequency of the RTOS tick. The supplied value of 1000Hz is useful for testing the RTOS kernel functionality, but is faster than needed by most applications. Lowering this frequency will improve efficiency.
Defines the interrupt priority used for by the tick and yield interrupts (the RTOS kernel interrupts). configKERNEL_INTERRUPT_PRIORITY should normally be set to the lowest interrupt priority, which is 1 on an RX200 core. See the customisation pages for more information.
Defines the maximum interrupt priority from which FreeRTOS API functions can be called. Interrupts at or below this priority can call FreeRTOS API functions provided that the API function ends in 'FromISR'. Interrupts above this priority cannot call any FreeRTOS API functions, but will never be disabled by the RTOS kernel. Interrupts that have a priority above configMAX_SYSCALL_INTERRUPT_PRIORITY are therefore suitable for functionality that requires very high timing accuracy. The high frequency timer test included in this demo uses a priority that is above configMAX_SYSCALL_INTERRUPT_PRIORITY. See the configuration pages for more information.
/* The 'enable' in the following line causes the compiler to generate code that
re-enables interrupts on function entry. This will allow interrupts to nest
(although in this case the high frequency timer interrupt is the highest priority
interrupt in the demo). */
#pragma interrupt ( prvTimer2IntHandler( vect = _VECT( _CMT2_CMI2 ), enable ) )
static void prvTimer2IntHandler( void )
{
/* ISR implementation goes here. */
}
See the examples provided by Renesas and the compiler documentation for full details.
Often an ISR wants to cause a context switch, so the task that the ISR returns to when the ISR processing is completed is different from the task that the ISR originally interrupted. This would be the case if the ISR caused a task to unblock, and the task that was unblocked has a priority above the task in the Running state (the task that was interrupted). The macro portYIELD_FROM_ISR() is provided for this purpose. portYIELD_FROM_ISR() takes a single parameter: If the parameter is zero, a context switch is not performed, if the parameter is non-zero, a context switch is performed. This is demonstrated in the code below - which is part of the RX210 demo, and implemented in FreeRTOS/Demo/RX200_RX210-RSK_Renesas/RTOSDemo/ButtonAndLCD.c.
/* The 'enable' in the following line causes the compiler to generate code that
re-enables interrupts on function entry. This will allow interrupts to nest. */
#pragma interrupt ( prvIRQ1_Handler( vect = 65, enable ) )
static void prvIRQ1_Handler( void )
{
static portTickType xTimeLastInterrupt = 0UL;
static const unsigned char ucCommand = lcdSHIFT_BACK_COMMAND;
portBASE_TYPE xHigherPriorityTaskWoken;
/* prvSendCommandOnDebouncedInput() returns true or false, depending on
whether the function unblocked a task that has equal or higher priority than the task
that is already in the running state. */
xHigherPriorityTaskWoken = prvSendCommandOnDebouncedInput( &xTimeLastInterrupt,
ucCommand );
portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
}
The application must define a function called vApplicationSetupTimerInterrupt() to configure the tick interrupt, then define configTICK_VECTOR to be the interrupt vector number associated with the chosen timer source.
It is suggested that a compare match timer is used to generate the tick interrupt, and an example implementation of vApplicationSetupTimerInterrupt() that uses compare match timer 0 is included in both main-full.c and main-blinky.c in this demo application. The demo application defines configTICK_VECTOR within FreeRTOSConfig.h to be _CMT0_CMI0 (the compare match 0 interrupt vector number). The provided example implementations can be used in any application that does not itself need to use the compare match 0 timer/interrupt.