Update the CCS4 MSP430X demo files.

This commit is contained in:
Richard Barry 2011-03-12 14:56:14 +00:00
parent d53e65ed82
commit 0ced5cc699
7 changed files with 491 additions and 180 deletions

View file

@ -43,7 +43,7 @@
<option id="com.ti.ccstudio.buildDefinitions.MSP430_3.3.compilerID.DATA_MODEL.1471292597" superClass="com.ti.ccstudio.buildDefinitions.MSP430_3.3.compilerID.DATA_MODEL" value="com.ti.ccstudio.buildDefinitions.MSP430_3.3.compilerID.DATA_MODEL.large" valueType="enumerated"/>
</tool>
<tool id="com.ti.ccstudio.buildDefinitions.MSP430_3.3.exe.linkerDebug.1882128094" name="MSP430 Linker" superClass="com.ti.ccstudio.buildDefinitions.MSP430_3.3.exe.linkerDebug">
<option id="com.ti.ccstudio.buildDefinitions.MSP430_3.3.linkerID.HEAP_SIZE.1907940977" superClass="com.ti.ccstudio.buildDefinitions.MSP430_3.3.linkerID.HEAP_SIZE" value="300" valueType="string"/>
<option id="com.ti.ccstudio.buildDefinitions.MSP430_3.3.linkerID.HEAP_SIZE.1907940977" superClass="com.ti.ccstudio.buildDefinitions.MSP430_3.3.linkerID.HEAP_SIZE" value="0" valueType="string"/>
<option id="com.ti.ccstudio.buildDefinitions.MSP430_3.3.linkerID.STACK_SIZE.155131239" superClass="com.ti.ccstudio.buildDefinitions.MSP430_3.3.linkerID.STACK_SIZE" value="300" valueType="string"/>
<option id="com.ti.ccstudio.buildDefinitions.MSP430_3.3.linkerID.USE_HW_MPY.1895647999" superClass="com.ti.ccstudio.buildDefinitions.MSP430_3.3.linkerID.USE_HW_MPY" value="com.ti.ccstudio.buildDefinitions.MSP430_3.3.linkerID.USE_HW_MPY.F5" valueType="enumerated"/>
<option id="com.ti.ccstudio.buildDefinitions.MSP430_3.3.linkerID.OUTPUT_FILE.2049770982" superClass="com.ti.ccstudio.buildDefinitions.MSP430_3.3.linkerID.OUTPUT_FILE" value="&quot;RTOSDemo.out&quot;" valueType="string"/>
@ -137,7 +137,7 @@
<option id="com.ti.ccstudio.buildDefinitions.MSP430_3.3.compilerID.SINGLE_INLINE.153283919" superClass="com.ti.ccstudio.buildDefinitions.MSP430_3.3.compilerID.SINGLE_INLINE" value="true" valueType="boolean"/>
</tool>
<tool id="com.ti.ccstudio.buildDefinitions.MSP430_3.3.exe.linkerDebug.1554119117" name="MSP430 Linker" superClass="com.ti.ccstudio.buildDefinitions.MSP430_3.3.exe.linkerDebug">
<option id="com.ti.ccstudio.buildDefinitions.MSP430_3.3.linkerID.HEAP_SIZE.884365605" name="Heap size for C/C++ dynamic memory allocation (--heap_size, -heap)" superClass="com.ti.ccstudio.buildDefinitions.MSP430_3.3.linkerID.HEAP_SIZE" value="300" valueType="string"/>
<option id="com.ti.ccstudio.buildDefinitions.MSP430_3.3.linkerID.HEAP_SIZE.884365605" name="Heap size for C/C++ dynamic memory allocation (--heap_size, -heap)" superClass="com.ti.ccstudio.buildDefinitions.MSP430_3.3.linkerID.HEAP_SIZE" value="0" valueType="string"/>
<option id="com.ti.ccstudio.buildDefinitions.MSP430_3.3.linkerID.STACK_SIZE.1998221473" name="Set C system stack size (--stack_size, -stack)" superClass="com.ti.ccstudio.buildDefinitions.MSP430_3.3.linkerID.STACK_SIZE" value="300" valueType="string"/>
<option id="com.ti.ccstudio.buildDefinitions.MSP430_3.3.linkerID.USE_HW_MPY.1687098000" name="Link in hardware version of RTS mpy routine (--use_hw_mpy)" superClass="com.ti.ccstudio.buildDefinitions.MSP430_3.3.linkerID.USE_HW_MPY" value="com.ti.ccstudio.buildDefinitions.MSP430_3.3.linkerID.USE_HW_MPY.F5" valueType="enumerated"/>
<option id="com.ti.ccstudio.buildDefinitions.MSP430_3.3.linkerID.OUTPUT_FILE.750680827" name="Specify output file name (--output_file, -o)" superClass="com.ti.ccstudio.buildDefinitions.MSP430_3.3.linkerID.OUTPUT_FILE" value="&quot;RTOSDemo.out&quot;" valueType="string"/>
@ -204,7 +204,7 @@
<option id="com.ti.ccstudio.buildDefinitions.MSP430_3.3.compilerID.DIAG_WARNING.1302018091" name="Treat diagnostic &lt;id&gt; as warning (--diag_warning, -pdsw)" superClass="com.ti.ccstudio.buildDefinitions.MSP430_3.3.compilerID.DIAG_WARNING" valueType="stringList">
<listOptionValue builtIn="false" value="225"/>
</option>
<option id="com.ti.ccstudio.buildDefinitions.MSP430_3.3.compilerID.PRINTF_SUPPORT.1956765338" name="Level of printf support required (--printf_support)" superClass="com.ti.ccstudio.buildDefinitions.MSP430_3.3.compilerID.PRINTF_SUPPORT" value="com.ti.ccstudio.buildDefinitions.MSP430_3.3.compilerID.PRINTF_SUPPORT.nofloat" valueType="enumerated"/>
<option id="com.ti.ccstudio.buildDefinitions.MSP430_3.3.compilerID.PRINTF_SUPPORT.1956765338" name="Level of printf support required (--printf_support)" superClass="com.ti.ccstudio.buildDefinitions.MSP430_3.3.compilerID.PRINTF_SUPPORT" value="com.ti.ccstudio.buildDefinitions.MSP430_3.3.compilerID.PRINTF_SUPPORT.minimal" valueType="enumerated"/>
<option id="com.ti.ccstudio.buildDefinitions.MSP430_3.3.compilerID.SILICON_VERSION.1373809772" name="Silicon version (--silicon_version, -v)" superClass="com.ti.ccstudio.buildDefinitions.MSP430_3.3.compilerID.SILICON_VERSION" value="com.ti.ccstudio.buildDefinitions.MSP430_3.3.compilerID.SILICON_VERSION.mspx" valueType="enumerated"/>
<option id="com.ti.ccstudio.buildDefinitions.MSP430_3.3.compilerID.DEFINE.566602389" name="Pre-define NAME (--define, -D)" superClass="com.ti.ccstudio.buildDefinitions.MSP430_3.3.compilerID.DEFINE" valueType="definedSymbols">
<listOptionValue builtIn="false" value="__MSP430F5438A__"/>
@ -226,9 +226,11 @@
</option>
<option id="com.ti.ccstudio.buildDefinitions.MSP430_3.3.compilerID.CODE_MODEL.1139014825" name="Specify the code memory model. (--code_model)" superClass="com.ti.ccstudio.buildDefinitions.MSP430_3.3.compilerID.CODE_MODEL" value="com.ti.ccstudio.buildDefinitions.MSP430_3.3.compilerID.CODE_MODEL.large" valueType="enumerated"/>
<option id="com.ti.ccstudio.buildDefinitions.MSP430_3.3.compilerID.DATA_MODEL.820058243" name="Specify the data memory model. (--data_model)" superClass="com.ti.ccstudio.buildDefinitions.MSP430_3.3.compilerID.DATA_MODEL" value="com.ti.ccstudio.buildDefinitions.MSP430_3.3.compilerID.DATA_MODEL.small" valueType="enumerated"/>
<option id="com.ti.ccstudio.buildDefinitions.MSP430_3.3.compilerID.SILICON_ERRATA.CPU15.1202920097" superClass="com.ti.ccstudio.buildDefinitions.MSP430_3.3.compilerID.SILICON_ERRATA.CPU15" value="true" valueType="boolean"/>
<option id="com.ti.ccstudio.buildDefinitions.MSP430_3.3.compilerID.SILICON_ERRATA.CPU18.1795934125" superClass="com.ti.ccstudio.buildDefinitions.MSP430_3.3.compilerID.SILICON_ERRATA.CPU18" value="true" valueType="boolean"/>
</tool>
<tool id="com.ti.ccstudio.buildDefinitions.MSP430_3.3.exe.linkerDebug.1837962732" name="MSP430 Linker" superClass="com.ti.ccstudio.buildDefinitions.MSP430_3.3.exe.linkerDebug">
<option id="com.ti.ccstudio.buildDefinitions.MSP430_3.3.linkerID.HEAP_SIZE.728234211" name="Heap size for C/C++ dynamic memory allocation (--heap_size, -heap)" superClass="com.ti.ccstudio.buildDefinitions.MSP430_3.3.linkerID.HEAP_SIZE" value="300" valueType="string"/>
<option id="com.ti.ccstudio.buildDefinitions.MSP430_3.3.linkerID.HEAP_SIZE.728234211" name="Heap size for C/C++ dynamic memory allocation (--heap_size, -heap)" superClass="com.ti.ccstudio.buildDefinitions.MSP430_3.3.linkerID.HEAP_SIZE" value="0" valueType="string"/>
<option id="com.ti.ccstudio.buildDefinitions.MSP430_3.3.linkerID.STACK_SIZE.312215125" name="Set C system stack size (--stack_size, -stack)" superClass="com.ti.ccstudio.buildDefinitions.MSP430_3.3.linkerID.STACK_SIZE" value="300" valueType="string"/>
<option id="com.ti.ccstudio.buildDefinitions.MSP430_3.3.linkerID.USE_HW_MPY.261762041" name="Link in hardware version of RTS mpy routine (--use_hw_mpy)" superClass="com.ti.ccstudio.buildDefinitions.MSP430_3.3.linkerID.USE_HW_MPY" value="com.ti.ccstudio.buildDefinitions.MSP430_3.3.linkerID.USE_HW_MPY.F5" valueType="enumerated"/>
<option id="com.ti.ccstudio.buildDefinitions.MSP430_3.3.linkerID.OUTPUT_FILE.820149163" name="Specify output file name (--output_file, -o)" superClass="com.ti.ccstudio.buildDefinitions.MSP430_3.3.linkerID.OUTPUT_FILE" value="&quot;RTOSDemo.out&quot;" valueType="string"/>
@ -319,7 +321,7 @@
<option id="com.ti.ccstudio.buildDefinitions.MSP430_3.3.compilerID.DATA_MODEL.102615768" name="Specify the data memory model. (--data_model)" superClass="com.ti.ccstudio.buildDefinitions.MSP430_3.3.compilerID.DATA_MODEL" value="com.ti.ccstudio.buildDefinitions.MSP430_3.3.compilerID.DATA_MODEL.small" valueType="enumerated"/>
</tool>
<tool id="com.ti.ccstudio.buildDefinitions.MSP430_3.3.exe.linkerDebug.400652052" name="MSP430 Linker" superClass="com.ti.ccstudio.buildDefinitions.MSP430_3.3.exe.linkerDebug">
<option id="com.ti.ccstudio.buildDefinitions.MSP430_3.3.linkerID.HEAP_SIZE.1589461908" name="Heap size for C/C++ dynamic memory allocation (--heap_size, -heap)" superClass="com.ti.ccstudio.buildDefinitions.MSP430_3.3.linkerID.HEAP_SIZE" value="300" valueType="string"/>
<option id="com.ti.ccstudio.buildDefinitions.MSP430_3.3.linkerID.HEAP_SIZE.1589461908" name="Heap size for C/C++ dynamic memory allocation (--heap_size, -heap)" superClass="com.ti.ccstudio.buildDefinitions.MSP430_3.3.linkerID.HEAP_SIZE" value="0" valueType="string"/>
<option id="com.ti.ccstudio.buildDefinitions.MSP430_3.3.linkerID.STACK_SIZE.761794468" name="Set C system stack size (--stack_size, -stack)" superClass="com.ti.ccstudio.buildDefinitions.MSP430_3.3.linkerID.STACK_SIZE" value="300" valueType="string"/>
<option id="com.ti.ccstudio.buildDefinitions.MSP430_3.3.linkerID.USE_HW_MPY.847690853" name="Link in hardware version of RTS mpy routine (--use_hw_mpy)" superClass="com.ti.ccstudio.buildDefinitions.MSP430_3.3.linkerID.USE_HW_MPY" value="com.ti.ccstudio.buildDefinitions.MSP430_3.3.linkerID.USE_HW_MPY.F5" valueType="enumerated"/>
<option id="com.ti.ccstudio.buildDefinitions.MSP430_3.3.linkerID.OUTPUT_FILE.1733576069" name="Specify output file name (--output_file, -o)" superClass="com.ti.ccstudio.buildDefinitions.MSP430_3.3.linkerID.OUTPUT_FILE" value="&quot;RTOSDemo.out&quot;" valueType="string"/>

View file

@ -23,6 +23,7 @@ IF EXIST FreeRTOS_Source Goto END
copy ..\..\Source\tasks.c FreeRTOS_Source
copy ..\..\Source\queue.c FreeRTOS_Source
copy ..\..\Source\list.c FreeRTOS_Source
copy ..\..\Source\timers.c FreeRTOS_Source
REM Copy the common header files
@ -38,6 +39,8 @@ IF EXIST FreeRTOS_Source Goto END
copy ..\Common\minimal\dynamic.c Demo_Source\Common_Demo_Files
copy ..\Common\minimal\comtest.c Demo_Source\Common_Demo_Files
copy ..\Common\minimal\GenQTest.c Demo_Source\Common_Demo_Files
copy ..\Common\minimal\TimerDemo.c Demo_Source\Common_Demo_Files
copy ..\Common\minimal\countsem.c Demo_Source\Common_Demo_Files
REM Copy the common demo file headers.
copy ..\Common\include\dynamic.h Demo_Source\Common_Demo_Files\include
@ -46,5 +49,7 @@ IF EXIST FreeRTOS_Source Goto END
copy ..\Common\include\GenQTest.h Demo_Source\Common_Demo_Files\include
copy ..\Common\include\serial.h Demo_Source\Common_Demo_Files\include
copy ..\Common\include\partest.h Demo_Source\Common_Demo_Files\include
copy ..\Common\include\TimerDemo.h Demo_Source\Common_Demo_Files\include
copy ..\Common\include\countsem.h Demo_Source\Common_Demo_Files\include
: END
: END

View file

@ -81,18 +81,19 @@
#define configCPU_CLOCK_HZ ( 25000000UL )
#define configTICK_RATE_HZ ( ( portTickType ) 1000 )
#define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 5 )
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 9 * 1024 ) )
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 10 * 1024 ) )
#define configMAX_TASK_NAME_LEN ( 10 )
#define configUSE_TRACE_FACILITY 1
#define configUSE_16_BIT_TICKS 0
#define configUSE_TRACE_FACILITY 0
#define configUSE_16_BIT_TICKS 1
#define configIDLE_SHOULD_YIELD 1
#define configUSE_MUTEXES 1
#define configQUEUE_REGISTRY_SIZE 0
#define configGENERATE_RUN_TIME_STATS 1
#define configGENERATE_RUN_TIME_STATS 0
#define configCHECK_FOR_STACK_OVERFLOW 2
#define configUSE_RECURSIVE_MUTEXES 0
#define configUSE_RECURSIVE_MUTEXES 1
#define configUSE_MALLOC_FAILED_HOOK 1
#define configUSE_APPLICATION_TASK_TAG 0
#define configUSE_COUNTING_SEMAPHORES 1
#ifdef __LARGE_DATA_MODEL__
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 80 )
@ -104,6 +105,12 @@
#define configUSE_CO_ROUTINES 0
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
/* Software timer definitions. */
#define configUSE_TIMERS 1
#define configTIMER_TASK_PRIORITY ( 3 )
#define configTIMER_QUEUE_LENGTH 10
#define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE )
/* Set the following definitions to 1 to include the API function, or zero
to exclude the API function. */
#define INCLUDE_vTaskPrioritySet 1
@ -121,39 +128,8 @@ vector for the chosen tick interrupt source. This implementation of
vApplicationSetupTimerInterrupt() generates the tick from timer A0, so in this
case configTICK_VECTOR is set to TIMER0_A0_VECTOR. */
#define configTICK_VECTOR TIMER0_A0_VECTOR
extern void vConfigureTimerForRunTimeStats( void );
extern volatile unsigned long ulStatsOverflowCount;
/* Configure a 16 bit timer to generate the time base for the run time stats.
The timer is configured to interrupt each time it overflows so a count of
overflows can be kept - that way a 32 bit time value can be constructed from
the timers current count value and the number of overflows. */
#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() vConfigureTimerForRunTimeStats()
/* Construct a 32 bit time value for use as the run time stats time base. This
comes from the current value of a 16 bit timer combined with the number of times
the timer has overflowed. */
#define portALT_GET_RUN_TIME_COUNTER_VALUE( ulCountValue ) \
{ \
/* Stop the counter counting temporarily. */ \
TA1CTL &= ~MC__CONTINOUS; \
\
/* Check to see if any counter overflow interrupts are pending. */ \
if( ( TA1CTL & TAIFG ) != 0 ) \
{ \
/* An overflow has occurred but not yet been processed. */ \
ulStatsOverflowCount++; \
\
/* Clear the interrupt. */ \
TA1CTL &= ~TAIFG; \
} \
\
/* Generate a 32 bit counter value by combinging the current peripheral \
counter value with the number of overflows. */ \
ulCountValue = ( ulStatsOverflowCount << 16UL ); \
ulCountValue |= ( unsigned long ) TA1R; \
TA1CTL |= MC__CONTINOUS; \
}
#endif /*0*/
#define configASSERT( x ) if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); for( ;; ); }
#endif /* FREERTOS_CONFIG_H */

View file

@ -62,8 +62,8 @@
* provide no particular functionality but do provide good examples of how to
* use the FreeRTOS API.
*
* In addition to the standard demo tasks, the following tasks, interrupts and
* tests are defined and/or created within this file:
* In addition to the standard demo tasks, the following tasks, interrupts tests
* and timers are defined and/or created within this file:
*
* "LCD" task - The LCD task is a 'gatekeeper' task. It is the only task that
* is permitted to access the LCD and therefore ensures access to the LCD is
@ -85,35 +85,24 @@
* the poll rate to ensure debouncing is not necessary and that the task does
* not use all the available CPU processing time.
*
* Button Interrupt and run time stats display - The select button on the
* joystick input device is configured to generate an external interrupt. The
* handler for this interrupt sends a message to LCD task, which interprets the
* message to mean, firstly write a message to the LCD, and secondly, generate
* a table of run time statistics. The run time statistics are displayed as a
* table that contains information on how much processing time each task has
* been allocated since the application started to execute. This information
* is provided both as an absolute time, and as a percentage of the total run
* time. The information is displayed in the terminal IO window of the IAR
* embedded workbench. The online documentation for this demo shows a screen
* shot demonstrating where the run time stats can be viewed.
* Button Interrupt - The select button on the joystick input device is
* configured to generate an external interrupt. The handler for this interrupt
* sends a message to LCD task, which then prints out a string to say the
* joystick select button was pressed.
*
* Idle Hook - The idle hook is a function that is called on each iteration of
* the idle task. In this case it is used to place the processor into a low
* power mode. Note however that this application is implemented using standard
* components, and is therefore not optimised for low power operation. Lower
* power consumption would be achieved by converting polling tasks into event
* driven tasks, and slowing the tick interrupt frequency.
* driven tasks, and slowing the tick interrupt frequency, etc.
*
* "Check" function called from the tick hook - The tick hook is called during
* each tick interrupt. It is called from an interrupt context so must execute
* quickly, not attempt to block, and not call any FreeRTOS API functions that
* do not end in "FromISR". In this case the tick hook executes a 'check'
* function. This only executes every five seconds. Its main function is to
* check that all the standard demo tasks are still operational. Each time it
* executes it sends a status code to the LCD task. The LCD task interprets the
* code and displays an appropriate message - which will be PASS if no tasks
* have reported any errors, or a message stating which task has reported an
* error.
* "Check" callback function - Called each time the 'check' timer expires. The
* check timer executes every five seconds. Its main function is to check that
* all the standard demo tasks are still operational. Each time it executes it
* sends a status code to the LCD task. The LCD task interprets the code and
* displays an appropriate message - which will be PASS if no tasks have
* reported any errors, or a message stating which task has reported an error.
*
* "Reg test" tasks - These fill the registers with known values, then check
* that each register still contains its expected value. Each task uses
@ -122,9 +111,12 @@
* test loop. A register containing an unexpected value is indicative of an
* error in the context switching mechanism and will result in a branch to a
* null loop - which in turn will prevent the check variable from incrementing
* any further and allow the check task (described a above) to determine that an
* error has occurred. The nature of the reg test tasks necessitates that they
* are written in assembly code.
* any further and allow the check timer callback (described a above) to
* determine that an error has occurred. The nature of the reg test tasks
* necessitates that they are written in assembly code.
*
* Tick hook function - called inside the RTOS tick function, this simple
* example does nothing but toggle an LED.
*
* *NOTE 1* vApplicationSetupTimerInterrupt() is called by the kernel to let
* the application set up a timer to generate the tick interrupt. In this
@ -138,6 +130,7 @@
/* FreeRTOS includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "timers.h"
#include "queue.h"
/* Hardware includes. */
@ -149,6 +142,8 @@
#include "dynamic.h"
#include "comtest2.h"
#include "GenQTest.h"
#include "TimerDemo.h"
#include "countsem.h"
/* Codes sent within messages to the LCD task so the LCD task can interpret
exactly what the message it just received was. These are sent in the
@ -164,6 +159,8 @@ of the same message and indicate what the status actually is. */
#define mainERROR_COM_TEST ( pdPASS + 2 )
#define mainERROR_GEN_QUEUE_TEST ( pdPASS + 3 )
#define mainERROR_REG_TEST ( pdPASS + 4 )
#define mainERROR_TIMER_TEST ( pdPASS + 5 )
#define mainERROR_COUNT_SEM_TEST ( pdPASS + 6 )
/* The length of the queue (the number of items the queue can hold) that is used
to send messages from tasks and interrupts the the LCD task. */
@ -178,14 +175,24 @@ to send messages from tasks and interrupts the the LCD task. */
information. */
#define mainCOM_TEST_LED ( 1 )
/* The baud rate used by the comtest tasks described at the top of this file. */
#define mainCOM_TEST_BAUD_RATE ( 38400 )
/* The baud rate used by the comtest tasks. */
#define mainCOM_TEST_BAUD_RATE ( 115200 )
/* The maximum number of lines of text that can be displayed on the LCD. */
#define mainMAX_LCD_LINES ( 8 )
/* Just used to ensure parameters are passed into tasks correctly. */
#define mainTASK_PARAMETER_CHECK_VALUE ( ( void * ) 0xDEAD )
/* The base period used by the timer test tasks. */
#define mainTIMER_TEST_PERIOD ( 50 )
/* The frequency at which the check timer (described in the comments at the top
of this file) will call its callback function. */
#define mainCHECK_TIMER_PERIOD ( 5000UL / ( unsigned long ) portTICK_RATE_MS )
/* Misc. */
#define mainDONT_BLOCK ( 0 )
/*-----------------------------------------------------------*/
/*
@ -215,7 +222,12 @@ static void prvButtonPollTask( void *pvParameters );
* Converts a status message value into an appropriate string for display on
* the LCD. The string is written to pcBuffer.
*/
static void prvGenerateStatusMessage( char *pcBuffer, long lStatusValue );
static void prvGenerateStatusMessage( char *pcBuffer, unsigned long ulStatusValue );
/*
* Defines the 'check' functionality as described at the top of this file. This
* function is the callback function for the 'check' timer. */
static void vCheckTimerCallback( xTimerHandle xTimer );
/*-----------------------------------------------------------*/
@ -229,6 +241,9 @@ volatile unsigned short usRegTest1Counter = 0, usRegTest2Counter = 0;
the LCD task. */
static xQueueHandle xLCDQueue = NULL;
/* The 'check' timer, as described at the top of this file. */
static xTimerHandle xCheckTimer = NULL;
/* The definition of each message sent from tasks and interrupts to the LCD
task. */
typedef struct
@ -239,10 +254,6 @@ typedef struct
/*-----------------------------------------------------------*/
/* The linker script tests the FreeRTOS ports use of 20bit addresses by
locating all code in high memory. The following pragma ensures that main
remains in low memory. */
#pragma CODE_SECTION(main,".main")
void main( void )
{
/* Configure the peripherals used by this demo application. This includes
@ -261,6 +272,15 @@ void main( void )
vAltStartComTestTasks( mainCOM_TEST_PRIORITY, mainCOM_TEST_BAUD_RATE, mainCOM_TEST_LED );
vStartDynamicPriorityTasks();
vStartGenericQueueTasks( mainGENERIC_QUEUE_TEST_PRIORITY );
vStartCountingSemaphoreTasks();
/* Note that creating the timer test/demo tasks will fill the timer
command queue. This is intentional, and forms part of the test the tasks
perform. It does mean however that, after this function is called, no
more timer commands can be sent until after the scheduler has been
started (at which point the timer daemon will drained the timer command
queue, freeing up space for more commands to be received). */
vStartTimerDemoTask( mainTIMER_TEST_PERIOD );
/* Create the LCD, button poll and register test tasks, as described at
the top of this file. */
@ -269,6 +289,13 @@ void main( void )
xTaskCreate( vRegTest1Task, ( signed char * ) "Reg1", configMINIMAL_STACK_SIZE, NULL, 0, NULL );
xTaskCreate( vRegTest2Task, ( signed char * ) "Reg2", configMINIMAL_STACK_SIZE, NULL, 0, NULL );
/* Create the 'check' timer - the timer that periodically calls the
check function as described at the top of this file. Note that, for
the reasons stated in the comments above the call to
vStartTimerDemoTask(), that the check timer is not actually started
until after the scheduler has been started. */
xCheckTimer = xTimerCreate( ( const signed char * ) "Check timer", mainCHECK_TIMER_PERIOD, pdTRUE, ( void * ) 0, vCheckTimerCallback );
/* Start the scheduler. */
vTaskStartScheduler();
}
@ -289,26 +316,32 @@ xQueueMessage xReceivedMessage;
LCD. Note this is a static variable to prevent it being allocated on the task
stack, which is too small to hold such a variable. The stack size is configured
when the task is created. */
static char cBuffer[ 512 ];
static char cBuffer[ 50 ];
unsigned char ucLine = 1;
/* Now the scheduler has been started (it must have been for this task to
be running), start the check timer too. The call to xTimerStart() will
block until the command has been accepted. */
if( xCheckTimer != NULL )
{
xTimerStart( xCheckTimer, portMAX_DELAY );
}
/* This function is the only function that uses printf(). If printf() is
used from any other function then some sort of mutual exclusion on stdout
will be necessary.
This is also the only function that is permitted to access the LCD.
/* This is the only function that is permitted to access the LCD.
First print out the number of bytes that remain in the FreeRTOS heap. This
can be viewed in the terminal IO window within the IAR Embedded Workbench. */
printf( "%d bytes of heap space remain unallocated\n", ( int ) xPortGetFreeHeapSize() );
fflush( stdout );
is done after a short delay to ensure all the demo tasks have created all
the objects they are going to use. */
vTaskDelay( mainTIMER_TEST_PERIOD * 10 );
sprintf( cBuffer, "%d heap free", ( int ) xPortGetFreeHeapSize() );
halLcdPrintLine( cBuffer, ucLine, OVERWRITE_TEXT );
ucLine++;
/* Just as a test of the port, and for no functional reason, check the task
parameter contains its expected value. */
if( pvParameters != mainTASK_PARAMETER_CHECK_VALUE )
{
halLcdPrintLine( "Invalid parameter", ucLine, OVERWRITE_TEXT );
halLcdPrintLine( "Invalid parameter", ucLine, OVERWRITE_TEXT );
ucLine++;
}
@ -340,33 +373,13 @@ unsigned char ucLine = 1;
case mainMESSAGE_BUTTON_SEL : /* The select button interrupt
just informed this task that the
select button was pressed.
Generate a table of task run time
statistics and output this to
the terminal IO window in the IAR
embedded workbench. */
printf( "\nTask\t Abs Time\t %%Time\n*****************************************" );
fflush( stdout );
vTaskGetRunTimeStats( ( signed char * ) cBuffer );
printf( cBuffer );
fflush( stdout );
/* Also generate and output a
table of task states. */
printf( "\nTask\t\tState Priority\tStack\t#\n*****************************************" );
fflush( stdout );
vTaskList( ( signed char * ) cBuffer );
printf( cBuffer );
fflush( stdout );
/* Finally print out a message
to the LCD - in this case the
pointer to the string to print
is sent directly in the
ulMessageValue member of the
message. This just demonstrates
a different communication
technique. */
select button has been pressed.
In this case the pointer to the
string to print is sent directly
in the ulMessageValue member of
the message. This just
demonstrates a different
communication technique. */
sprintf( cBuffer, "%s", ( char * ) xReceivedMessage.ulMessageValue );
break;
@ -391,11 +404,11 @@ unsigned char ucLine = 1;
}
/*-----------------------------------------------------------*/
static void prvGenerateStatusMessage( char *pcBuffer, long lStatusValue )
static void prvGenerateStatusMessage( char *pcBuffer, unsigned long ulStatusValue )
{
/* Just a utility function to convert a status value into a meaningful
string for output onto the LCD. */
switch( lStatusValue )
switch( ulStatusValue )
{
case pdPASS : sprintf( pcBuffer, "Status = PASS" );
break;
@ -407,6 +420,10 @@ static void prvGenerateStatusMessage( char *pcBuffer, long lStatusValue )
break;
case mainERROR_REG_TEST : sprintf( pcBuffer, "Error: Reg test" );
break;
case mainERROR_TIMER_TEST : sprintf( pcBuffer, "Error: Tmr test" );
break;
case mainERROR_COUNT_SEM_TEST : sprintf( pcBuffer, "Error: Count sem" );
break;
default : sprintf( pcBuffer, "Unknown status" );
break;
}
@ -447,6 +464,68 @@ xQueueMessage xMessage;
}
/*-----------------------------------------------------------*/
static void vCheckTimerCallback( xTimerHandle xTimer )
{
static unsigned short usLastRegTest1Counter = 0, usLastRegTest2Counter = 0;
/* Define the status message that is sent to the LCD task. By default the
status is PASS. */
static xQueueMessage xStatusMessage = { mainMESSAGE_STATUS, pdPASS };
/* This is the callback function used by the 'check' timer, as described
at the top of this file. */
/* The parameter is not used. */
( void ) xTimer;
/* See if the standard demo tasks are executing as expected, changing
the message that is sent to the LCD task from PASS to an error code if
any tasks set reports an error. */
if( xAreComTestTasksStillRunning() != pdPASS )
{
xStatusMessage.ulMessageValue = mainERROR_COM_TEST;
}
if( xAreDynamicPriorityTasksStillRunning() != pdPASS )
{
xStatusMessage.ulMessageValue = mainERROR_DYNAMIC_TASKS;
}
if( xAreGenericQueueTasksStillRunning() != pdPASS )
{
xStatusMessage.ulMessageValue = mainERROR_GEN_QUEUE_TEST;
}
if( xAreCountingSemaphoreTasksStillRunning() != pdPASS )
{
xStatusMessage.ulMessageValue = mainERROR_COUNT_SEM_TEST;
}
if( xAreTimerDemoTasksStillRunning( ( portTickType ) mainCHECK_TIMER_PERIOD ) != pdPASS )
{
xStatusMessage.ulMessageValue = mainERROR_TIMER_TEST;
}
/* Check the reg test tasks are still cycling. They will stop
incrementing their loop counters if they encounter an error. */
if( usRegTest1Counter == usLastRegTest1Counter )
{
xStatusMessage.ulMessageValue = mainERROR_REG_TEST;
}
if( usRegTest2Counter == usLastRegTest2Counter )
{
xStatusMessage.ulMessageValue = mainERROR_REG_TEST;
}
usLastRegTest1Counter = usRegTest1Counter;
usLastRegTest2Counter = usRegTest2Counter;
/* This is called from a timer callback so must not block! */
xQueueSendToBack( xLCDQueue, &xStatusMessage, mainDONT_BLOCK );
}
/*-----------------------------------------------------------*/
static void prvSetupHardware( void )
{
/* Convert a Hz value to a KHz value, as required by the Init_FLL_Settle()
@ -480,63 +559,13 @@ unsigned long ulCPU_Clock_KHz = ( configCPU_CLOCK_HZ / 1000UL );
}
/*-----------------------------------------------------------*/
void vApplicationTickHook( void )
{
static unsigned short usLastRegTest1Counter = 0, usLastRegTest2Counter = 0;
static unsigned long ulCounter = 0;
static const unsigned long ulCheckFrequency = 5000UL / portTICK_RATE_MS;
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
/* Define the status message that is sent to the LCD task. By default the
status is PASS. */
static xQueueMessage xStatusMessage = { mainMESSAGE_STATUS, pdPASS };
/* This is called from within the tick interrupt and performs the 'check'
functionality as described in the comments at the top of this file.
Is it time to perform the 'check' functionality again? */
/* Is it time to toggle the LED again? */
ulCounter++;
if( ulCounter >= ulCheckFrequency )
{
/* See if the standard demo tasks are executing as expected, changing
the message that is sent to the LCD task from PASS to an error code if
any tasks set reports an error. */
if( xAreComTestTasksStillRunning() != pdPASS )
{
xStatusMessage.ulMessageValue = mainERROR_COM_TEST;
}
if( xAreDynamicPriorityTasksStillRunning() != pdPASS )
{
xStatusMessage.ulMessageValue = mainERROR_DYNAMIC_TASKS;
}
if( xAreGenericQueueTasksStillRunning() != pdPASS )
{
xStatusMessage.ulMessageValue = mainERROR_GEN_QUEUE_TEST;
}
/* Check the reg test tasks are still cycling. They will stop
incrementing their loop counters if they encounter an error. */
if( usRegTest1Counter == usLastRegTest1Counter )
{
xStatusMessage.ulMessageValue = mainERROR_REG_TEST;
}
if( usRegTest2Counter == usLastRegTest2Counter )
{
xStatusMessage.ulMessageValue = mainERROR_REG_TEST;
}
usLastRegTest1Counter = usRegTest1Counter;
usLastRegTest2Counter = usRegTest2Counter;
/* As this is the tick hook the lHigherPriorityTaskWoken parameter is not
needed (a context switch is going to be performed anyway), but it must
still be provided. */
xQueueSendFromISR( xLCDQueue, &xStatusMessage, &xHigherPriorityTaskWoken );
ulCounter = 0;
}
/* Just periodically toggle an LED to show that the tick interrupt is
running. Note that this access LED_PORT_OUT in a non-atomic way, so tasks
@ -642,3 +671,4 @@ void vApplicationStackOverflowHook( xTaskHandle *pxTask, signed char *pcTaskName
}
/*-----------------------------------------------------------*/

View file

@ -0,0 +1,293 @@
/*
Copyright 2001, 2002 Georges Menie (www.menie.org)
stdarg version contributed by Christian Ettinger
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
putchar is the only external dependency for this file,
if you have a working putchar, leave it commented out.
If not, uncomment the define below and
replace outbyte(c) by your own function call.
*/
#define putchar(c) c
#include <stdarg.h>
static void printchar(char **str, int c)
{
//extern int putchar(int c);
if (str) {
**str = (char)c;
++(*str);
}
else
{
(void)putchar(c);
}
}
#define PAD_RIGHT 1
#define PAD_ZERO 2
static int prints(char **out, const char *string, int width, int pad)
{
register int pc = 0, padchar = ' ';
if (width > 0) {
register int len = 0;
register const char *ptr;
for (ptr = string; *ptr; ++ptr) ++len;
if (len >= width) width = 0;
else width -= len;
if (pad & PAD_ZERO) padchar = '0';
}
if (!(pad & PAD_RIGHT)) {
for ( ; width > 0; --width) {
printchar (out, padchar);
++pc;
}
}
for ( ; *string ; ++string) {
printchar (out, *string);
++pc;
}
for ( ; width > 0; --width) {
printchar (out, padchar);
++pc;
}
return pc;
}
/* the following should be enough for 32 bit int */
#define PRINT_BUF_LEN 12
static int printi(char **out, int i, int b, int sg, int width, int pad, int letbase)
{
char print_buf[PRINT_BUF_LEN];
register char *s;
register int t, neg = 0, pc = 0;
register unsigned int u = (unsigned int)i;
if (i == 0) {
print_buf[0] = '0';
print_buf[1] = '\0';
return prints (out, print_buf, width, pad);
}
if (sg && b == 10 && i < 0) {
neg = 1;
u = (unsigned int)-i;
}
s = print_buf + PRINT_BUF_LEN-1;
*s = '\0';
while (u) {
t = (unsigned int)u % b;
if( t >= 10 )
t += letbase - '0' - 10;
*--s = (char)(t + '0');
u /= b;
}
if (neg) {
if( width && (pad & PAD_ZERO) ) {
printchar (out, '-');
++pc;
--width;
}
else {
*--s = '-';
}
}
return pc + prints (out, s, width, pad);
}
static int print( char **out, const char *format, va_list args )
{
register int width, pad;
register int pc = 0;
char scr[2];
for (; *format != 0; ++format) {
if (*format == '%') {
++format;
width = pad = 0;
if (*format == '\0') break;
if (*format == '%') goto out;
if (*format == '-') {
++format;
pad = PAD_RIGHT;
}
while (*format == '0') {
++format;
pad |= PAD_ZERO;
}
for ( ; *format >= '0' && *format <= '9'; ++format) {
width *= 10;
width += *format - '0';
}
if( *format == 's' ) {
register char *s = (char *)va_arg( args, int );
pc += prints (out, s?s:"(null)", width, pad);
continue;
}
if( *format == 'd' ) {
pc += printi (out, va_arg( args, int ), 10, 1, width, pad, 'a');
continue;
}
if( *format == 'x' ) {
pc += printi (out, va_arg( args, int ), 16, 0, width, pad, 'a');
continue;
}
if( *format == 'X' ) {
pc += printi (out, va_arg( args, int ), 16, 0, width, pad, 'A');
continue;
}
if( *format == 'u' ) {
pc += printi (out, va_arg( args, int ), 10, 0, width, pad, 'a');
continue;
}
if( *format == 'c' ) {
/* char are converted to int then pushed on the stack */
scr[0] = (char)va_arg( args, int );
scr[1] = '\0';
pc += prints (out, scr, width, pad);
continue;
}
}
else {
out:
printchar (out, *format);
++pc;
}
}
if (out) **out = '\0';
va_end( args );
return pc;
}
int printf(const char *format, ...)
{
va_list args;
va_start( args, format );
return print( 0, format, args );
}
int sprintf(char *out, const char *format, ...)
{
va_list args;
va_start( args, format );
return print( &out, format, args );
}
int snprintf( char *buf, unsigned int count, const char *format, ... )
{
va_list args;
( void ) count;
va_start( args, format );
return print( &buf, format, args );
}
#ifdef TEST_PRINTF
int main(void)
{
char *ptr = "Hello world!";
char *np = 0;
int i = 5;
unsigned int bs = sizeof(int)*8;
int mi;
char buf[80];
mi = (1 << (bs-1)) + 1;
printf("%s\n", ptr);
printf("printf test\n");
printf("%s is null pointer\n", np);
printf("%d = 5\n", i);
printf("%d = - max int\n", mi);
printf("char %c = 'a'\n", 'a');
printf("hex %x = ff\n", 0xff);
printf("hex %02x = 00\n", 0);
printf("signed %d = unsigned %u = hex %x\n", -3, -3, -3);
printf("%d %s(s)%", 0, "message");
printf("\n");
printf("%d %s(s) with %%\n", 0, "message");
sprintf(buf, "justif: \"%-10s\"\n", "left"); printf("%s", buf);
sprintf(buf, "justif: \"%10s\"\n", "right"); printf("%s", buf);
sprintf(buf, " 3: %04d zero padded\n", 3); printf("%s", buf);
sprintf(buf, " 3: %-4d left justif.\n", 3); printf("%s", buf);
sprintf(buf, " 3: %4d right justif.\n", 3); printf("%s", buf);
sprintf(buf, "-3: %04d zero padded\n", -3); printf("%s", buf);
sprintf(buf, "-3: %-4d left justif.\n", -3); printf("%s", buf);
sprintf(buf, "-3: %4d right justif.\n", -3); printf("%s", buf);
return 0;
}
/*
* if you compile this file with
* gcc -Wall $(YOUR_C_OPTIONS) -DTEST_PRINTF -c printf.c
* you will get a normal warning:
* printf.c:214: warning: spurious trailing `%' in format
* this line is testing an invalid % at the end of the format string.
*
* this should display (on 32bit int machine) :
*
* Hello world!
* printf test
* (null) is null pointer
* 5 = 5
* -2147483647 = - max int
* char a = 'a'
* hex ff = ff
* hex 00 = 00
* signed -3 = unsigned 4294967293 = hex fffffffd
* 0 message(s)
* 0 message(s) with %
* justif: "left "
* justif: " right"
* 3: 0003 zero padded
* 3: 3 left justif.
* 3: 3 right justif.
* -3: -003 zero padded
* -3: -3 left justif.
* -3: -3 right justif.
*/
#endif
/* To keep linker happy. */
int write( int i, char* c, int n)
{
(void)i;
(void)n;
(void)c;
return 0;
}

View file

@ -95,8 +95,8 @@ unsigned portLONG ulBaudRateCount;
portENTER_CRITICAL();
{
/* Create the queues used by the com test task. */
xRxedChars = xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE ) sizeof( signed portCHAR ) );
xCharsForTx = xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE ) sizeof( signed portCHAR ) );
xRxedChars = xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE ) sizeof( signed char ) );
xCharsForTx = xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE ) sizeof( signed char ) );
/* Reset UART. */
UCA1CTL1 |= UCSWRST;
@ -105,11 +105,11 @@ unsigned portLONG ulBaudRateCount;
UCA1CTL1 = UCSSEL0 | UCSSEL1;
/* Setup baud rate low byte. */
UCA1BR0 = ( unsigned portCHAR ) ( ulBaudRateCount & ( unsigned portLONG ) 0xff );
UCA1BR0 = ( unsigned portCHAR ) ( ulBaudRateCount & ( unsigned long ) 0xff );
/* Setup baud rate high byte. */
ulBaudRateCount >>= 8UL;
UCA1BR1 = ( unsigned portCHAR ) ( ulBaudRateCount & ( unsigned portLONG ) 0xff );
UCA1BR1 = ( unsigned portCHAR ) ( ulBaudRateCount & ( unsigned long ) 0xff );
/* UCLISTEN sets loopback mode! */
UCA1STAT = UCLISTEN;
@ -152,16 +152,21 @@ signed portBASE_TYPE xReturn;
completed and switched itself off. */
xReturn = xQueueSend( xCharsForTx, &cOutChar, xBlockTime );
UCA1IE |= UCTXIE;
return xReturn;
}
/*-----------------------------------------------------------*/
/* The implementation of this interrupt is provided to demonstrate the use
of queues from inside an interrupt service routine. It is *not* intended to
be an efficient interrupt implementation. A real application should make use
of the DMA. Or, as a minimum, transmission and reception could use a simple
RAM ring buffer, and synchronise with a task using a semaphore when a complete
message has been received or transmitted. */
#pragma vector=USCI_A1_VECTOR
interrupt void prvUSCI_A1_ISR( void )
{
signed portCHAR cChar;
portBASE_TYPE xTaskWoken = pdFALSE;
signed char cChar;
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
while( ( UCA1IFG & UCRXIFG ) != 0 )
@ -177,7 +182,7 @@ portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
{
/* The previous character has been transmitted. See if there are any
further characters waiting transmission. */
if( xQueueReceiveFromISR( xCharsForTx, &cChar, &xTaskWoken ) == pdTRUE )
if( xQueueReceiveFromISR( xCharsForTx, &cChar, &xHigherPriorityTaskWoken ) == pdTRUE )
{
/* There was another character queued - transmit it now. */
UCA1TXBUF = cChar;
@ -189,7 +194,7 @@ portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
UCA1IE &= ~UCTXIE;
}
}
__bic_SR_register_on_exit( SCG1 + SCG0 + OSCOFF + CPUOFF );
/* If writing to a queue caused a task to unblock, and the unblocked task

View file

@ -110,7 +110,7 @@ SECTIONS
/* Original line. */
.text : {}>> FLASH | FLASH2 /* CODE */
/* Modified line. */
/* .text : {}>> FLASH2 */ /* CODE */
/* .text : {}>> FLASH2 */ /* CODE */
.main : {} > FLASH
.text:_isr : {} > FLASH /* ISR CODE SPACE */
.cinit : {} > FLASH /* INITIALIZATION TABLES */