ColdFire V2 RTOS and TCP/IP Demo
Using uIP, Eclipse and GCC
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.
See also the FAQ My application does not run, what could be wrong?
- Source Code Organization
- The Demo Application
- Configuration and Usage Details
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 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).
The demo application creates 33 tasks (including the idle task) before starting the RTOS scheduler.
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 LED1, LED2 and LED3 are under control of the very simple 'flash' tasks. Each will flash at a constant frequency, with LED LED1 being
the fastest and LED LED3 being the slowest. LED4 is controlled via the web server interface.
- The MCF52233 will serve web pages as described below - to connect to the server:
- Open a web browser on a connected computer.
- Type "HTTP://" followed by the target IP address into the browsers address bar.
Entering the IP address into the web browser
(obviously use the correct IP address for your system)
- 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.
An error found in any task will be
latched in the ulErrorCode variable for display through the web server (the
error code is displayed at the foot of the table that contains information on
the state of each task). An error code of 0 indicates that no errors have been detected.
The RTOS 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.
- To build the demo application:
Ensure you have the CodeSourcery compiler correctly
installed, and that the compilers bin directory is included within your host systems PATH environment variable.
Ensure you have installed and configured Eclipse exactly as described in these instructions.
Start the Eclipse workbench IDE - at which point you will be prompted for a workspace location.
The Eclipse workspace for the ColdFire MCF52233 Eclipse demo is contained in the FreeRTOS/Demo/ColdFire_MCF52233_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
Make sure you set the "FreeRTOS_ROOT" variable to point to your FreeRTOS installation (again, this is described here).
Select "Build All" from the Eclipse "Project" menu item. The demo should build with no errors, although the const structures that define the web page
content within httpd-fsdata.c will generate 4 or 5 identical warnings - this is unfortunately unavoidable.
- To program the Coldfire Flash memory:
Ensure the P&E Micro USB connector on the M52233DEMO hardware is correctly connected to your host computer.
Start the CF Flasher utility.
- Click the "Target Configuration" button, then ensure the configuration is set as per the image below.
The required CF Flasher target configuration settings
Next click the "Program" button in the CF Flasher utility to reveal the Program window. Select the file
FreeRTOS/Demo/ColdFire_MCF52233_Eclipse/RTOSDemo/bin/RTOSDemo.s19, then click the "Program" button within the
Wait until the flash programming has completed, then close the CF Flasher utility. The utility must be closed for the debugger to function
- To run the demo application (with the M52233DEMO hardware still connected to your host computer, and the flash memory already programmed):
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 were not already there.
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
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 -
- configKERNEL_INTERRUPT_PRIORITY and configMAX_SYSCALL_INTERRUPT_PRIORITY
See the interrupt configuration section of the RTOS kernel configuration documentation for full information on
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
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 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;
/* 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
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 MCF52233 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.
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.
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_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.
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.
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
Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.