
This page presents the new FreeRTOS.org port and demo application for the V2 ColdFire core from Freescale. This new port, first provided with FreeRTOS.org V5.0.4, has extended functionality and therefore supersedes ports provided in previous versions.
The previous V2 port has been retained in the FreeRTOS.org download but is not recommended for new designs. The new port is almost a 'drop in' replacement so upgrading old designs should be simple, with only the interrupt service routine semantics (described on this page) requiring some consideration (writing interrupts is now simpler).
Port highlights include full interrupt nesting support and no special coding requirements when writing interrupt service routines.
The port and demo are preconfigured to use:
See also the FAQ My application does not run, what could be wrong?
The Eclipse workspace for the ColdFire MCF5282 Eclipse demo is contained in the FreeRTOS/Demo/ColdFire_MCF5282_Eclipse directory.
NOTE: Please follow these instructions carefully to install and configure Eclipse correctly for use with this demo application. Instructions for opening the Eclipse workspace are provided within the "Demo Application" section of this page.
The demo application uses the LEDs built onto the evaluation board so jumpers JP12 to JP15 should be in place.
The demo application includes an interrupt driven UART test where one task transmits characters that are then received by another task. For correct operation of this functionality a loopback connector must be fitted to the AUXILIARY connector of the M5282EVB hardware (pins 2 and 3 must be connected together on the 9Way connector - a paper clip is normally sufficient for the purpose).
The standard demo tasks do not perform any particular function other than to serve as usage examples for each FreeRTOS.org API function.
When executing correctly the demo will behave as follows:
More information is provided in the comments of the code itself.
The kernel is configured to use interrupt priority level 1. The UART uses interrupt priority level 2. Interrupt nesting is further exercised by the 'IntQueue' test whereby one task and two interrupts all access the same two queues. The two interrupts run at priority levels 4 and 3 respectively so the maximum possible interrupt nesting depth is 4. See the RTOS Configuration and Usage section for a more complete explanation of the executing interrupts and their respective priorities.
Remember that the deeper the nesting depth you permit the greater the stack size consumed - configCHECK_FOR_STACK_OVERFLOW needs to be set to 2 (rather than 1 as is the default for this demo) to catch overflows caused by deep nesting, but this should be used for debug purposes only as it will slow down the context switch operation. The demo application dumbly assigns the same stack size to each task rather tuning each stack to ensure RAM is not wasted.
The Eclipse workspace for the ColdFire MCF5282 Eclipse demo is contained in the FreeRTOS/Demo/ColdFire_MCF5282_Eclipse directory. This is therefore the directory that should be selected when Eclipse asks you for a workspace location, as depicted below.


You should be taken to the Eclipse Debug perspective, if you are not already there.
Wait for the program to be loaded into the evaluation board RAM - a progress bar in the bottom right corner of the IDE will show you when this is complete.

Once loaded the program should break on entry to main(). The Eclipse IDE can then be used to step through the code, view variables, view memory, etc, just as any other debug IDE. Manually remove the breakpoint at main() as a new break point will be added each time a debug session is started.
The WITTENSTEIN provided FreeRTOS Eclipse Plug-in can be used to view task and queue state information:

See the interrupt configuration section of the kernel configuration documentation for full information on these options.
configKERNEL_INTERRUPT_PRIORITY sets the interrupt priority used by the kernel itself. configMAX_SYSCALL_INTERRUPT_PRIORITY sets the highest interrupt priority from which queue and semaphore API functions can be called (note that only API functions that end in FromISR() can be called from within an ISR).
configKERNEL_INTERRUPT_PRIORITY should be set to the lowest priority.
Interrupts above configMAX_SYSCALL_INTERRUPT_PRIORITY will not be masked out by kernel critical sections and will therefore be unaffected by kernel activity - within the limitations imposed by the hardware itself.
By way of demonstration, the demo application defines configMAX_SYSCALL_INTERRUPT_PRIORITY to be 4 and configKERNEL_INTERRUPT_PRIORITY to be 1.
Each port #defines 'portBASE_TYPE' to equal the most efficient data type for that processor. This port defines portBASE_TYPE to be of type long.
Note that vPortEndScheduler() has not been implemented.
Interrupt service routines have no special requirements and can be written as per the compiler documentation. The macro portEND_SWITCHING_ISR() can be used to ensure an interrupt always returns to the highest priority ready state task - tasks can be unblocked by an ISR so the highest priority ready task at the end of an ISR might be different to the highest priority ready/running task when the ISR was entered.
The UART1 interrupt (listing 1 below) within the MCF5282 demo can be used as an example:
/* The function prototype must use the 'interrupt' attribute.*/
void __attribute__( ( interrupt ) ) __cs3_isr_interrupt_78( void );
Next provide the ISR function, with the correct vector number in the name.
NOTE: This is NOT intended to be an example of an efficient ISR. It is provided
only to demonstrate using queues from within interrupts. Great efficiency
improvements would be gained by simply placing received characters in a RAM
buffer, then using a single write to a semaphore to unblock a task if required.
void __cs3_isr_interrupt_78( void )
{
unsigned portCHAR ucChar;
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE, xDoneSomething = pdTRUE;
while( xDoneSomething != pdFALSE )
{
xDoneSomething = pdFALSE;
/* Does the tx buffer contain space? */
if( ( MCF_UART1_USR & MCF_UART_USR_TXRDY ) != 0x00 )
{
/* Are there any characters queued to be sent? */
if( xQueueReceiveFromISR( xCharsForTx, &ucChar, &xHigherPriorityTaskWoken ) == pdTRUE )
{
/* Send the next char. */
MCF_UART1_UTB = ucChar;
xDoneSomething = pdTRUE;
}
else
{
/* Turn off the Tx interrupt until such time as another character
is being transmitted. */
MCF_UART1_UIMR = serRX_INT;
xTxHasEnded = pdTRUE;
}
}
/* Any characters in the receive buffer? */
if( MCF_UART1_USR & MCF_UART_USR_RXRDY )
{
/* Queue the character for processing by a task? */
ucChar = MCF_UART1_URB;
xQueueSendFromISR( xRxedChars, &ucChar, &xHigherPriorityTaskWoken );
xDoneSomething = pdTRUE;
}
}
/* Finally we call portEND_SWITCHING_ISR(). This ensures that the interrupt returns
to the highest priority ready task - which may not be the currently running task if
reading from or writing to a queue causes a task of higher priority to unblock. */
portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );
}
In addition the kernel requires one additional interrupt vector. As delivered vector 16 on interrupt controller 0 is used as on the MCF5282 vector 16 is not used by any peripherals and is therefore spare. The kernel uses this vector in conjunction with the Interrupt Force Register 0 (INTFRCL0). For reasons of efficiency the kernel assumes is has exclusive access to this register and therefore does not attempt to maintain its state - although this behaviour can be easily altered by using bitwise sets and clears on the register rather than writing to the register in its entirety.
To allow users the flexibility to change vector assignments both the PIT0 and vector 16 configuration is performed in a file called FreeRTOS_tick_setup.c which is included as part of the user application, rather than part of the fixed kernel code.