SmartFusion2 Starter Kit |
SmartFusion2 Development Kit |
The demo uses:
See also the FAQ My application does not run, what could be wrong?
The SoftConsole Eclipse project file is located in the FreeRTOS/Demo/CORTEX_SmartFusion2_M2S050_SoftConsole" directory. Please refer to the build instructions on this page for information on preparing the project directory.
Hardware and software set up
The demo presented on this page can be executed on either the SmartFusion2
Starter Kit or the SmartFusion2 Development kit.
Set up required to use the SmartFusion2 Starter Kit:
Set up required to use the SmartFusion2 Development Kit:
FreeRTOS+CLI is used to, among other things, access a set of example files created on a RAM disk by
FreeRTOS+FAT SL. As always typing "help" in the CLI will generate a list of
available commands (commands that have been registered with FreeRTOS+CLI by the
demo application). Both the files created and the file system related CLI commands
are (at the time of writing) identical to those used by the FreeRTOS+FAT SL
Win32 simulator demo. See the
Win32 simulator demo documentation
page for details.
FreeRTOS+CLI is accessed through a virtual COM port that will enumerate when the SmartFusion2 Starter Kit or SmartFusion2 Development kit is connected by the USB port marked P1 (Starter Kit) or J24 (Development Kit) to the host computer. Once enumerated the virtual COM will appear as a standard COM port, allowing access to the CLI through a standard dumb terminal program such as HyperTerminal or TeraTerm. The image on the right shows a sample CLI session using TeraTerm. 115200 baud is used in the hardware. Note the Development Kit enumerates 4 separate virtual COM ports - attempt to connect through the highest numbered of the 4 first.
Most of the other created tasks are from the set of standard demo tasks that are used by all FreeRTOS demo applications. The standard demo tasks have no specific functionality or purpose other than to demonstrate the FreeRTOS API being used and test the RTOS kernel port.
A 'check' software timer is created that periodically inspects the standard demo tasks to ensure all the tasks are functioning as expected. The check software timer's callback function toggles an LED to give visual feedback of the demo status. If an LED toggles every 3 seconds, then the check software timer has not discovered any problems. If the rate at which the LED toggles increases to every 200 milliseconds, then the check software timer is indicating that an issue has been reported by at least one standard demo task. Another LED will also toggle with a fixed 333 millisecond period. This second LED is under the control of a standard demo "flash" software timer.
Building and executing the demo application
This sets the frequency of the RTOS tick interrupt. The supplied value of 1000Hz is useful for testing the RTOS kernel functionality but is faster than most applications need. Lowering the frequency will improve efficiency.
See the RTOS kernel configuration documentation for full information on these configuration constants.
Whereas configKERNEL_INTERRUPT_PRIORITY and configMAX_SYSCALL_INTERRUPT_PRIORITY are full eight bit shifted values, defined to be used as raw numbers directly in the ARM Cortex-M3 NVIC registers, configLIBRARY_LOWEST_INTERRUPT_PRIORITY and configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY are equivalents that are defined using just the 4 priority bits implemented in the SmartFusion2 NVIC. These values are provided because the CMSIS library function NVIC_SetPriority() requires the un-shifted 4 bit format.
Attention please!: See the page dedicated to setting interrupt priorities on ARM Cortex-M devices. Remember that ARM Cortex-M cores use numerically low priority numbers to represent HIGH priority interrupts. This can seem counter-intuitive and is easy to forget! If you wish to assign an interrupt a low priority do NOT assign it a priority of 0 (or other low numeric value) as this will result in the interrupt actually having the highest priority in the system - and therefore potentially make your system crash if this priority is above configMAX_SYSCALL_INTERRUPT_PRIORITY. Also, do not leave interrupt priorities unassigned, as by default they will have a priority of 0 and therefore the highest priority possible.
The lowest priority on a ARM Cortex-M core is in fact 255 - however different ARM Cortex-M microcontroller manufacturers implement a different number of priority bits and supply library functions that expect priorities to be specified in different ways. For example, on Microsemi SmartFusion2 SoC Cortex-M3 cores, the lowest priority you can specify is in fact 15 - this is defined by the constant configLIBRARY_LOWEST_INTERRUPT_PRIORITY in FreeRTOSConfig.h. The highest priority that can be assigned is always zero.
It is also recommended to ensure that all priority bits are assigned as being preemption priority bits, and none as sub priority bits, as they are in the provided demo.
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 portEND_SWITCHING_ISR() will leave interrupts enabled.
The following source code snippet is provided as an example. The interrupt uses a semaphore to synchronise with a task (not shown), and calls portEND_SWITCHING_ISR to ensure the interrupt returns directly to the task. See the function prvUARTRxNotificationHandler() in the file UARTCommandConsole.c included in this demo project for another example.
void Dummy_IRQHandler(void)
{
long lHigherPriorityTaskWoken = pdFALSE;
/* Clear the interrupt if necessary. */
Dummy_ClearITPendingBit();
/* This interrupt does nothing more than demonstrate how to synchronise a
task with an interrupt. A semaphore is used for this purpose. Note
lHigherPriorityTaskWoken is initialised to zero. */
xSemaphoreGiveFromISR( xTestSemaphore, &lHigherPriorityTaskWoken );
/* If there was a task that was blocked on the semaphore, and giving the
semaphore caused the task to unblock, and the unblocked task has a priority
higher than the current Running state task (the task that this interrupt
interrupted), then lHigherPriorityTaskWoken will have been set to pdTRUE
internally within xSemaphoreGiveFromISR(). Passing pdTRUE into the
portEND_SWITCHING_ISR() macro will result in a context switch being pended to
ensure this interrupt returns directly to the unblocked, higher priority,
task. Passing pdFALSE into portEND_SWITCHING_ISR() has no effect. */
portEND_SWITCHING_ISR( lHigherPriorityTaskWoken );
}
Only FreeRTOS API functions that end in "FromISR" can be called from an interrupt service routine - and then only if the priority of the interrupt is less than or equal to that set by the configMAX_SYSCALL_INTERRUPT_PRIORITY configuration constant (or configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY).