OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [freertos-6.1.1/] [Demo/] [MSP430X_MSP430F5438_CCS4/] [Demo_Source/] [main.c] - Blame information for rev 598

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 584 jeremybenn
/*
2
    FreeRTOS V6.1.1 - Copyright (C) 2011 Real Time Engineers Ltd.
3
 
4
    ***************************************************************************
5
    *                                                                         *
6
    * If you are:                                                             *
7
    *                                                                         *
8
    *    + New to FreeRTOS,                                                   *
9
    *    + Wanting to learn FreeRTOS or multitasking in general quickly       *
10
    *    + Looking for basic training,                                        *
11
    *    + Wanting to improve your FreeRTOS skills and productivity           *
12
    *                                                                         *
13
    * then take a look at the FreeRTOS books - available as PDF or paperback  *
14
    *                                                                         *
15
    *        "Using the FreeRTOS Real Time Kernel - a Practical Guide"        *
16
    *                  http://www.FreeRTOS.org/Documentation                  *
17
    *                                                                         *
18
    * A pdf reference manual is also available.  Both are usually delivered   *
19
    * to your inbox within 20 minutes to two hours when purchased between 8am *
20
    * and 8pm GMT (although please allow up to 24 hours in case of            *
21
    * exceptional circumstances).  Thank you for your support!                *
22
    *                                                                         *
23
    ***************************************************************************
24
 
25
    This file is part of the FreeRTOS distribution.
26
 
27
    FreeRTOS is free software; you can redistribute it and/or modify it under
28
    the terms of the GNU General Public License (version 2) as published by the
29
    Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
30
    ***NOTE*** The exception to the GPL is included to allow you to distribute
31
    a combined work that includes FreeRTOS without being obliged to provide the
32
    source code for proprietary components outside of the FreeRTOS kernel.
33
    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT
34
    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
35
    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
36
    more details. You should have received a copy of the GNU General Public
37
    License and the FreeRTOS license exception along with FreeRTOS; if not it
38
    can be viewed here: http://www.freertos.org/a00114.html and also obtained
39
    by writing to Richard Barry, contact details for whom are available on the
40
    FreeRTOS WEB site.
41
 
42
    1 tab == 4 spaces!
43
 
44
    http://www.FreeRTOS.org - Documentation, latest information, license and
45
    contact details.
46
 
47
    http://www.SafeRTOS.com - A version that is certified for use in safety
48
    critical systems.
49
 
50
    http://www.OpenRTOS.com - Commercial support, development, porting,
51
    licensing and training services.
52
*/
53
 
54
/*
55
 * The documentation page for this demo available on http://www.FreeRTOS.org
56
 * documents the hardware configuration required to run this demo.  It also
57
 * provides more information on the expected demo application behaviour.
58
 *
59
 * main() creates all the demo application tasks, then starts the scheduler.
60
 * A lot of the created tasks are from the pool of "standard demo" tasks.  The
61
 * web documentation provides more details of the standard demo tasks, which
62
 * provide no particular functionality but do provide good examples of how to
63
 * use the FreeRTOS API.
64
 *
65
 * In addition to the standard demo tasks, the following tasks, interrupts and
66
 * tests are defined and/or created within this file:
67
 *
68
 * "LCD" task - The LCD task is a 'gatekeeper' task.  It is the only task that
69
 * is permitted to access the LCD and therefore ensures access to the LCD is
70
 * always serialised and there are no mutual exclusion issues.  When a task or
71
 * an interrupt wants to write to the LCD, it does not access the LCD directly
72
 * but instead sends the message to the LCD task.  The LCD task then performs
73
 * the actual LCD output.  This mechanism also allows interrupts to, in effect,
74
 * write to the LCD by sending messages to the LCD task.
75
 *
76
 * The LCD task is also a demonstration of a 'controller' task design pattern.
77
 * Some tasks do not actually send a string to the LCD task directly, but
78
 * instead send a command that is interpreted by the LCD task.  In a normal
79
 * application these commands can be control values or set points, in this
80
 * simple example the commands just result in messages being displayed on the
81
 * LCD.
82
 *
83
 * "Button Poll" task - This task polls the state of the 'up' key on the
84
 * joystick input device.  It uses the vTaskDelay() API function to control
85
 * the poll rate to ensure debouncing is not necessary and that the task does
86
 * not use all the available CPU processing time.
87
 *
88
 * Button Interrupt and run time stats display - The select button on the
89
 * joystick input device is configured to generate an external interrupt.  The
90
 * handler for this interrupt sends a message to LCD task, which interprets the
91
 * message to mean, firstly write a message to the LCD, and secondly, generate
92
 * a table of run time statistics.  The run time statistics are displayed as a
93
 * table that contains information on how much processing time each task has
94
 * been allocated since the application started to execute.  This information
95
 * is provided both as an absolute time, and as a percentage of the total run
96
 * time.  The information is displayed in the terminal IO window of the IAR
97
 * embedded workbench.  The online documentation for this demo shows a screen
98
 * shot demonstrating where the run time stats can be viewed.
99
 *
100
 * Idle Hook - The idle hook is a function that is called on each iteration of
101
 * the idle task.  In this case it is used to place the processor into a low
102
 * power mode.  Note however that this application is implemented using standard
103
 * components, and is therefore not optimised for low power operation.  Lower
104
 * power consumption would be achieved by converting polling tasks into event
105
 * driven tasks, and slowing the tick interrupt frequency.
106
 *
107
 * "Check" function called from the tick hook - The tick hook is called during
108
 * each tick interrupt.  It is called from an interrupt context so must execute
109
 * quickly, not attempt to block, and not call any FreeRTOS API functions that
110
 * do not end in "FromISR".  In this case the tick hook executes a 'check'
111
 * function.  This only executes every five seconds.  Its main function is to
112
 * check that all the standard demo tasks are still operational.  Each time it
113
 * executes it sends a status code to the LCD task.  The LCD task interprets the
114
 * code and displays an appropriate message - which will be PASS if no tasks
115
 * have reported any errors, or a message stating which task has reported an
116
 * error.
117
 *
118
 * "Reg test" tasks - These fill the registers with known values, then check
119
 * that each register still contains its expected value.  Each task uses
120
 * different values.  The tasks run with very low priority so get preempted
121
 * very frequently.  A check variable is incremented on each iteration of the
122
 * test loop.  A register containing an unexpected value is indicative of an
123
 * error in the context switching mechanism and will result in a branch to a
124
 * null loop - which in turn will prevent the check variable from incrementing
125
 * any further and allow the check task (described a above) to determine that an
126
 * error has occurred.  The nature of the reg test tasks necessitates that they
127
 * are written in assembly code.
128
 *
129
 * *NOTE 1* vApplicationSetupTimerInterrupt() is called by the kernel to let
130
 * the application set up a timer to generate the tick interrupt.  In this
131
 * example a timer A0 is used for this purpose.
132
 *
133
*/
134
 
135
/* Standard includes. */
136
#include <stdio.h>
137
 
138
/* FreeRTOS includes. */
139
#include "FreeRTOS.h"
140
#include "task.h"
141
#include "queue.h"
142
 
143
/* Hardware includes. */
144
#include "msp430.h"
145
#include "hal_MSP-EXP430F5438.h"
146
 
147
/* Standard demo includes. */
148
#include "ParTest.h"
149
#include "dynamic.h"
150
#include "comtest2.h"
151
#include "GenQTest.h"
152
 
153
/* Codes sent within messages to the LCD task so the LCD task can interpret
154
exactly what the message it just received was.  These are sent in the
155
cMessageID member of the message structure (defined below). */
156
#define mainMESSAGE_BUTTON_UP                   ( 1 )
157
#define mainMESSAGE_BUTTON_SEL                  ( 2 )
158
#define mainMESSAGE_STATUS                              ( 3 )
159
 
160
/* When the cMessageID member of the message sent to the LCD task is
161
mainMESSAGE_STATUS then these definitions are sent in the ulMessageValue member
162
of the same message and indicate what the status actually is. */
163
#define mainERROR_DYNAMIC_TASKS                 ( pdPASS + 1 )
164
#define mainERROR_COM_TEST                              ( pdPASS + 2 )
165
#define mainERROR_GEN_QUEUE_TEST                ( pdPASS + 3 )
166
#define mainERROR_REG_TEST                              ( pdPASS + 4 )
167
 
168
/* The length of the queue (the number of items the queue can hold) that is used
169
to send messages from tasks and interrupts the the LCD task. */
170
#define mainQUEUE_LENGTH                                ( 5 )
171
 
172
/* Priorities used by the test and demo tasks. */
173
#define mainLCD_TASK_PRIORITY                   ( tskIDLE_PRIORITY + 1 )
174
#define mainCOM_TEST_PRIORITY                   ( tskIDLE_PRIORITY + 2 )
175
#define mainGENERIC_QUEUE_TEST_PRIORITY ( tskIDLE_PRIORITY )
176
 
177
/* The LED used by the comtest tasks. See the comtest.c file for more
178
information.  */
179
#define mainCOM_TEST_LED                                ( 1 )
180
 
181
/* The baud rate used by the comtest tasks described at the top of this file. */
182
#define mainCOM_TEST_BAUD_RATE                  ( 38400 )
183
 
184
/* The maximum number of lines of text that can be displayed on the LCD. */
185
#define mainMAX_LCD_LINES                               ( 8 )
186
 
187
/* Just used to ensure parameters are passed into tasks correctly. */
188
#define mainTASK_PARAMETER_CHECK_VALUE  ( ( void * ) 0xDEAD )
189
/*-----------------------------------------------------------*/
190
 
191
/*
192
 * The reg test tasks as described at the top of this file.
193
 */
194
extern void vRegTest1Task( void *pvParameters );
195
extern void vRegTest2Task( void *pvParameters );
196
 
197
/*
198
 * Configures clocks, LCD, port pints, etc. necessary to execute this demo.
199
 */
200
static void prvSetupHardware( void );
201
 
202
/*
203
 * Definition of the LCD/controller task described in the comments at the top
204
 * of this file.
205
 */
206
static void prvLCDTask( void *pvParameters );
207
 
208
/*
209
 * Definition of the button poll task described in the comments at the top of
210
 * this file.
211
 */
212
static void prvButtonPollTask( void *pvParameters );
213
 
214
/*
215
 * Converts a status message value into an appropriate string for display on
216
 * the LCD.  The string is written to pcBuffer.
217
 */
218
static void prvGenerateStatusMessage( char *pcBuffer, long lStatusValue );
219
 
220
/*-----------------------------------------------------------*/
221
 
222
/* Variables that are incremented on each iteration of the reg test tasks -
223
provided the tasks have not reported any errors.  The check task inspects these
224
variables to ensure they are still incrementing as expected.  If a variable
225
stops incrementing then it is likely that its associate task has stalled. */
226
volatile unsigned short usRegTest1Counter = 0, usRegTest2Counter = 0;
227
 
228
/* The handle of the queue used to send messages from tasks and interrupts to
229
the LCD task. */
230
static xQueueHandle xLCDQueue = NULL;
231
 
232
/* The definition of each message sent from tasks and interrupts to the LCD
233
task. */
234
typedef struct
235
{
236
        char cMessageID;                                /* << States what the message is. */
237
        unsigned long ulMessageValue;   /* << States the message value (can be an integer, string pointer, etc. depending on the value of cMessageID). */
238
} xQueueMessage;
239
 
240
/*-----------------------------------------------------------*/
241
 
242
/* The linker script tests the FreeRTOS ports use of 20bit addresses by
243
locating all code in high memory.  The following pragma ensures that main
244
remains in low memory. */
245
#pragma CODE_SECTION(main,".main")
246
void main( void )
247
{
248
        /* Configure the peripherals used by this demo application.  This includes
249
        configuring the joystick input select button to generate interrupts. */
250
        prvSetupHardware();
251
 
252
        /* Create the queue used by tasks and interrupts to send strings to the LCD
253
        task. */
254
        xLCDQueue = xQueueCreate( mainQUEUE_LENGTH, sizeof( xQueueMessage ) );
255
 
256
        /* If the queue could not be created then don't create any tasks that might
257
        attempt to use the queue. */
258
        if( xLCDQueue != NULL )
259
        {
260
                /* Create the standard demo tasks. */
261
                vAltStartComTestTasks( mainCOM_TEST_PRIORITY, mainCOM_TEST_BAUD_RATE, mainCOM_TEST_LED );
262
                vStartDynamicPriorityTasks();
263
                vStartGenericQueueTasks( mainGENERIC_QUEUE_TEST_PRIORITY );
264
 
265
                /* Create the LCD, button poll and register test tasks, as described at
266
                the top of this file. */
267
                xTaskCreate( prvLCDTask, ( signed char * ) "LCD", configMINIMAL_STACK_SIZE * 2, mainTASK_PARAMETER_CHECK_VALUE, mainLCD_TASK_PRIORITY, NULL );
268
                xTaskCreate( prvButtonPollTask, ( signed char * ) "BPoll", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
269
                xTaskCreate( vRegTest1Task, ( signed char * ) "Reg1", configMINIMAL_STACK_SIZE, NULL, 0, NULL );
270
                xTaskCreate( vRegTest2Task, ( signed char * ) "Reg2", configMINIMAL_STACK_SIZE, NULL, 0, NULL );
271
 
272
                /* Start the scheduler. */
273
                vTaskStartScheduler();
274
        }
275
 
276
        /* If all is well then this line will never be reached.  If it is reached
277
        then it is likely that there was insufficient (FreeRTOS) heap memory space
278
        to create the idle task.  This may have been trapped by the malloc() failed
279
        hook function, if one is configured. */
280
        for( ;; );
281
}
282
/*-----------------------------------------------------------*/
283
 
284
static void prvLCDTask( void *pvParameters )
285
{
286
xQueueMessage xReceivedMessage;
287
 
288
/* Buffer into which strings are formatted and placed ready for display on the
289
LCD.  Note this is a static variable to prevent it being allocated on the task
290
stack, which is too small to hold such a variable.  The stack size is configured
291
when the task is created. */
292
static char cBuffer[ 512 ];
293
unsigned char ucLine = 1;
294
 
295
 
296
        /* This function is the only function that uses printf().  If printf() is
297
        used from any other function then some sort of mutual exclusion on stdout
298
        will be necessary.
299
 
300
        This is also the only function that is permitted to access the LCD.
301
 
302
        First print out the number of bytes that remain in the FreeRTOS heap.  This
303
        can be viewed in the terminal IO window within the IAR Embedded Workbench. */
304
        printf( "%d bytes of heap space remain unallocated\n", ( int ) xPortGetFreeHeapSize() );
305
        fflush( stdout );
306
 
307
        /* Just as a test of the port, and for no functional reason, check the task
308
        parameter contains its expected value. */
309
        if( pvParameters != mainTASK_PARAMETER_CHECK_VALUE )
310
        {
311
                halLcdPrintLine( "Invalid parameter", ucLine,  OVERWRITE_TEXT );
312
                ucLine++;
313
        }
314
 
315
        for( ;; )
316
        {
317
                /* Wait for a message to be received.  Using portMAX_DELAY as the block
318
                time will result in an indefinite wait provided INCLUDE_vTaskSuspend is
319
                set to 1 in FreeRTOSConfig.h, therefore there is no need to check the
320
                function return value and the function will only return when a value
321
                has been received. */
322
                xQueueReceive( xLCDQueue, &xReceivedMessage, portMAX_DELAY );
323
 
324
                /* Clear the LCD if no room remains for any more text output. */
325
                if( ucLine > mainMAX_LCD_LINES )
326
                {
327
                        halLcdClearScreen();
328
                        ucLine = 0;
329
                }
330
 
331
                /* What is this message?  What does it contain? */
332
                switch( xReceivedMessage.cMessageID )
333
                {
334
                        case mainMESSAGE_BUTTON_UP              :       /* The button poll task has just
335
                                                                                                informed this task that the up
336
                                                                                                button on the joystick input has
337
                                                                                                been pressed or released. */
338
                                                                                                sprintf( cBuffer, "Button up = %d", ( int ) xReceivedMessage.ulMessageValue );
339
                                                                                                break;
340
 
341
                        case mainMESSAGE_BUTTON_SEL             :       /* The select button interrupt
342
                                                                                                just informed this task that the
343
                                                                                                select button was pressed.
344
                                                                                                Generate a table of task run time
345
                                                                                                statistics and output this to
346
                                                                                                the terminal IO window in the IAR
347
                                                                                                embedded workbench. */
348
                                                                                                printf( "\nTask\t     Abs Time\t     %%Time\n*****************************************" );
349
                                                                                                fflush( stdout );
350
                                                                                                vTaskGetRunTimeStats( ( signed char * ) cBuffer );
351
                                                                                                printf( cBuffer );
352
                                                                                                fflush( stdout );
353
 
354
                                                                                                /* Also generate and output a
355
                                                                                                table of task states. */
356
                                                                                                printf( "\nTask\t\tState Priority\tStack\t#\n*****************************************" );
357
                                                                                                fflush( stdout );
358
                                                                                                vTaskList( ( signed char * ) cBuffer );
359
                                                                                                printf( cBuffer );
360
                                                                                                fflush( stdout );
361
 
362
                                                                                                /* Finally print out a message
363
                                                                                                to the LCD - in this case the
364
                                                                                                pointer to the string to print
365
                                                                                                is sent directly in the
366
                                                                                                ulMessageValue member of the
367
                                                                                                message.  This just demonstrates
368
                                                                                                a different communication
369
                                                                                                technique. */
370
                                                                                                sprintf( cBuffer, "%s", ( char * ) xReceivedMessage.ulMessageValue );
371
                                                                                                break;
372
 
373
                        case mainMESSAGE_STATUS                 :       /* The tick interrupt hook
374
                                                                                                function has just informed this
375
                                                                                                task of the system status.
376
                                                                                                Generate a string in accordance
377
                                                                                                with the status value. */
378
                                                                                                prvGenerateStatusMessage( cBuffer, xReceivedMessage.ulMessageValue );
379
                                                                                                break;
380
 
381
                        default                                                 :       sprintf( cBuffer, "Unknown message" );
382
                                                                                                break;
383
                }
384
 
385
                /* Output the message that was placed into the cBuffer array within the
386
                switch statement above, then move onto the next line ready for the next
387
                message to arrive on the queue. */
388
                halLcdPrintLine( cBuffer, ucLine,  OVERWRITE_TEXT );
389
                ucLine++;
390
        }
391
}
392
/*-----------------------------------------------------------*/
393
 
394
static void prvGenerateStatusMessage( char *pcBuffer, long lStatusValue )
395
{
396
        /* Just a utility function to convert a status value into a meaningful
397
        string for output onto the LCD. */
398
        switch( lStatusValue )
399
        {
400
                case pdPASS                                             :       sprintf( pcBuffer, "Status = PASS" );
401
                                                                                        break;
402
                case mainERROR_DYNAMIC_TASKS    :       sprintf( pcBuffer, "Err: Dynamic tsks" );
403
                                                                                        break;
404
                case mainERROR_COM_TEST                 :       sprintf( pcBuffer, "Err: COM test" );
405
                                                                                        break;
406
                case mainERROR_GEN_QUEUE_TEST   :       sprintf( pcBuffer, "Error: Gen Q test" );
407
                                                                                        break;
408
                case mainERROR_REG_TEST                 :       sprintf( pcBuffer, "Error: Reg test" );
409
                                                                                        break;
410
                default                                                 :       sprintf( pcBuffer, "Unknown status" );
411
                                                                                        break;
412
        }
413
}
414
/*-----------------------------------------------------------*/
415
 
416
static void prvButtonPollTask( void *pvParameters )
417
{
418
unsigned char ucLastState = pdFALSE, ucState;
419
xQueueMessage xMessage;
420
 
421
        /* This tasks performs the button polling functionality as described at the
422
        top of this file. */
423
        for( ;; )
424
        {
425
                /* Check the button state. */
426
                ucState = ( halButtonsPressed() & BUTTON_UP );
427
 
428
                if( ucState != 0 )
429
                {
430
                        /* The button was pressed. */
431
                        ucState = pdTRUE;
432
                }
433
 
434
                if( ucState != ucLastState )
435
                {
436
                        /* The state has changed, send a message to the LCD task. */
437
                        xMessage.cMessageID = mainMESSAGE_BUTTON_UP;
438
                        xMessage.ulMessageValue = ( unsigned long ) ucState;
439
                        ucLastState = ucState;
440
                        xQueueSend( xLCDQueue, &xMessage, portMAX_DELAY );
441
                }
442
 
443
                /* Block for 10 milliseconds so this task does not utilise all the CPU
444
                time and debouncing of the button is not necessary. */
445
                vTaskDelay( 10 / portTICK_RATE_MS );
446
        }
447
}
448
/*-----------------------------------------------------------*/
449
 
450
static void prvSetupHardware( void )
451
{
452
/* Convert a Hz value to a KHz value, as required by the Init_FLL_Settle()
453
function. */
454
unsigned long ulCPU_Clock_KHz = ( configCPU_CLOCK_HZ / 1000UL );
455
 
456
        taskDISABLE_INTERRUPTS();
457
 
458
        /* Disable the watchdog. */
459
        WDTCTL = WDTPW + WDTHOLD;
460
 
461
        halBoardInit();
462
 
463
        LFXT_Start( XT1DRIVE_0 );
464
        Init_FLL_Settle( ( unsigned short ) ulCPU_Clock_KHz, 488 );
465
 
466
        halButtonsInit( BUTTON_ALL );
467
        halButtonsInterruptEnable( BUTTON_SELECT );
468
 
469
        /* Initialise the LCD, but note that the backlight is not used as the
470
        library function uses timer A0 to modulate the backlight, and this file
471
        defines vApplicationSetupTimerInterrupt() to also use timer A0 to generate
472
        the tick interrupt.  If the backlight is required, then change either the
473
        halLCD library or vApplicationSetupTimerInterrupt() to use a different
474
        timer.  Timer A1 is used for the run time stats time base6. */
475
        halLcdInit();
476
        halLcdSetContrast( 100 );
477
        halLcdClearScreen();
478
 
479
        halLcdPrintLine( " www.FreeRTOS.org", 0,  OVERWRITE_TEXT );
480
}
481
/*-----------------------------------------------------------*/
482
 
483
void vApplicationTickHook( void )
484
{
485
static unsigned short usLastRegTest1Counter = 0, usLastRegTest2Counter = 0;
486
static unsigned long ulCounter = 0;
487
static const unsigned long ulCheckFrequency = 5000UL / portTICK_RATE_MS;
488
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
489
 
490
/* Define the status message that is sent to the LCD task.  By default the
491
status is PASS. */
492
static xQueueMessage xStatusMessage = { mainMESSAGE_STATUS, pdPASS };
493
 
494
        /* This is called from within the tick interrupt and performs the 'check'
495
        functionality as described in the comments at the top of this file.
496
 
497
        Is it time to perform the 'check' functionality again? */
498
        ulCounter++;
499
        if( ulCounter >= ulCheckFrequency )
500
        {
501
                /* See if the standard demo tasks are executing as expected, changing
502
                the message that is sent to the LCD task from PASS to an error code if
503
                any tasks set reports an error. */
504
                if( xAreComTestTasksStillRunning() != pdPASS )
505
                {
506
                        xStatusMessage.ulMessageValue = mainERROR_COM_TEST;
507
                }
508
 
509
                if( xAreDynamicPriorityTasksStillRunning() != pdPASS )
510
                {
511
                        xStatusMessage.ulMessageValue = mainERROR_DYNAMIC_TASKS;
512
                }
513
 
514
                if( xAreGenericQueueTasksStillRunning() != pdPASS )
515
                {
516
                        xStatusMessage.ulMessageValue = mainERROR_GEN_QUEUE_TEST;
517
                }
518
 
519
                /* Check the reg test tasks are still cycling.  They will stop
520
                incrementing their loop counters if they encounter an error. */
521
                if( usRegTest1Counter == usLastRegTest1Counter )
522
                {
523
                        xStatusMessage.ulMessageValue = mainERROR_REG_TEST;
524
                }
525
 
526
                if( usRegTest2Counter == usLastRegTest2Counter )
527
                {
528
                        xStatusMessage.ulMessageValue = mainERROR_REG_TEST;
529
                }
530
 
531
                usLastRegTest1Counter = usRegTest1Counter;
532
                usLastRegTest2Counter = usRegTest2Counter;
533
 
534
                /* As this is the tick hook the lHigherPriorityTaskWoken parameter is not
535
                needed (a context switch is going to be performed anyway), but it must
536
                still be provided. */
537
                xQueueSendFromISR( xLCDQueue, &xStatusMessage, &xHigherPriorityTaskWoken );
538
                ulCounter = 0;
539
        }
540
 
541
        /* Just periodically toggle an LED to show that the tick interrupt is
542
        running.  Note that this access LED_PORT_OUT in a non-atomic way, so tasks
543
        that access the same port must do so from a critical section. */
544
        if( ( ulCounter & 0xff ) == 0 )
545
        {
546
                if( ( LED_PORT_OUT & LED_1 ) == 0 )
547
                {
548
                        LED_PORT_OUT |= LED_1;
549
                }
550
                else
551
                {
552
                        LED_PORT_OUT &= ~LED_1;
553
                }
554
        }
555
}
556
/*-----------------------------------------------------------*/
557
 
558
#pragma vector=PORT2_VECTOR
559
interrupt void prvSelectButtonInterrupt( void )
560
{
561
/* Define the message sent to the LCD task from this interrupt. */
562
static const xQueueMessage xMessage = { mainMESSAGE_BUTTON_SEL, ( unsigned long ) "Select Interrupt" };
563
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
564
 
565
        /* This is the interrupt handler for the joystick select button input.
566
        The button has been pushed, write a message to the LCD via the LCD task. */
567
        xQueueSendFromISR( xLCDQueue, &xMessage, &xHigherPriorityTaskWoken );
568
 
569
        P2IFG = 0;
570
 
571
        /* If writing to xLCDQueue caused a task to unblock, and the unblocked task
572
        has a priority equal to or above the task that this interrupt interrupted,
573
        then lHigherPriorityTaskWoken will have been set to pdTRUE internally within
574
        xQueuesendFromISR(), and portEND_SWITCHING_ISR() will ensure that this
575
        interrupt returns directly to the higher priority unblocked task. */
576
        portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
577
}
578
/*-----------------------------------------------------------*/
579
 
580
/* The MSP430X port uses this callback function to configure its tick interrupt.
581
This allows the application to choose the tick interrupt source.
582
configTICK_VECTOR must also be set in FreeRTOSConfig.h to the correct
583
interrupt vector for the chosen tick interrupt source.  This implementation of
584
vApplicationSetupTimerInterrupt() generates the tick from timer A0, so in this
585
case configTICK_VECTOR is set to TIMER0_A0_VECTOR. */
586
void vApplicationSetupTimerInterrupt( void )
587
{
588
const unsigned short usACLK_Frequency_Hz = 32768;
589
 
590
        /* Ensure the timer is stopped. */
591
        TA0CTL = 0;
592
 
593
        /* Run the timer from the ACLK. */
594
        TA0CTL = TASSEL_1;
595
 
596
        /* Clear everything to start with. */
597
        TA0CTL |= TACLR;
598
 
599
        /* Set the compare match value according to the tick rate we want. */
600
        TA0CCR0 = usACLK_Frequency_Hz / configTICK_RATE_HZ;
601
 
602
        /* Enable the interrupts. */
603
        TA0CCTL0 = CCIE;
604
 
605
        /* Start up clean. */
606
        TA0CTL |= TACLR;
607
 
608
        /* Up mode. */
609
        TA0CTL |= MC_1;
610
}
611
/*-----------------------------------------------------------*/
612
 
613
void vApplicationIdleHook( void )
614
{
615
        /* Called on each iteration of the idle task.  In this case the idle task
616
        just enters a low(ish) power mode. */
617
        __bis_SR_register( LPM1_bits + GIE );
618
}
619
/*-----------------------------------------------------------*/
620
 
621
void vApplicationMallocFailedHook( void )
622
{
623
        /* Called if a call to pvPortMalloc() fails because there is insufficient
624
        free memory available in the FreeRTOS heap.  pvPortMalloc() is called
625
        internally by FreeRTOS API functions that create tasks, queues or
626
        semaphores. */
627
        taskDISABLE_INTERRUPTS();
628
        for( ;; );
629
}
630
/*-----------------------------------------------------------*/
631
 
632
void vApplicationStackOverflowHook( xTaskHandle *pxTask, signed char *pcTaskName )
633
{
634
        ( void ) pxTask;
635
        ( void ) pcTaskName;
636
 
637
        /* Run time stack overflow checking is performed if
638
        configconfigCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2.  This hook
639
        function is called if a stack overflow is detected. */
640
        taskDISABLE_INTERRUPTS();
641
        for( ;; );
642
}
643
/*-----------------------------------------------------------*/
644
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.