ColdFire V2 RTOS and TCP/IP Demo
Using uIP, Eclipse and GCC
[RTOS Ports]


This port and demo are preconfigured to use:

Port highlights include full interrupt nesting support and no special coding requirements when writing interrupt service routines.


IMPORTANT! Notes on using the MCF52233 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 that 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 MCF52233 Eclipse demo is contained in the FreeRTOS/Demo/ColdFire_MCF52233_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 setup

The demo application uses the LEDs built onto the evaluation board so no particular hardware setup is required.

Connect the M52233DEMO evaluation board to a computer running a WEB browser either directly using a point to point (crossover) cable, or via a hub/router using a standard Ethernet cable. The prototyping board may also allow the use of a standard Ethernet cable when connecting point to point, but I have not tried this configuration.

The IP address used by the demo is set by the constants configIP_ADDR0 to configIP_ADDR3 within the file FreeRTOS/Demo/ColdFire_MCF52233_Eclipse/FreeRTOSConfig.h. The IP addresses used by the WEB browser computer and the evaluation board must be compatible. This can be ensured by making the first three octets of both IP addresses identical. For example, if the WEB browser computer uses IP address 192.168.100.1, then the prototyping board can be given any address in the range 192.168.100.2 to 192.168.100.254 (barring any addresses already present on the network).


Functionality

The demo application creates 33 tasks (including the idle task) before starting the scheduler. 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:

The kernel is configured to use interrupt priority level 1. The Ethernet peripheral (FEC) uses interrupt priority level 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 WEB Server

The FEC driver is implemented using an efficient 'no copy' mechanism, meaning the data remains in a single buffer all the way up the TCP/IP stack, and back down again.

The top of each served WEB page includes a menu containing a link to every other page.

  • The RTOS stats page provides run time information on the state of each task within the system - including the stack high water mark (the minimum amount of stack there has been available at any time since the task started executing). At the foot of the table you will find the refresh count, and the error code maintained by the 'check' task (as described above). The page will reload approximately every two seconds - depending on network load.

    This page is transmitted in three sections - the HTML header and menu, the dynamically generated content, then finally the HTML footer. This makes the page relatively fast to load. It could be optimised further by transmitting the entire page in one go.

    The continuous reloading can sometimes make navigating away from the RTOS stats page a little tricky.

  • The IO page provides a simple interface that permits data to be sent to and read from an LED on the development board. The check box permits the state of the user LED to be set and queried. Changes are sent to the target hardware by clicking the "Update IO" button. Note This is quite a crude demo that is setup for use with Microsoft Internet Explorer.

  • The TCP Stats and Connections pages display run time networking information. Note that these pages transmit each line individually so will not load quickly. This demonstrates how memory usage can be optimised through the use of a small transmit buffer by sacrificing the achieved data throughput.

  • The last page serves a 30KByte JPG file - which should load very quickly. Normally the uIP 'split' feature is required to obtain this high a throughput, but in this case the errata concerning double FEC transmissions is a convenient way of achieving a similar effect while also lowering processor loading (the split mechanism requires the TCP checksum to be calculated twice). No attempt has therefore been made to work around the double transmission errata.


The IO page


The task stats page


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.



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_MCF52233_Eclipse/RTOSDemo/FreeRTOSConfig.h. The constants defined in this file can be edited to suit your application. In particular -

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.


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 FEC interrupt within the MCF52233 demo can be used as an example. Listing 1 below provides another 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 );
}

Listing 1: An example ISR


Resources used by the kernel

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

In addition the kernel requires one additional interrupt vector. As delivered vector 16 on interrupt controller 0 is used as on the MCF52233 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.


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.org 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 real time kernels

Set the definition configUSE_PREEMPTION within FreeRTOS/Demo/ColdFire_MCF52233_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 real time kernel. Please refer to the Memory Management section of the API documentation for full information.



Copyright (C) 2010 Real Time Engineers Ltd.
Any and all data, files, source code, html content and documentation included in the FreeRTOS distribution or available on this site are the exclusive property of Real Time Engineers Ltd.. See the files license.txt (included in the distribution) and this copyright notice for more information. FreeRTOSTM and FreeRTOS.orgTM are trade marks of Real Time Engineers Ltd..