Included in the demo is an example web server that is implemented using a modified version of Adam Dunkels open source uIP embedded TCP/IP stack. The web server provides a basic CGI scripting facility which is used to display both RTOS and TCP/IP run time information. uIP is licensed separately from FreeRTOS. Users must familiarise themselves with the uIP licence, which is included at the top of each uIP source file.
See also the FAQ My application does not run, what could be wrong?
The FreeRTOS zip file download contains the implementation of all the FreeRTOS ports and every demo application project. It therefore 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 IP address used by the SH7216 is set by the constants configIP_ADDR0 to configIP_ADDR3 which are defined at the bottom of the FreeRTOS/Demo/SuperH_SH7216_Renesas/RTOSDemo/FreeRTOSConfig.h header file. Constants that define the MAC address and the NET mask can be found in the same file.
The IP addresses used by the web browser and the RSK+SH7216 must be compatible. This can be ensured by making the first three octets of both IP addresses the same. For example, if the web browser computer uses IP address 10.10.10.1, then the RSK+SH7216 evaluation board can be given any address in the range 10.10.10.2 to 10.10.10.254, other than any addresses that already exist on the same network.
The MAC address assigned to the RSK+SH7216 must be unique on the network to which it is being attached.
The following tasks and tests are also created from within main():
This only executes every five seconds but has the highest priority to ensure it gets processing time. Its main function is to check that all the standard demo tasks are still operational. The check function maintains a status string that can be viewed at the very bottom of the "Task Stats" page served by the uIP TCP/IP web server. It also toggles LED5, with the toggle frequency being used to indicate the system status. A frequency of one toggle every 5 seconds means all the standard demo tasks are executing without error - if the toggle rate increases to 200ms then an error has been detected in at least one task.
This is the task that executes the TCP/IP stack. All network processing is performed in this task.
These fill all the registers with known values, then check that each register still contains its expected value. Two reg test tasks are created, each of which uses different known values. The tasks run with very low priority so get preempted very frequently. A register containing an unexpected value is indicative of an error in the context switching mechanism. Both standard and floating point registers are checked. The nature of the reg test tasks necessitates that they are written in assembly code. They are implemented in regtest.src.
When executing correctly the demo application will behave as follows:

![]() The RTOS stats page served by the SuperH web server |
![]() The run time stats page served by the SuperH web |

The IO page provides a simple interface to permit LED4 to be turned on and off via the web server. Changes are sent to the evaluation board when the "Update IO" button is clicked.
Other pages served include TCP/IP statistics and a large JPG image.
This sets the frequency of the RTOS tick. The supplied value of 1000Hz is useful for testing the kernel functionality but is faster than most applications need. Lowering this frequency will improve efficiency.
Each port #defines 'portBASE_TYPE' to equal the most efficient data type for that processor. The SuperH port defines portBASE_TYPE to be of type long.
Priority 1 interrupts must save their context to the stack, rather than a register bank.
ISRs that don't use the FreeRTOS API and cannot cause a context switch have no special requirements and can be written as per the compiler documentation. See the MTU interrupt handler called MTU_Match() and defined within main.c for an example.
Interrupts that do perform a context switch require an assembly wrapper. The assembly wrapper would normally call a standard C function handler, although the entire interrupt handler could be written in assembler if that was preferable. An example interrupt handler implementation is provided below.
To write an interrupt that can cause a context switch:
; Import the C handler so it can be called from this file. _pxCurrentTCB
; is also required.
.import _ISRHandler
.import _pxCurrentTCB
; Export the wrapper so it can be used to populate the vector table.
.export _ISRWrapper
; This header file contains the portSAVE_CONTEXT and portRESTORE_CONTEXT
; macros.
.INCLUDE "ISR_Support.inc"
; This wrapper goes into the program section.
.section P
;-----------------------------------------------------------
; The start of the assembly wrapper function. This is what is used to
; populate the vector table.
_ISRWrapper:
; portSAVE_CONTEXT must be called first!
portSAVE_CONTEXT
; Next call the C handler function, although the whole interrupt handler
; could be written in assembly if that is preferred.
mov.l #_ISRHandler, r0
jsr @r0
nop
; portRESTORE_CONTEXT must be called last! This handles the exit from the
; interrupt.
portRESTORE_CONTEXT
void ISRHandler( void )
{
long lHigherPriorityTaskWoken = pdFALSE;
/* Perform the actual interrupt processing here - not forgetting to clear
the interrupt source. */
/* In this example, a semaphore is given from the ISR, and it is possible
that giving the semaphore unblocks a task. The semaphore has already
been declared and created. */
xSemaphoreGiveFromISR( xSem, &lHigherPriorityTaskWoken );
/* If giving the semaphore did cause a task to unblock, and the unblocked
task has a priority equal to or higher than the currently executing task
(the interrupted task), then lHigherPriorityTaskWoken will have been set to
pdTRUE. Passing pdTRUE to portYIELD_FROM_ISR() will cause the required
context switch. */
portYIELD_FROM_ISR( lHigherPriorityTaskWoken );
}
The implementation of the Ethernet controller in the demo project can be used as a complete
example. The wrapper for the Ethernet driver is
define in EMAC_ISR.src, and the C portion of the handler in EMAC.c.
To tell the kernel that a task requires a floating point context pass the task handle into the xPortUsesFloatingPoint(xHandle) API function. xPortUsesFloatingPoint() must be called after the task is created but before the task first executes.
As an example, the following code can be found in main() of the SuperH demo application:
void main(void)
{
/* Declare a variable of type xTaskHandle to temporarily hold the handle of
the task being created. */
xTaskHandle xCreatedTask;
/* Create the task, storing the handle of the task in xCreatedTask. */
xTaskCreate( vRegTest1Task, "RegTst1", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, &xCreatedTask );
/* The task uses floating point registers, so tell the kernel that it
requires a floating point context. */
xPortUsesFloatingPoint( xCreatedTask );
/* ... rest of main() goes here ... */