X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=FreeRTOS%2FDemo%2FPIC32MX_MPLAB%2Fmain_full.c;h=0ee66fb8378f3bb1c2444a5a4eb2aa824d3d1a72;hb=bb2faca82c580d60469d268594bdc3cb26a632b3;hp=53cfd603b5a660eedd12986f04b478e94ada8ba3;hpb=a97a430d525b824853f6528cb60d160468690963;p=freertos diff --git a/FreeRTOS/Demo/PIC32MX_MPLAB/main_full.c b/FreeRTOS/Demo/PIC32MX_MPLAB/main_full.c index 53cfd603b..0ee66fb83 100644 --- a/FreeRTOS/Demo/PIC32MX_MPLAB/main_full.c +++ b/FreeRTOS/Demo/PIC32MX_MPLAB/main_full.c @@ -1,48 +1,38 @@ /* - FreeRTOS V7.4.2 - Copyright (C) 2013 Real Time Engineers Ltd. + FreeRTOS V8.0.1 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved - FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT - http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. *************************************************************************** * * - * FreeRTOS tutorial books are available in pdf and paperback. * - * Complete, revised, and edited pdf reference manuals are also * - * available. * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * * * - * Purchasing FreeRTOS documentation will not only help you, by * - * ensuring you get running as quickly as possible and with an * - * in-depth knowledge of how to use FreeRTOS, it will also help * - * the FreeRTOS project to continue with its mission of providing * - * professional grade, cross platform, de facto standard solutions * - * for microcontrollers - completely free of charge! * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * * * - * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * - * * - * Thank you for using FreeRTOS, and thank you for your support! * + * Thank you! * * * *************************************************************************** - This file is part of the FreeRTOS distribution. FreeRTOS is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License (version 2) as published by the - Free Software Foundation AND MODIFIED BY the FreeRTOS exception. + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. - >>>>>>NOTE<<<<<< The modification to the GPL is included to allow you to - distribute a combined work that includes FreeRTOS without being obliged to - provide the source code for proprietary components outside of the FreeRTOS - kernel. + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< FreeRTOS 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 General Public License for more - details. You should have received a copy of the GNU General Public License - and the FreeRTOS license exception along with FreeRTOS; if not it can be - viewed here: http://www.freertos.org/a00114.html and also obtained by - writing to Real Time Engineers Ltd., contact details for whom are available - on the FreeRTOS WEB site. + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html 1 tab == 4 spaces! @@ -55,21 +45,22 @@ * * *************************************************************************** - - http://www.FreeRTOS.org - Documentation, books, training, latest versions, + http://www.FreeRTOS.org - Documentation, books, training, latest versions, license and Real Time Engineers Ltd. contact details. http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, - including FreeRTOS+Trace - an indispensable productivity tool, and our new - fully thread aware and reentrant UDP/IP stack. - - http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High - Integrity Systems, who sell the code with commercial support, - indemnification and middleware, under the OpenRTOS brand. - - http://www.SafeRTOS.com - High Integrity Systems also provide a safety - engineered and independently SIL3 certified version for use in safety and + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and mission critical applications that require provable dependability. + + 1 tab == 4 spaces! */ /****************************************************************************** @@ -84,9 +75,9 @@ * required to configure the hardware, are defined in main.c. ****************************************************************************** * - * main_full() creates all the demo application tasks and software timers, then - * starts the scheduler. The WEB documentation provides more details of the - * standard demo application tasks. In addition to the standard demo tasks, the + * main_full() creates all the demo application tasks and software timers, then + * starts the scheduler. The WEB documentation provides more details of the + * standard demo application tasks. In addition to the standard demo tasks, the * following tasks and tests are defined and/or created within this file: * * "LCD" task - the LCD task is a 'gatekeeper' task. It is the only task that @@ -102,34 +93,34 @@ * the check software timer discovers that a task has either stalled, or * reported an error, then it changes its own execution period from the initial * three seconds, to just 200ms. The check software timer callback function - * also writes a status message to the LCD (via the LCD task). If all the demo - * tasks are executing with their expected behaviour then the check task writes + * also writes a status message to the LCD (via the LCD task). If all the demo + * tasks are executing with their expected behaviour then the check task writes * a count of the number of times the high frequency interrupt has incremented * ulHighFrequencyTimerInterrupts - which is one in every 20,000 interrupts. * * "Register test" tasks - These tasks are used in part to test the kernel port. - * They set each processor register to a known value, then check that the + * They set each processor register to a known value, then check that the * register still contains that value. Each of the tasks sets the registers - * to different values, and will get swapping in and out between setting and + * to different values, and will get swapping in and out between setting and * then subsequently checking the register values. Discovery of an incorrect * value would be indicative of an error in the task switching mechanism. * - * By way of demonstration, the demo application defines - * configMAX_SYSCALL_INTERRUPT_PRIORITY to be 3, configKERNEL_INTERRUPT_PRIORITY + * By way of demonstration, the demo application defines + * configMAX_SYSCALL_INTERRUPT_PRIORITY to be 3, configKERNEL_INTERRUPT_PRIORITY * to be 1, and all other interrupts as follows: * - * + The UART is allocated a priority of 2. This means it can interrupt the + * + The UART is allocated a priority of 2. This means it can interrupt the * RTOS tick, and can also safely use queues. - * + Two timers are configured to generate interrupts just to test the nesting - * and queue access mechanisms. These timers are allocated priorities 2 and 3 - * respectively. Even though they both access the same two queues, the - * priority 3 interrupt can safely interrupt the priority 2 interrupt. Both + * + Two timers are configured to generate interrupts just to test the nesting + * and queue access mechanisms. These timers are allocated priorities 2 and 3 + * respectively. Even though they both access the same two queues, the + * priority 3 interrupt can safely interrupt the priority 2 interrupt. Both * can interrupt the RTOS tick. - * + Finally a high frequency timer interrupt is configured to use priority 4 - - * therefore kernel activity will never prevent the high frequency timer from - * executing immediately that the interrupt is raised (within the limitations - * of the hardware itself). It would not be safe to access a queue from this - * interrupt as it is above configMAX_SYSCALL_INTERRUPT_PRIORITY. + * + Finally a high frequency timer interrupt is configured to use priority 4 - + * therefore kernel activity will never prevent the high frequency timer from + * executing immediately that the interrupt is raised (within the limitations + * of the hardware itself). It would not be safe to access a queue from this + * interrupt as it is above configMAX_SYSCALL_INTERRUPT_PRIORITY. * * See the online documentation for this demo for more information on interrupt * usage. @@ -160,13 +151,13 @@ /* The period after which the check timer will expire, in ms, provided no errors have been reported by any of the standard demo tasks. ms are converted to the -equivalent in ticks using the portTICK_RATE_MS constant. */ -#define mainCHECK_TIMER_PERIOD_MS ( 3000UL / portTICK_RATE_MS ) +equivalent in ticks using the portTICK_PERIOD_MS constant. */ +#define mainCHECK_TIMER_PERIOD_MS ( 3000UL / portTICK_PERIOD_MS ) /* The period at which the check timer will expire, in ms, if an error has been reported in one of the standard demo tasks. ms are converted to the equivalent -in ticks using the portTICK_RATE_MS constant. */ -#define mainERROR_CHECK_TIMER_PERIOD_MS ( 200UL / portTICK_RATE_MS ) +in ticks using the portTICK_PERIOD_MS constant. */ +#define mainERROR_CHECK_TIMER_PERIOD_MS ( 200UL / portTICK_PERIOD_MS ) /* The priorities of the various demo application tasks. */ #define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 ) @@ -175,9 +166,6 @@ in ticks using the portTICK_RATE_MS constant. */ #define mainINTEGER_TASK_PRIORITY ( tskIDLE_PRIORITY ) #define mainGEN_QUEUE_TASK_PRIORITY ( tskIDLE_PRIORITY ) -/* The LED controlled by the 'check' software timer. */ -#define mainCHECK_LED ( 7 ) - /* The LED used by the comtest tasks. mainCOM_TEST_LED + 1 is also used. See the comtest.c file for more information. */ #define mainCOM_TEST_LED ( 4 ) @@ -188,14 +176,14 @@ See the comtest.c file for more information. */ /* Misc. */ #define mainDONT_BLOCK ( 0 ) -/* Dimension the buffer used to hold the value of the high frequency timer +/* Dimension the buffer used to hold the value of the high frequency timer count when it is converted to a string. */ #define mainMAX_STRING_LENGTH ( 20 ) /* The frequency at which the "fast interrupt test" interrupt will occur. */ #define mainTEST_INTERRUPT_FREQUENCY ( 20000 ) -/* The number of timer clocks expected to occur between each "fast interrupt +/* The number of timer clocks expected to occur between each "fast interrupt test" interrupt. */ #define mainEXPECTED_CLOCKS_BETWEEN_INTERRUPTS ( ( configCPU_CLOCK_HZ >> 1 ) / mainTEST_INTERRUPT_FREQUENCY ) @@ -203,15 +191,23 @@ test" interrupt. */ #define mainNS_PER_CLOCK ( ( unsigned long ) ( ( 1.0 / ( double ) ( configCPU_CLOCK_HZ >> 1 ) ) * 1000000000.0 ) ) /* The number of LEDs that should be controlled by the flash software timer -standard demo. */ -#define mainNUM_FLASH_TIMER_LEDS ( 3 ) +standard demo and the LED to be toggle by the check task. The starter kit only +has three LEDs so when the demo is configured to run on the starter kit there +is one less flash timer so the check task can use the third LED. */ +#ifdef PIC32_STARTER_KIT + #define mainNUM_FLASH_TIMER_LEDS ( 2 ) + #define mainCHECK_LED ( 2 ) +#else + #define mainNUM_FLASH_TIMER_LEDS ( 3 ) + #define mainCHECK_LED ( 7 ) +#endif /*-----------------------------------------------------------*/ /* * The check timer callback function, as described at the top of this file. */ -static void prvCheckTimerCallback( xTimerHandle xTimer ); +static void prvCheckTimerCallback( TimerHandle_t xTimer ); /* * It is important to ensure the high frequency timer test does not start before @@ -220,14 +216,14 @@ static void prvCheckTimerCallback( xTimerHandle xTimer ); * executing. A one-shot timer is used, so the callback function will only * execute once (unless it is manually reset/restarted). */ -static void prvSetupHighFrequencyTimerTest( xTimerHandle xTimer ); +static void prvSetupHighFrequencyTimerTest( TimerHandle_t xTimer ); /* - * Tasks that test the context switch mechanism by filling the processor + * Tasks that test the context switch mechanism by filling the processor * registers with known values, then checking that the values contained * within the registers is as expected. The tasks are likely to get swapped * in and out between setting the register values and checking the register - * values. + * values. */ static void prvRegTestTask1( void *pvParameters ); static void prvRegTestTask2( void *pvParameters ); @@ -235,13 +231,9 @@ static void prvRegTestTask2( void *pvParameters ); /*-----------------------------------------------------------*/ /* The queue used to send messages to the LCD task. */ -static xQueueHandle xLCDQueue; - -/* Flag used by prvRegTestTask1() and prvRegTestTask2() to indicate their status -(pass/fail). */ -volatile unsigned long ulStatus1 = pdPASS; +static QueueHandle_t xLCDQueue; -/* Variables incremented by prvRegTestTask1() and prvRegTestTask2() respectively on +/* Variables incremented by prvRegTestTask1() and prvRegTestTask2() respectively on each iteration of their function. This is used to detect either task stopping their execution.. */ volatile unsigned long ulRegTest1Cycles = 0, ulRegTest2Cycles = 0; @@ -253,9 +245,9 @@ volatile unsigned long ulRegTest1Cycles = 0, ulRegTest2Cycles = 0; */ int main_full( void ) { -xTimerHandle xTimer = NULL; +TimerHandle_t xTimer = NULL; - /* Create the LCD task - this returns the queue to use when writing + /* Create the LCD task - this returns the queue to use when writing messages to the LCD. */ xLCDQueue = xStartLCDTask(); @@ -268,34 +260,34 @@ xTimerHandle xTimer = NULL; vStartInterruptQueueTasks(); /* Create the tasks defined within this file. */ - xTaskCreate( prvRegTestTask1, ( const signed char * const ) "Reg1", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL ); - xTaskCreate( prvRegTestTask2, ( const signed char * const ) "Reg2", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL ); + xTaskCreate( prvRegTestTask1, "Reg1", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL ); + xTaskCreate( prvRegTestTask2, "Reg2", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL ); - /* The PIC32MX795 uses an 8 deep fifo where TX interrupts are asserted - whilst the TX buffer is empty. This causes an issue with the test driver so + /* The PIC32MX795 uses an 8 deep fifo where TX interrupts are asserted + whilst the TX buffer is empty. This causes an issue with the test driver so it is not used in this demo */ #if !defined(__32MX795F512L__) vAltStartComTestTasks( mainCOM_TEST_PRIORITY, mainCOM_TEST_BAUD_RATE, mainCOM_TEST_LED ); - #endif - - /* Create the software timer that performs the 'check' functionality, as + #endif + + /* Create the software timer that performs the 'check' functionality, as described at the top of this file. */ - xTimer = xTimerCreate( ( const signed char * ) "CheckTimer",/* A text name, purely to help debugging. */ + xTimer = xTimerCreate( "CheckTimer",/* A text name, purely to help debugging. */ ( mainCHECK_TIMER_PERIOD_MS ), /* The timer period, in this case 3000ms (3s). */ pdTRUE, /* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */ ( void * ) 0, /* The ID is not used, so can be set to anything. */ prvCheckTimerCallback /* The callback function that inspects the status of all the other tasks. */ - ); - + ); + if( xTimer != NULL ) { xTimerStart( xTimer, mainDONT_BLOCK ); } - + /* A software timer is also used to start the high frequency timer test. This is to ensure the test does not start before the kernel. This time a one shot software timer is used. */ - xTimer = xTimerCreate( ( const signed char * ) "HighHzTimerSetup", 1, pdFALSE, ( void * ) 0, prvSetupHighFrequencyTimerTest ); + xTimer = xTimerCreate( "HighHzTimerSetup", 1, pdFALSE, ( void * ) 0, prvSetupHighFrequencyTimerTest ); if( xTimer != NULL ) { xTimerStart( xTimer, mainDONT_BLOCK ); @@ -317,15 +309,15 @@ static void prvRegTestTask1( void *pvParameters ) { extern void vRegTest1( volatile unsigned long * ); - for( ;; ) - { - /* Perform the register test function. */ - vRegTest1( &ulStatus1 ); + /* Avoid compiler warnings. */ + ( void ) pvParameters; - /* Increment the counter so the check task knows we are still - running. */ - ulRegTest1Cycles++; - } + /* Pass the address of the RegTest1 loop counter into the test function, + which is necessarily implemented in assembler. */ + vRegTest1( &ulRegTest1Cycles ); + + /* vRegTest1 should never exit! */ + vTaskDelete( NULL ); } /*-----------------------------------------------------------*/ @@ -333,19 +325,19 @@ static void prvRegTestTask2( void *pvParameters ) { extern void vRegTest2( volatile unsigned long * ); - for( ;; ) - { - /* Perform the register test function. */ - vRegTest2( &ulStatus1 ); + /* Avoid compiler warnings. */ + ( void ) pvParameters; - /* Increment the counter so the check task knows we are still - running. */ - ulRegTest2Cycles++; - } + /* Pass the address of the RegTest2 loop counter into the test function, + which is necessarily implemented in assembler. */ + vRegTest2( &ulRegTest2Cycles ); + + /* vRegTest1 should never exit! */ + vTaskDelete( NULL ); } /*-----------------------------------------------------------*/ -static void prvCheckTimerCallback( xTimerHandle xTimer ) +static void prvCheckTimerCallback( TimerHandle_t xTimer ) { static long lChangedTimerPeriodAlready = pdFALSE; static unsigned long ulLastRegTest1Value = 0, ulLastRegTest2Value = 0; @@ -355,13 +347,7 @@ static char cStringBuffer[ mainMAX_STRING_LENGTH ]; /* The count of the high frequency timer interrupts. */ extern unsigned long ulHighFrequencyTimerInterrupts; -static xLCDMessage xMessage = { ( 200 / portTICK_RATE_MS ), cStringBuffer }; - - /* Has either register check 1 or 2 task discovered an error? */ - if( ulStatus1 != pdPASS ) - { - xMessage.pcMessage = "Error: Reg test1"; - } +static xLCDMessage xMessage = { ( 200 / portTICK_PERIOD_MS ), cStringBuffer }; /* Check that the register test 1 task is still running. */ if( ulLastRegTest1Value == ulRegTest1Cycles ) @@ -370,16 +356,16 @@ static xLCDMessage xMessage = { ( 200 / portTICK_RATE_MS ), cStringBuffer }; } ulLastRegTest1Value = ulRegTest1Cycles; - + /* Check that the register test 2 task is still running. */ if( ulLastRegTest2Value == ulRegTest2Cycles ) { xMessage.pcMessage = "Error: Reg test3"; } ulLastRegTest2Value = ulRegTest2Cycles; - - /* Have any of the standard demo tasks detected an error in their + + /* Have any of the standard demo tasks detected an error in their operation? */ if( xAreGenericQueueTasksStillRunning() != pdTRUE ) { @@ -389,10 +375,6 @@ static xLCDMessage xMessage = { ( 200 / portTICK_RATE_MS ), cStringBuffer }; { xMessage.pcMessage = "Error: Q Peek"; } - else if( xAreComTestTasksStillRunning() != pdTRUE ) - { - xMessage.pcMessage = "Error: COM test"; - } else if( xAreBlockTimeTestTasksStillRunning() != pdTRUE ) { xMessage.pcMessage = "Error: Blck time"; @@ -405,6 +387,12 @@ static xLCDMessage xMessage = { ( 200 / portTICK_RATE_MS ), cStringBuffer }; { xMessage.pcMessage = "Error: Int queue"; } + #if !defined(__32MX795F512L__) + else if( xAreComTestTasksStillRunning() != pdTRUE ) + { + xMessage.pcMessage = "Error: COM test"; + } + #endif if( xMessage.pcMessage != cStringBuffer ) { @@ -415,33 +403,33 @@ static xLCDMessage xMessage = { ( 200 / portTICK_RATE_MS ), cStringBuffer }; if( lChangedTimerPeriodAlready == pdFALSE ) { lChangedTimerPeriodAlready = pdTRUE; - + /* This call to xTimerChangePeriod() uses a zero block time. Functions called from inside of a timer callback function must *never* attempt to block as to do so could impact other software timers. */ xTimerChangePeriod( xTimer, ( mainERROR_CHECK_TIMER_PERIOD_MS ), mainDONT_BLOCK ); - } + } } else { - /* Write the ulHighFrequencyTimerInterrupts value to the string + /* Write the ulHighFrequencyTimerInterrupts value to the string buffer. It will only be displayed if no errors have been detected. */ sprintf( cStringBuffer, "Pass %u", ( unsigned int ) ulHighFrequencyTimerInterrupts ); } - /* Send the status message to the LCD task for display on the LCD. This is + /* Send the status message to the LCD task for display on the LCD. This is a timer callback function, so the queue send function *must not* block. */ xQueueSend( xLCDQueue, &xMessage, mainDONT_BLOCK ); - vParTestToggleLED( mainCHECK_LED ); + vParTestToggleLED( mainCHECK_LED ); } /*-----------------------------------------------------------*/ -static void prvSetupHighFrequencyTimerTest( xTimerHandle xTimer ) +static void prvSetupHighFrequencyTimerTest( TimerHandle_t xTimer ) { /* Setup the high frequency, high priority, timer test. It is setup in this software timer callback to ensure it does not start before the kernel does. This is a one shot timer - so the setup routine will only be executed once. */ - vSetupTimerTest( mainTEST_INTERRUPT_FREQUENCY ); + vSetupTimerTest( mainTEST_INTERRUPT_FREQUENCY ); }