mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-09-02 04:13:54 -04:00
Continue to develop the MSP430X IAR demo project - still a work in progress.
This commit is contained in:
parent
df4e7ceba0
commit
ae6380f70b
8 changed files with 522 additions and 32 deletions
|
@ -50,15 +50,23 @@
|
|||
http://www.OpenRTOS.com - Commercial support, development, porting,
|
||||
licensing and training services.
|
||||
*/
|
||||
|
||||
/* Standard includes. */
|
||||
#include <stdio.h>
|
||||
|
||||
/* FreeRTOS includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "queue.h"
|
||||
|
||||
/* Hardware includes. */
|
||||
#include "msp430.h"
|
||||
#include "hal_MSP-EXP430F5438.h"
|
||||
|
||||
/* Standard demo includes. */
|
||||
#include "ParTest.h"
|
||||
#include "comtest2.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
|
||||
cMessageID member of the message structure (defined below). */
|
||||
|
@ -67,7 +75,7 @@ cMessageID member of the message structure (defined below). */
|
|||
#define mainMESSAGE_STATUS ( 3 )
|
||||
|
||||
/* When the cMessageID member of the message sent to the LCD task is
|
||||
mainMESSAGE_STATUS then these definitions are sent in the cMessageValue member
|
||||
mainMESSAGE_STATUS then these definitions are sent in the ulMessageValue member
|
||||
of the same message and indicate what the status actually is. */
|
||||
#define mainERROR_DYNAMIC_TASKS ( pdPASS + 1 )
|
||||
#define mainERROR_COM_TEST ( pdPASS + 2 )
|
||||
|
@ -79,6 +87,13 @@ to send messages from tasks and interrupts the the LCD task. */
|
|||
#define mainQUEUE_LENGTH ( 5 )
|
||||
|
||||
#define mainLCD_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
|
||||
#define mainCOM_TEST_PRIORITY ( tskIDLE_PRIORITY + 2 )
|
||||
|
||||
/* The LED used by the comtest tasks. See the comtest.c file for more
|
||||
information. In this case it is deliberately out of range as there are only
|
||||
two LEDs, and they are both already in use. */
|
||||
#define mainCOM_TEST_LED ( 3 )
|
||||
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
@ -92,6 +107,7 @@ static void prvGenerateStatusMessage( char *pcBuffer, long lStatusValue );
|
|||
/*-----------------------------------------------------------*/
|
||||
|
||||
volatile unsigned short usRegTest1Counter = 0, usRegTest2Counter = 0;
|
||||
volatile unsigned long ulStatsOverflowCount = 0;
|
||||
|
||||
/* The handle of the queue used to send messages from tasks and interrupts to
|
||||
the LCD task. */
|
||||
|
@ -102,31 +118,34 @@ task. */
|
|||
typedef struct
|
||||
{
|
||||
char cMessageID; /* << States what the message is. */
|
||||
char cMessageValue; /* << States the message value (can be an integer, string pointer, etc. depending on the value of cMessageID. */
|
||||
unsigned long ulMessageValue; /* << States the message value (can be an integer, string pointer, etc. depending on the value of cMessageID. */
|
||||
} xQueueMessage;
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void main( void )
|
||||
{
|
||||
prvSetupHardware();
|
||||
|
||||
|
||||
/* Create the queue used by tasks and interrupts to send strings to the LCD
|
||||
task. */
|
||||
xLCDQueue = xQueueCreate( mainQUEUE_LENGTH, sizeof( xQueueMessage ) );
|
||||
|
||||
|
||||
if( xLCDQueue != NULL )
|
||||
{
|
||||
/* Add the created queue to the queue registry so it can be viewed in
|
||||
the IAR FreeRTOS state viewer plug-in. */
|
||||
vQueueAddToRegistry( xLCDQueue, "LCDQueue" );
|
||||
|
||||
/* Create the standard demo tasks. */
|
||||
vAltStartComTestTasks( mainCOM_TEST_PRIORITY, 9600, mainCOM_TEST_LED );
|
||||
|
||||
/* Create the terminal IO and button poll tasks, as described at the top
|
||||
of this file. */
|
||||
xTaskCreate( prvTerminalIOTask, ( signed char * ) "IO", configMINIMAL_STACK_SIZE, NULL, mainLCD_TASK_PRIORITY, NULL );
|
||||
xTaskCreate( prvButtonPollTask, ( signed char * ) "ButPoll", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
|
||||
xTaskCreate( prvTerminalIOTask, ( signed char * ) "IO", configMINIMAL_STACK_SIZE * 2, NULL, mainLCD_TASK_PRIORITY, NULL );
|
||||
xTaskCreate( prvButtonPollTask, ( signed char * ) "BPoll", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
|
||||
|
||||
xTaskCreate( vRegTest1Task, "RegTest1", configMINIMAL_STACK_SIZE, NULL, 0, NULL );
|
||||
xTaskCreate( vRegTest2Task, "RegTest2", configMINIMAL_STACK_SIZE, NULL, 0, NULL );
|
||||
xTaskCreate( vRegTest1Task, "Reg1", configMINIMAL_STACK_SIZE, NULL, 0, NULL );
|
||||
xTaskCreate( vRegTest2Task, "Reg2", configMINIMAL_STACK_SIZE, NULL, 0, NULL );
|
||||
vTaskStartScheduler();
|
||||
}
|
||||
for( ;; );
|
||||
|
@ -169,7 +188,7 @@ static char cBuffer[ 512 ];
|
|||
informed this task that the up
|
||||
button on the joystick input has
|
||||
been pressed or released. */
|
||||
sprintf( cBuffer, "Button up = %d", xReceivedMessage.cMessageValue );
|
||||
sprintf( cBuffer, "Button up = %d", ( int ) xReceivedMessage.ulMessageValue );
|
||||
break;
|
||||
|
||||
case mainMESSAGE_BUTTON_SEL : /* The select button interrupt
|
||||
|
@ -180,7 +199,8 @@ static char cBuffer[ 512 ];
|
|||
the terminal IO window in the IAR
|
||||
embedded workbench. */
|
||||
printf( "\nTask\t Abs Time\t %%Time\n*****************************************" );
|
||||
// vTaskGetRunTimeStats( ( signed char * ) cBuffer );
|
||||
fflush( stdout );
|
||||
vTaskGetRunTimeStats( ( signed char * ) cBuffer );
|
||||
// printf( cBuffer );
|
||||
break;
|
||||
|
||||
|
@ -189,7 +209,7 @@ static char cBuffer[ 512 ];
|
|||
task of the system status.
|
||||
Generate a string in accordance
|
||||
with the status value. */
|
||||
prvGenerateStatusMessage( cBuffer, xReceivedMessage.cMessageValue );
|
||||
prvGenerateStatusMessage( cBuffer, xReceivedMessage.ulMessageValue );
|
||||
break;
|
||||
|
||||
default : sprintf( cBuffer, "Unknown message" );
|
||||
|
@ -214,7 +234,7 @@ static void prvGenerateStatusMessage( char *pcBuffer, long lStatusValue )
|
|||
break;
|
||||
case mainERROR_DYNAMIC_TASKS : sprintf( pcBuffer, "Error: Dynamic tasks" );
|
||||
break;
|
||||
case mainERROR_COM_TEST : sprintf( pcBuffer, "Err: loop connected?" ); /* Error in COM test - is the Loopback connector connected? */
|
||||
case mainERROR_COM_TEST : sprintf( pcBuffer, "Err: COM test" ); /* Error in COM test - is the Loopback connector connected? */
|
||||
break;
|
||||
case mainERROR_GEN_QUEUE_TEST : sprintf( pcBuffer, "Error: Gen Q test" );
|
||||
break;
|
||||
|
@ -247,7 +267,7 @@ xQueueMessage xMessage;
|
|||
{
|
||||
/* The state has changed, send a message to the LCD task. */
|
||||
xMessage.cMessageID = mainMESSAGE_BUTTON_UP;
|
||||
xMessage.cMessageValue = ucState;
|
||||
xMessage.ulMessageValue = ( unsigned long ) ucState;
|
||||
ucLastState = ucState;
|
||||
xQueueSend( xLCDQueue, &xMessage, portMAX_DELAY );
|
||||
}
|
||||
|
@ -261,11 +281,13 @@ xQueueMessage xMessage;
|
|||
|
||||
static void prvSetupHardware( void )
|
||||
{
|
||||
unsigned long ulCPU_Clock_KHz = ( configCPU_CLOCK_HZ / 1000UL );
|
||||
|
||||
halBoardInit();
|
||||
halButtonsInit( BUTTON_ALL );
|
||||
halButtonsInterruptEnable( BUTTON_SELECT );
|
||||
LFXT_Start (XT1DRIVE_0);
|
||||
Init_FLL_Settle( 18000, 488 );
|
||||
LFXT_Start( XT1DRIVE_0 );
|
||||
Init_FLL_Settle( ( unsigned short ) ulCPU_Clock_KHz, 488 );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
@ -276,7 +298,7 @@ const unsigned short usACLK_Frequency_Hz = 32768;
|
|||
/* Ensure the timer is stopped. */
|
||||
TA0CTL = 0;
|
||||
|
||||
/* Run the timer of the ACLK. */
|
||||
/* Run the timer from the ACLK. */
|
||||
TA0CTL = TASSEL_1;
|
||||
|
||||
/* Clear everything to start with. */
|
||||
|
@ -344,26 +366,30 @@ static xQueueMessage xStatusMessage = { mainMESSAGE_STATUS, pdPASS };
|
|||
xStatusMessage.lMessageValue = mainERROR_DYNAMIC_TASKS;
|
||||
}
|
||||
|
||||
if( xAreComTestTasksStillRunning() != pdPASS )
|
||||
{
|
||||
xStatusMessage.lMessageValue = mainERROR_COM_TEST;
|
||||
}
|
||||
|
||||
if( xAreGenericQueueTasksStillRunning() != pdPASS )
|
||||
{
|
||||
xStatusMessage.lMessageValue = mainERROR_GEN_QUEUE_TEST;
|
||||
}
|
||||
#else
|
||||
/* 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;
|
||||
}
|
||||
|
||||
|
||||
/* Check the reg test tasks are still cycling. They will stop incrementing
|
||||
their loop counters if they encounter an error. */
|
||||
if( usRegTest1Counter == usLastRegTest1Counter )
|
||||
{
|
||||
xStatusMessage.cMessageValue = mainERROR_REG_TEST;
|
||||
xStatusMessage.ulMessageValue = mainERROR_REG_TEST;
|
||||
}
|
||||
|
||||
if( usRegTest2Counter == usLastRegTest2Counter )
|
||||
{
|
||||
xStatusMessage.cMessageValue = mainERROR_REG_TEST;
|
||||
xStatusMessage.ulMessageValue = mainERROR_REG_TEST;
|
||||
}
|
||||
|
||||
usLastRegTest1Counter = usRegTest1Counter;
|
||||
|
@ -391,5 +417,70 @@ static xQueueMessage xStatusMessage = { mainMESSAGE_STATUS, pdPASS };
|
|||
}
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#pragma vector=PORT2_VECTOR
|
||||
__interrupt static void prvSelectButtonInterrupt(void)
|
||||
{
|
||||
/* Define the message sent to the LCD task from this interrupt. */
|
||||
static const xQueueMessage xMessage = { mainMESSAGE_BUTTON_SEL, ( unsigned long ) "Select Interrupt!" };
|
||||
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
|
||||
|
||||
/* This is the interrupt handler for the joystick select button input.
|
||||
The button has been pushed, write a message to the LCD via the LCD task. */
|
||||
xQueueSendFromISR( xLCDQueue, &xMessage, &xHigherPriorityTaskWoken );
|
||||
|
||||
P2IFG = 0;
|
||||
|
||||
/* If writing to xLCDQueue caused a task to unblock, and the unblocked task
|
||||
has a priority equal to or above the task that this interrupt interrupted,
|
||||
then lHigherPriorityTaskWoken will have been set to pdTRUE internally within
|
||||
xQueuesendFromISR(), and portEND_SWITCHING_ISR() will ensure that this
|
||||
interrupt returns directly to the higher priority unblocked task. */
|
||||
portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vConfigureTimerForRunTimeStats( void )
|
||||
{
|
||||
/* Ensure the timer is stopped. */
|
||||
TA1CTL = 0;
|
||||
|
||||
/* Run the timer from the ACLK/4. */
|
||||
TA1CTL = TASSEL_1 | ID__4;
|
||||
|
||||
/* Clear everything to start with. */
|
||||
TA1CTL |= TACLR;
|
||||
|
||||
/* Enable the interrupts. */
|
||||
TA1CCTL0 = CCIE;
|
||||
|
||||
/* Start up clean. */
|
||||
TA1CTL |= TACLR;
|
||||
|
||||
/* Continuous mode. */
|
||||
TA1CTL |= MC__CONTINOUS;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#pragma vector=TIMER1_A0_VECTOR
|
||||
static __interrupt void prvRunTimeStatsOverflowISR( void )
|
||||
{
|
||||
ulStatsOverflowCount++;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
inline unsigned long ulGetRunTimeStatsTime( void )
|
||||
{
|
||||
unsigned long ulReturn;
|
||||
|
||||
TA1CTL &= ~MC__CONTINOUS;
|
||||
ulReturn = ( ( ulStatsOverflowCount << 16UL ) | ( unsigned long ) TA1R );
|
||||
TA1CTL |= MC__CONTINOUS;
|
||||
|
||||
return ulReturn;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue