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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [freertos-6.1.1/] [Demo/] [MSP430X_MSP430F5438_IAR/] [main.c] - Blame information for rev 831

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.  The ISR_CODE segment is used for convenience as ISR
245
functions are always placed in low memory. */
246
#pragma location="ISR_CODE"
247
void main( void )
248
{
249
        /* Configure the peripherals used by this demo application.  This includes
250
        configuring the joystick input select button to generate interrupts. */
251
        prvSetupHardware();
252
 
253
        /* Create the queue used by tasks and interrupts to send strings to the LCD
254
        task. */
255
        xLCDQueue = xQueueCreate( mainQUEUE_LENGTH, sizeof( xQueueMessage ) );
256
 
257
        /* If the queue could not be created then don't create any tasks that might
258
        attempt to use the queue. */
259
        if( xLCDQueue != NULL )
260
        {
261
                /* Add the created queue to the queue registry so it can be viewed in
262
                the IAR FreeRTOS state viewer plug-in. */
263
                vQueueAddToRegistry( xLCDQueue, "LCDQueue" );
264
 
265
                /* Create the standard demo tasks. */
266
                vAltStartComTestTasks( mainCOM_TEST_PRIORITY, mainCOM_TEST_BAUD_RATE, mainCOM_TEST_LED );
267
                vStartDynamicPriorityTasks();
268
                vStartGenericQueueTasks( mainGENERIC_QUEUE_TEST_PRIORITY );
269
 
270
                /* Create the LCD, button poll and register test tasks, as described at
271
                the top of this file. */
272
                xTaskCreate( prvLCDTask, ( signed char * ) "LCD", configMINIMAL_STACK_SIZE * 2, mainTASK_PARAMETER_CHECK_VALUE, mainLCD_TASK_PRIORITY, NULL );
273
                xTaskCreate( prvButtonPollTask, ( signed char * ) "BPoll", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
274
                xTaskCreate( vRegTest1Task, ( signed char * ) "Reg1", configMINIMAL_STACK_SIZE, NULL, 0, NULL );
275
                xTaskCreate( vRegTest2Task, ( signed char * ) "Reg2", configMINIMAL_STACK_SIZE, NULL, 0, NULL );
276
 
277
                /* Start the scheduler. */
278
                vTaskStartScheduler();
279
        }
280
 
281
        /* If all is well then this line will never be reached.  If it is reached
282
        then it is likely that there was insufficient (FreeRTOS) heap memory space
283
        to create the idle task.  This may have been trapped by the malloc() failed
284
        hook function, if one is configured. */
285
        for( ;; );
286
}
287
/*-----------------------------------------------------------*/
288
 
289
static void prvLCDTask( void *pvParameters )
290
{
291
xQueueMessage xReceivedMessage;
292
 
293
/* Buffer into which strings are formatted and placed ready for display on the
294
LCD.  Note this is a static variable to prevent it being allocated on the task
295
stack, which is too small to hold such a variable.  The stack size is configured
296
when the task is created. */
297
static char cBuffer[ 512 ];
298
unsigned char ucLine = 1;
299
 
300
 
301
        /* This function is the only function that uses printf().  If printf() is
302
        used from any other function then some sort of mutual exclusion on stdout
303
        will be necessary.
304
 
305
        This is also the only function that is permitted to access the LCD.
306
 
307
        First print out the number of bytes that remain in the FreeRTOS heap.  This
308
        can be viewed in the terminal IO window within the IAR Embedded Workbench. */
309
        printf( "%d bytes of heap space remain unallocated\n", ( int ) xPortGetFreeHeapSize() );
310
 
311
        /* Just as a test of the port, and for no functional reason, check the task
312
        parameter contains its expected value. */
313
        if( pvParameters != mainTASK_PARAMETER_CHECK_VALUE )
314
        {
315
                halLcdPrintLine( "Invalid parameter", ucLine,  OVERWRITE_TEXT );
316
                ucLine++;
317
        }
318
 
319
        for( ;; )
320
        {
321
                /* Wait for a message to be received.  Using portMAX_DELAY as the block
322
                time will result in an indefinite wait provided INCLUDE_vTaskSuspend is
323
                set to 1 in FreeRTOSConfig.h, therefore there is no need to check the
324
                function return value and the function will only return when a value
325
                has been received. */
326
                xQueueReceive( xLCDQueue, &xReceivedMessage, portMAX_DELAY );
327
 
328
                /* Clear the LCD if no room remains for any more text output. */
329
                if( ucLine > mainMAX_LCD_LINES )
330
                {
331
                        halLcdClearScreen();
332
                        ucLine = 0;
333
                }
334
 
335
                /* What is this message?  What does it contain? */
336
                switch( xReceivedMessage.cMessageID )
337
                {
338
                        case mainMESSAGE_BUTTON_UP              :       /* The button poll task has just
339
                                                                                                informed this task that the up
340
                                                                                                button on the joystick input has
341
                                                                                                been pressed or released. */
342
                                                                                                sprintf( cBuffer, "Button up = %d", ( int ) xReceivedMessage.ulMessageValue );
343
                                                                                                break;
344
 
345
                        case mainMESSAGE_BUTTON_SEL             :       /* The select button interrupt
346
                                                                                                just informed this task that the
347
                                                                                                select button was pressed.
348
                                                                                                Generate a table of task run time
349
                                                                                                statistics and output this to
350
                                                                                                the terminal IO window in the IAR
351
                                                                                                embedded workbench. */
352
                                                                                                printf( "\nTask\t     Abs Time\t     %%Time\n*****************************************" );
353
                                                                                                vTaskGetRunTimeStats( ( signed char * ) cBuffer );
354
                                                                                                printf( cBuffer );
355
 
356
                                                                                                /* Also print out a message to
357
                                                                                                the LCD - in this case the
358
                                                                                                pointer to the string to print
359
                                                                                                is sent directly in the
360
                                                                                                ulMessageValue member of the
361
                                                                                                message.  This just demonstrates
362
                                                                                                a different communication
363
                                                                                                technique. */
364
                                                                                                sprintf( cBuffer, "%s", ( char * ) xReceivedMessage.ulMessageValue );
365
                                                                                                break;
366
 
367
                        case mainMESSAGE_STATUS                 :       /* The tick interrupt hook
368
                                                                                                function has just informed this
369
                                                                                                task of the system status.
370
                                                                                                Generate a string in accordance
371
                                                                                                with the status value. */
372
                                                                                                prvGenerateStatusMessage( cBuffer, xReceivedMessage.ulMessageValue );
373
                                                                                                break;
374
 
375
                        default                                                 :       sprintf( cBuffer, "Unknown message" );
376
                                                                                                break;
377
                }
378
 
379
                /* Output the message that was placed into the cBuffer array within the
380
                switch statement above, then move onto the next line ready for the next
381
                message to arrive on the queue. */
382
                halLcdPrintLine( cBuffer, ucLine,  OVERWRITE_TEXT );
383
                ucLine++;
384
        }
385
}
386
/*-----------------------------------------------------------*/
387
 
388
static void prvGenerateStatusMessage( char *pcBuffer, long lStatusValue )
389
{
390
        /* Just a utility function to convert a status value into a meaningful
391
        string for output onto the LCD. */
392
        switch( lStatusValue )
393
        {
394
                case pdPASS                                             :       sprintf( pcBuffer, "Status = PASS" );
395
                                                                                        break;
396
                case mainERROR_DYNAMIC_TASKS    :       sprintf( pcBuffer, "Err: Dynamic tsks" );
397
                                                                                        break;
398
                case mainERROR_COM_TEST                 :       sprintf( pcBuffer, "Err: COM test" );
399
                                                                                        break;
400
                case mainERROR_GEN_QUEUE_TEST   :       sprintf( pcBuffer, "Error: Gen Q test" );
401
                                                                                        break;
402
                case mainERROR_REG_TEST                 :       sprintf( pcBuffer, "Error: Reg test" );
403
                                                                                        break;
404
                default                                                 :       sprintf( pcBuffer, "Unknown status" );
405
                                                                                        break;
406
        }
407
}
408
/*-----------------------------------------------------------*/
409
 
410
static void prvButtonPollTask( void *pvParameters )
411
{
412
unsigned char ucLastState = pdFALSE, ucState;
413
xQueueMessage xMessage;
414
 
415
        /* This tasks performs the button polling functionality as described at the
416
        top of this file. */
417
        for( ;; )
418
        {
419
                /* Check the button state. */
420
                ucState = ( halButtonsPressed() & BUTTON_UP );
421
 
422
                if( ucState != 0 )
423
                {
424
                        /* The button was pressed. */
425
                        ucState = pdTRUE;
426
                }
427
 
428
                if( ucState != ucLastState )
429
                {
430
                        /* The state has changed, send a message to the LCD task. */
431
                        xMessage.cMessageID = mainMESSAGE_BUTTON_UP;
432
                        xMessage.ulMessageValue = ( unsigned long ) ucState;
433
                        ucLastState = ucState;
434
                        xQueueSend( xLCDQueue, &xMessage, portMAX_DELAY );
435
                }
436
 
437
                /* Block for 10 milliseconds so this task does not utilise all the CPU
438
                time and debouncing of the button is not necessary. */
439
                vTaskDelay( 10 / portTICK_RATE_MS );
440
        }
441
}
442
/*-----------------------------------------------------------*/
443
 
444
static void prvSetupHardware( void )
445
{
446
/* Convert a Hz value to a KHz value, as required by the Init_FLL_Settle()
447
function. */
448
unsigned long ulCPU_Clock_KHz = ( configCPU_CLOCK_HZ / 1000UL );
449
 
450
        halBoardInit();
451
 
452
        LFXT_Start( XT1DRIVE_0 );
453
        Init_FLL_Settle( ( unsigned short ) ulCPU_Clock_KHz, 488 );
454
 
455
        halButtonsInit( BUTTON_ALL );
456
        halButtonsInterruptEnable( BUTTON_SELECT );
457
 
458
        /* Initialise the LCD, but note that the backlight is not used as the
459
        library function uses timer A0 to modulate the backlight, and this file
460
        defines vApplicationSetupTimerInterrupt() to also use timer A0 to generate
461
        the tick interrupt.  If the backlight is required, then change either the
462
        halLCD library or vApplicationSetupTimerInterrupt() to use a different
463
        timer.  Timer A1 is used for the run time stats time base6. */
464
        halLcdInit();
465
        halLcdSetContrast( 100 );
466
        halLcdClearScreen();
467
 
468
        halLcdPrintLine( " www.FreeRTOS.org", 0,  OVERWRITE_TEXT );
469
}
470
/*-----------------------------------------------------------*/
471
 
472
void vApplicationTickHook( void )
473
{
474
static unsigned short usLastRegTest1Counter = 0, usLastRegTest2Counter = 0;
475
static unsigned long ulCounter = 0;
476
static const unsigned long ulCheckFrequency = 5000UL / portTICK_RATE_MS;
477
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
478
 
479
/* Define the status message that is sent to the LCD task.  By default the
480
status is PASS. */
481
static xQueueMessage xStatusMessage = { mainMESSAGE_STATUS, pdPASS };
482
 
483
        /* This is called from within the tick interrupt and performs the 'check'
484
        functionality as described in the comments at the top of this file.
485
 
486
        Is it time to perform the 'check' functionality again? */
487
        ulCounter++;
488
        if( ulCounter >= ulCheckFrequency )
489
        {
490
                /* See if the standard demo tasks are executing as expected, changing
491
                the message that is sent to the LCD task from PASS to an error code if
492
                any tasks set reports an error. */
493
                if( xAreComTestTasksStillRunning() != pdPASS )
494
                {
495
                        xStatusMessage.ulMessageValue = mainERROR_COM_TEST;
496
                }
497
 
498
                if( xAreDynamicPriorityTasksStillRunning() != pdPASS )
499
                {
500
                        xStatusMessage.ulMessageValue = mainERROR_DYNAMIC_TASKS;
501
                }
502
 
503
                if( xAreGenericQueueTasksStillRunning() != pdPASS )
504
                {
505
                        xStatusMessage.ulMessageValue = mainERROR_GEN_QUEUE_TEST;
506
                }
507
 
508
                /* Check the reg test tasks are still cycling.  They will stop
509
                incrementing their loop counters if they encounter an error. */
510
                if( usRegTest1Counter == usLastRegTest1Counter )
511
                {
512
                        xStatusMessage.ulMessageValue = mainERROR_REG_TEST;
513
                }
514
 
515
                if( usRegTest2Counter == usLastRegTest2Counter )
516
                {
517
                        xStatusMessage.ulMessageValue = mainERROR_REG_TEST;
518
                }
519
 
520
                usLastRegTest1Counter = usRegTest1Counter;
521
                usLastRegTest2Counter = usRegTest2Counter;
522
 
523
                /* As this is the tick hook the lHigherPriorityTaskWoken parameter is not
524
                needed (a context switch is going to be performed anyway), but it must
525
                still be provided. */
526
                xQueueSendFromISR( xLCDQueue, &xStatusMessage, &xHigherPriorityTaskWoken );
527
                ulCounter = 0;
528
        }
529
 
530
        /* Just periodically toggle an LED to show that the tick interrupt is
531
        running.  Note that this access LED_PORT_OUT in a non-atomic way, so tasks
532
        that access the same port must do so from a critical section. */
533
        if( ( ulCounter & 0xff ) == 0 )
534
        {
535
                if( ( LED_PORT_OUT & LED_1 ) == 0 )
536
                {
537
                        LED_PORT_OUT |= LED_1;
538
                }
539
                else
540
                {
541
                        LED_PORT_OUT &= ~LED_1;
542
                }
543
        }
544
}
545
/*-----------------------------------------------------------*/
546
 
547
#pragma vector=PORT2_VECTOR
548
__interrupt static void prvSelectButtonInterrupt(void)
549
{
550
/* Define the message sent to the LCD task from this interrupt. */
551
static const xQueueMessage xMessage = { mainMESSAGE_BUTTON_SEL, ( unsigned long ) "Select Interrupt" };
552
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
553
 
554
        /* This is the interrupt handler for the joystick select button input.
555
        The button has been pushed, write a message to the LCD via the LCD task. */
556
        xQueueSendFromISR( xLCDQueue, &xMessage, &xHigherPriorityTaskWoken );
557
 
558
        P2IFG = 0;
559
 
560
        /* If writing to xLCDQueue caused a task to unblock, and the unblocked task
561
        has a priority equal to or above the task that this interrupt interrupted,
562
        then lHigherPriorityTaskWoken will have been set to pdTRUE internally within
563
        xQueuesendFromISR(), and portEND_SWITCHING_ISR() will ensure that this
564
        interrupt returns directly to the higher priority unblocked task. */
565
        portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
566
}
567
/*-----------------------------------------------------------*/
568
 
569
/* The MSP430X port uses this callback function to configure its tick interrupt.
570
This allows the application to choose the tick interrupt source.
571
configTICK_VECTOR must also be set in FreeRTOSConfig.h to the correct
572
interrupt vector for the chosen tick interrupt source.  This implementation of
573
vApplicationSetupTimerInterrupt() generates the tick from timer A0, so in this
574
case configTICK_VECTOR is set to TIMER0_A0_VECTOR. */
575
void vApplicationSetupTimerInterrupt( void )
576
{
577
const unsigned short usACLK_Frequency_Hz = 32768;
578
 
579
        /* Ensure the timer is stopped. */
580
        TA0CTL = 0;
581
 
582
        /* Run the timer from the ACLK. */
583
        TA0CTL = TASSEL_1;
584
 
585
        /* Clear everything to start with. */
586
        TA0CTL |= TACLR;
587
 
588
        /* Set the compare match value according to the tick rate we want. */
589
        TA0CCR0 = usACLK_Frequency_Hz / configTICK_RATE_HZ;
590
 
591
        /* Enable the interrupts. */
592
        TA0CCTL0 = CCIE;
593
 
594
        /* Start up clean. */
595
        TA0CTL |= TACLR;
596
 
597
        /* Up mode. */
598
        TA0CTL |= MC_1;
599
}
600
/*-----------------------------------------------------------*/
601
 
602
void vApplicationIdleHook( void )
603
{
604
        /* Called on each iteration of the idle task.  In this case the idle task
605
        just enters a low power mode. */
606
        __bis_SR_register( LPM3_bits + GIE );
607
}
608
/*-----------------------------------------------------------*/
609
 
610
void vApplicationMallocFailedHook( void )
611
{
612
        /* Called if a call to pvPortMalloc() fails because there is insufficient
613
        free memory available in the FreeRTOS heap.  pvPortMalloc() is called
614
        internally by FreeRTOS API functions that create tasks, queues or
615
        semaphores. */
616
        taskDISABLE_INTERRUPTS();
617
        for( ;; );
618
}
619
/*-----------------------------------------------------------*/
620
 
621
void vApplicationStackOverflowHook( xTaskHandle *pxTask, signed char *pcTaskName )
622
{
623
        ( void ) pxTask;
624
        ( void ) pcTaskName;
625
 
626
        /* Run time stack overflow checking is performed if
627
        configconfigCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2.  This hook
628
        function is called if a stack overflow is detected. */
629
        taskDISABLE_INTERRUPTS();
630
        for( ;; );
631
}
632
/*-----------------------------------------------------------*/
633
 

powered by: WebSVN 2.1.0

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