Download FreeRTOS
 

Quality RTOS & Embedded Software

KERNEL
WHAT'S NEW
Simplifying Authenticated Cloud Connectivity for Any Device.
Designing an energy efficient and cloud-connected IoT solution with CoAP.
Introducing FreeRTOS Kernel version 11.0.0:
FreeRTOS Roadmap and Code Contribution process.
OPC-UA over TSN with FreeRTOS.

ColdFire V2 RTOS Demo
Using Eclipse and GCC
[RTOS Ports]


This page presents the new FreeRTOS port and demo application for the V2 ColdFire core from Freescale. This new port, first provided with FreeRTOS V5.0.4, has extended functionality and therefore supersedes ports provided in previous versions.

The previous V2 port has been retained in the FreeRTOS 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:


IMPORTANT! Notes on using the V2 ColdFire RTOS port

Please read all the following points before using this RTOS port.

  1. Source Code Organization
  2. The Demo Application
  3. Configuration and Usage Details
See also the FAQ My application does not run, what could be wrong?

Source Code Organization

The FreeRTOS download contains the source code for all the FreeRTOS ports so contains many more files than used by this demo. See the Source Code Organization section for a description of the downloaded files and information on creating a new project.

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


Demo application hardware setup

The linker script is configured to place executable code in the M5282EVB SDRAM (not the fastest place to run code from!) and data in the internal SRAM of the MCF8252 itself. All switches in the SW1 bank can therefore be set to their 'ON' position.

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).


Functionality

The demo application creates 42 tasks before starting the RTOS scheduler (including the idle task), then repeatedly dynamically creates and deletes a further two tasks when the RTOS kernel is running.

The standard demo tasks do not perform any particular function other than to serve as usage examples for each FreeRTOS API function.

When executing correctly the demo will behave as follows:

  • LEDs marked D6, D7 and D8 are under control of the very simple 'flash' tasks. Each will flash at a constant frequency, with LED D6 being the fastest and LED D8 being the slowest.

  • Most of the tasks do not update an LED so have no visible indication that they are operating correctly. Therefore a 'Check' task is created whose job it is to ensure that no errors have been detected in any of the other tasks. The check task only executes every few seconds, but has a high priority so is guaranteed to get processing time when required. The check task will toggle LED D9 once every 5 seconds if all the demo tasks are executing as expected. The toggle rate will increase to 500ms should an error be detected in any task. This mechanism can be tested by removing the loopback connector from the AUXILIARY port to deliberately generate an error.

More information is provided in the comments of the code itself.

The RTOS 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.


Building and executing the demo application

A 'standard make' Eclipse project is used. This means the files to build and the build options are detailed within a standard makefile which can be viewed and edited using the Eclipse IDE. The optimisation level is set by the OPTIM definition at the very top of the makefile.

  • To build the demo application:

    1. Ensure you have the CodeSourcery compiler correctly installed, and that the compilers bin directory is included within your host systems PATH environment variable.

    2. Ensure you have installed and configured Eclipse exactly as described in these instructions.

    3. Start the Eclipse workbench IDE - at which point you will be prompted for a workspace location.

      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.


      Opening the Eclipse workspace - obviously use the path that is correct for your installation, which might not be the same as that shown here

    4. Make sure you set the "FreeRTOS_ROOT" variable to point to your FreeRTOS installation (again, this is described here).

    5. Select "Build All" from the Eclipse "Project" menu item. The demo should build with no errors or warnings.

  • To run the demo application:

    1. Ensure your M5282EVB is correctly connected to your host computer using a BDM interface supported by the CodeSourcery debug sprite.

    2. Press the down arrow next to the speed button that shows a little bug, then select RTOSDemo from the menu.


      Launching the RTOSDemo debug session

      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.


      Waiting for the program to load

      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:


Using the FreeRTOS Eclipse plug-in viewer


Configuration and Usage Details


RTOS port specific configuration

Configuration items specific to this demo are contained in FreeRTOS/Demo/ColdFire_MCF5282_Eclipse/RTOSDemo/FreeRTOSConfig.h. The constants defined in this file can be edited to suit your application. In particular -
  • configKERNEL_INTERRUPT_PRIORITY and configMAX_SYSCALL_INTERRUPT_PRIORITY

    See the interrupt configuration section of the RTOS kernel configuration documentation for full information on these options.

    configKERNEL_INTERRUPT_PRIORITY sets the interrupt priority used by the RTOS 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 RTOS kernel critical sections and will therefore be unaffected by RTOS 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 'BaseType_t' to equal the most efficient data type for that processor. This port defines BaseType_t to be of type long.

Note that vPortEndScheduler() has not been implemented.


Writing interrupt service routines

The CodeSourcery libraries populate the interrupt vector table with default handlers - each of which is called __cs3_isr_interrupt_xx(), where 'xx' is the vector number. You can override the default handler by simply providing your own definition of the handler function. For example, the UART1 peripheral uses vector number 78 - to provide your own UART1 handler simply provide your own definition of a function called __cs3_isr_interrupt_78().

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 char ucChar;
BaseType_t 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 );
}

Listing 1: An example ISR


Resources used by the RTOS kernel

The RTOS kernel uses the PIT0 timer to generate the RTOS tick. The function vApplicationSetupInterrupts() can be altered to use any convenient timer source.

In RTOS addition the RTOS 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 RTOS kernel uses this vector in conjunction with the Interrupt Force Register 0 (INTFRCL0). For reasons of efficiency the RTOS kernel assumes it 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 RTOS kernel code.


Critical sections

Exiting a critical section will always set the interrupt priority such that all interrupts are enabled, no matter what its level when the critical section was entered. FreeRTOS API functions themselves will use critical sections.


Execution context

For reasons of efficiency, tasks run with Supervisor privileges.


Switching between the pre-emptive and co-operative RTOS kernels

Set the definition configUSE_PREEMPTION within FreeRTOS/Demo/ColdFire_MCF5282_Eclipse/RTOSDemo/FreeRTOSConfig.h to 1 to use pre-emption or 0 to use co-operative. The demo application will only execute correctly with configUSE_PREEMPTION set to 0 if configIDLE_SHOULD_YIELD is set to 1.


Compiler options

As with all the ports, it is essential that the correct compiler options are used. The best way to ensure this is to base your application on the provided demo application files.


Memory allocation

Source/Portable/MemMang/heap_2.c is included in the ColdFire demo application project to provide the memory allocation required by the RTOS kernel. Please refer to the Memory Management section of the API documentation for full information.



Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.