Selecting the required build
Select "Build Solution" from the CrossStudio project menu or simply press F7.
Downloading and executing
To download the application to the target hardware:
- Connect the FETP JTAG interface between the target and host. The target will be powered via the FETP JTAG interface and no other
power source should be connected.
- Select "Connect MSP430 Flash Emulation Tool" from the CrossStudio Target menu.
- Select "Start Debugging" from the CrossStudio Debug menu. The MSP430 Flash will be automatically programmed
with the demo application.
Once the application has been programmed into flash it can executed within the CrossStudio debugger. Alternatively, stop the
debugger (to power down the target), remove the FETP JTAG interface, then supply the target with an external power
source.
Serial port driver
As provided the serial port drivers are configured for loopback mode. This enables the demo application to execute but
switch loopback mode off for any other use.
It should also be noted that the serial drivers are written to test some of the real time kernel features - and they are not
intended to represent an optimised solution.
RTOS port specific configuration
Configuration items specific to this port are contained in
Demo/MSP430_CrossWorks/FreeRTOSConfig.h. The constants defined in
this file can be edited to suit your application. In particular - the definition configTICK_RATE_HZ is used to set the frequency
of the RTOS tick. The supplied value of 1000Hz is useful for testing the RTOS kernel functionality but is faster than most applications
require. Lowering this value will improve efficiency.
Each port #defines 'BaseType_t' to equal the most efficient data type for that processor. This port defines
BaseType_t to be of type short.
Note that vPortEndScheduler() has not been implemented.
To use a part other than an MSP430F449
The core real time kernel components should be
portable across all MSP430F4xx devices - but the peripheral setup and memory requirements will require consideration.
Items to consider:
- prvSetupTimerInterrupt() in Source/portable/Rowley/MSP430F449/port.c configures the microcontroller timer to generate
the RTOS tick.
- Port, memory access and system clock configuration is performed by prvSetupHardware() within Demo/MSP430_CrossWorks/main.c.
- The serial port drivers.
- Register location definitions are provided by the file msp430x44x.h which is included at the top of
Demo/MSP430_CrossWorks/FreeRTOSConfig.h.
- RAM size - see Memory Allocation below.
Switching between the pre-emptive and co-operative RTOS kernels
Set the definition configUSE_PREEMPTION within
Demo/MSP430_CrossWorks/FreeRTOSConfig.h to 1 to use pre-emption or 0 to use
co-operative.
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 project.
Memory allocation
Source/Portable/MemMang/heap_1.c is included in the MSP430 demo 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.
Interrupt Service Routines
Versions of FreeRTOS prior to V5.1.0 included two separate sets of port layer files for the MSP430:
- The officially supported version that uses the extensions provided by the Rowley compiler to implement interrupt service routines completely in C.
- A contributed port that required interrupt service routines to have assembly function wrappers.
FreeRTOS V5.1.0 only includes the officially supported version but introduces a pre-processor macro and a new header file that allows the users to define
which method of writing interrupt service routines will be used. The following sections describe the steps required to use both methods.
The UART driver within the supplied demo application also demonstrates both methods.
Method 1 only requires C code so is simpler to implement than method 2. It only saves and restores the task context when a context switch is actually
required, so can also be more efficient. However - a context switch being performed within the interrupt will result in some processor registers being
saved twice (once on interrupt entry, and then again for the context switch). This means the stack allocated to each task will need to be larger when
using method 1 compared to that required when using method 2.
Writing ISRs - Method 1
To use method 1:
- Set the pre-processor macro configINTERRUPT_EXAMPLE_METHOD to 1. The supplied demo application defines configINTERRUPT_EXAMPLE_METHOD within FreeRTOSConfig.h.
- Use the __interrupt[ ] function qualifier to implement interrupt service routines within C files.
- If using low power modes - ensure __bic_SR_register_on_exit(SCG1 + SCG0 + OSCOFF + CPUOFF) is called prior to exiting the interrupt service routine.
- Use the standard taskYIELD() macro should a context switch be required from within the interrupt routine.
Below is an example UART Rx interrupt written using method 1.
void vRxISR( void ) __interrupt[ UART1RX_VECTOR ]
{
signed char cChar;
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
/* Get the character from the UART and post it on the queue of Rxed
characters. */
cChar = U1RXBUF;
xQueueSendFromISR( xRxedChars, &cChar, &xHigherPriorityTaskWoken );
if( xHigherPriorityTaskWoken )
{
/*If the post causes a task to wake force a context switch
as the woken task may have a higher priority than the task we have
interrupted. */
taskYIELD();
}
/* Make sure any low power mode bits are clear before leaving the ISR. */
__bic_SR_register_on_exit( SCG1 + SCG0 + OSCOFF + CPUOFF );
}
Writing an ISR using method 1
Writing ISRs - Method 2
To use method 2:
- Set the pre-processor macro configINTERRUPT_EXAMPLE_METHOD to 2. The supplied demo application defines configINTERRUPT_EXAMPLE_METHOD within FreeRTOSConfig.h.
- Provide an assembly function that will be installed as the interrupt handler routine. The required format of this function is demonstrated below. Note the assembly file must include the portasm.h header file to gain access to the required portSAVE_CONTEXT and portRESTORE_CONTEXT assembly macros.
- Provide a standard C function that is called by the assembly file wrapper to perform the actual interrupt handling work - again see below for an example.
- Use the portYIELD_FROM_ISR() macro should a context switch be required from within the interrupt routine.
Below are examples of both the assembly file wrapper and C function portions of the interrupt implementation.
/* Ensure the required header files are included. */
#include "FreeRTOSConfig.h"
#include "portasm.h"
.CODE
/* Example wrapper for the Rx UART interrupt. */
_vUARTRx_Wrapper:
/* portSAVE_CONTEXT must be the first macro to be called. This is defined within
portasm.h. */
portSAVE_CONTEXT
/* Following portSAVE_CONTEXT the C portion of the handler can be called. */
call #_vRxISR
/* Finally portRESTORE_CONTEXT must be called at the end of the wrapper. This too
is defined within portasm.h. */
portRESTORE_CONTEXT
/******************************************************************/
/* The wrapper must be installed as the interrupt handler. */
.VECTORS
.KEEP
ORG UART1RX_VECTOR
DW _vUARTRx_Wrapper
END
The assembly file portion of the ISR
/* This is the standard C function called by the assembly file wrapper. */
void vRxISR( void )
{
signed char cChar;
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
/* Get the character from the UART and post it on the queue of Rxed
characters. */
cChar = U1RXBUF;
xQueueSendFromISR( xRxedChars, &cChar, &xHigherPriorityTaskWoken );
/*If the post causes a task to wake force a context switch
as the woken task may have a higher priority than the task we have
interrupted. */
portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
}
The C function called from the assembly file wrapper
Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.