From 1310641c169a4db49c9a6806819d022997b6c124 Mon Sep 17 00:00:00 2001 From: richardbarry Date: Sat, 21 Jan 2012 15:23:40 +0000 Subject: [PATCH] Complete LPC11xx demo functionality. The batch file to copy the code over is not written yet. git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@1668 1d2547de-c912-0410-9cb9-b8ca96c0e9e2 --- .../Source/Common_Demo_Tasks/GenQTest.c | 572 ------------------ .../Source/Common_Demo_Tasks/dynamic.c | 427 ------------- .../Source/Common_Demo_Tasks/include/BlockQ.h | 62 -- .../Common_Demo_Tasks/include/GenQTest.h | 63 -- .../Common_Demo_Tasks/include/dynamic.h | 62 -- .../RTOSDemo/Source/FreeRTOSConfig.h | 6 +- .../RTOSDemo/Source/main-blinky.c | 225 +++++++ .../RTOSDemo/Source/main-full.c | 293 +++++++++ .../RTOSDemo/Source/main.c | 224 +++---- 9 files changed, 597 insertions(+), 1337 deletions(-) delete mode 100644 Demo/CORTEX_M0_LPC1114_LPCXpresso/RTOSDemo/Source/Common_Demo_Tasks/GenQTest.c delete mode 100644 Demo/CORTEX_M0_LPC1114_LPCXpresso/RTOSDemo/Source/Common_Demo_Tasks/dynamic.c delete mode 100644 Demo/CORTEX_M0_LPC1114_LPCXpresso/RTOSDemo/Source/Common_Demo_Tasks/include/BlockQ.h delete mode 100644 Demo/CORTEX_M0_LPC1114_LPCXpresso/RTOSDemo/Source/Common_Demo_Tasks/include/GenQTest.h delete mode 100644 Demo/CORTEX_M0_LPC1114_LPCXpresso/RTOSDemo/Source/Common_Demo_Tasks/include/dynamic.h create mode 100644 Demo/CORTEX_M0_LPC1114_LPCXpresso/RTOSDemo/Source/main-blinky.c create mode 100644 Demo/CORTEX_M0_LPC1114_LPCXpresso/RTOSDemo/Source/main-full.c diff --git a/Demo/CORTEX_M0_LPC1114_LPCXpresso/RTOSDemo/Source/Common_Demo_Tasks/GenQTest.c b/Demo/CORTEX_M0_LPC1114_LPCXpresso/RTOSDemo/Source/Common_Demo_Tasks/GenQTest.c deleted file mode 100644 index be6206721..000000000 --- a/Demo/CORTEX_M0_LPC1114_LPCXpresso/RTOSDemo/Source/Common_Demo_Tasks/GenQTest.c +++ /dev/null @@ -1,572 +0,0 @@ -/* - FreeRTOS V7.1.0 - Copyright (C) 2011 Real Time Engineers Ltd. - - - *************************************************************************** - * * - * FreeRTOS tutorial books are available in pdf and paperback. * - * Complete, revised, and edited pdf reference manuals are also * - * available. * - * * - * 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! * - * * - * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * - * * - * Thank you for using FreeRTOS, and thank you for your support! * - * * - *************************************************************************** - - - 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. - >>>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 Richard Barry, contact details for whom are available on the - FreeRTOS WEB site. - - 1 tab == 4 spaces! - - http://www.FreeRTOS.org - Documentation, latest information, license and - contact details. - - http://www.SafeRTOS.com - A version that is certified for use in safety - critical systems. - - http://www.OpenRTOS.com - Commercial support, development, porting, - licensing and training services. -*/ - - -/* - * Tests the extra queue functionality introduced in FreeRTOS.org V4.5.0 - - * including xQueueSendToFront(), xQueueSendToBack(), xQueuePeek() and - * mutex behaviour. - * - * See the comments above the prvSendFrontAndBackTest() and - * prvLowPriorityMutexTask() prototypes below for more information. - */ - - -#include - -/* Scheduler include files. */ -#include "FreeRTOS.h" -#include "task.h" -#include "queue.h" -#include "semphr.h" - -/* Demo program include files. */ -#include "GenQTest.h" - -#define genqQUEUE_LENGTH ( 5 ) -#define genqNO_BLOCK ( 0 ) - -#define genqMUTEX_LOW_PRIORITY ( tskIDLE_PRIORITY ) -#define genqMUTEX_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 ) -#define genqMUTEX_MEDIUM_PRIORITY ( tskIDLE_PRIORITY + 2 ) -#define genqMUTEX_HIGH_PRIORITY ( tskIDLE_PRIORITY + 3 ) - -/*-----------------------------------------------------------*/ - -/* - * Tests the behaviour of the xQueueSendToFront() and xQueueSendToBack() - * macros by using both to fill a queue, then reading from the queue to - * check the resultant queue order is as expected. Queue data is also - * peeked. - */ -static void prvSendFrontAndBackTest( void *pvParameters ); - -/* - * The following three tasks are used to demonstrate the mutex behaviour. - * Each task is given a different priority to demonstrate the priority - * inheritance mechanism. - * - * The low priority task obtains a mutex. After this a high priority task - * attempts to obtain the same mutex, causing its priority to be inherited - * by the low priority task. The task with the inherited high priority then - * resumes a medium priority task to ensure it is not blocked by the medium - * priority task while it holds the inherited high priority. Once the mutex - * is returned the task with the inherited priority returns to its original - * low priority, and is therefore immediately preempted by first the high - * priority task and then the medium prioroity task before it can continue. - */ -static void prvLowPriorityMutexTask( void *pvParameters ); -static void prvMediumPriorityMutexTask( void *pvParameters ); -static void prvHighPriorityMutexTask( void *pvParameters ); - -/*-----------------------------------------------------------*/ - -/* Flag that will be latched to pdTRUE should any unexpected behaviour be -detected in any of the tasks. */ -static portBASE_TYPE xErrorDetected = pdFALSE; - -/* Counters that are incremented on each cycle of a test. This is used to -detect a stalled task - a test that is no longer running. */ -static volatile unsigned portLONG ulLoopCounter = 0; -static volatile unsigned portLONG ulLoopCounter2 = 0; - -/* The variable that is guarded by the mutex in the mutex demo tasks. */ -static volatile unsigned portLONG ulGuardedVariable = 0; - -/* Handles used in the mutext test to suspend and resume the high and medium -priority mutex test tasks. */ -static xTaskHandle xHighPriorityMutexTask, xMediumPriorityMutexTask; - -/*-----------------------------------------------------------*/ - -void vStartGenericQueueTasks( unsigned portBASE_TYPE uxPriority ) -{ -xQueueHandle xQueue; -xSemaphoreHandle xMutex; - - /* Create the queue that we are going to use for the - prvSendFrontAndBackTest demo. */ - xQueue = xQueueCreate( genqQUEUE_LENGTH, sizeof( unsigned portLONG ) ); - - /* vQueueAddToRegistry() adds the queue to the queue registry, if one is - in use. The queue registry is provided as a means for kernel aware - debuggers to locate queues and has no purpose if a kernel aware debugger - is not being used. The call to vQueueAddToRegistry() will be removed - by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is - defined to be less than 1. */ - vQueueAddToRegistry( xQueue, ( signed portCHAR * ) "Gen_Queue_Test" ); - - /* Create the demo task and pass it the queue just created. We are - passing the queue handle by value so it does not matter that it is - declared on the stack here. */ - xTaskCreate( prvSendFrontAndBackTest, ( signed portCHAR * )"GenQ", configMINIMAL_STACK_SIZE, ( void * ) xQueue, uxPriority, NULL ); - - /* Create the mutex used by the prvMutexTest task. */ - xMutex = xSemaphoreCreateMutex(); - - /* vQueueAddToRegistry() adds the mutex to the registry, if one is - in use. The registry is provided as a means for kernel aware - debuggers to locate mutexes and has no purpose if a kernel aware debugger - is not being used. The call to vQueueAddToRegistry() will be removed - by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is - defined to be less than 1. */ - vQueueAddToRegistry( ( xQueueHandle ) xMutex, ( signed portCHAR * ) "Gen_Queue_Mutex" ); - - /* Create the mutex demo tasks and pass it the mutex just created. We are - passing the mutex handle by value so it does not matter that it is declared - on the stack here. */ - xTaskCreate( prvLowPriorityMutexTask, ( signed portCHAR * )"MuLow", configMINIMAL_STACK_SIZE, ( void * ) xMutex, genqMUTEX_LOW_PRIORITY, NULL ); - xTaskCreate( prvMediumPriorityMutexTask, ( signed portCHAR * )"MuMed", configMINIMAL_STACK_SIZE, NULL, genqMUTEX_MEDIUM_PRIORITY, &xMediumPriorityMutexTask ); - xTaskCreate( prvHighPriorityMutexTask, ( signed portCHAR * )"MuHigh", configMINIMAL_STACK_SIZE, ( void * ) xMutex, genqMUTEX_HIGH_PRIORITY, &xHighPriorityMutexTask ); -} -/*-----------------------------------------------------------*/ - -static void prvSendFrontAndBackTest( void *pvParameters ) -{ -unsigned portLONG ulData, ulData2; -xQueueHandle xQueue; - - #ifdef USE_STDIO - void vPrintDisplayMessage( const portCHAR * const * ppcMessageToSend ); - - const portCHAR * const pcTaskStartMsg = "Queue SendToFront/SendToBack/Peek test started.\r\n"; - - /* Queue a message for printing to say the task has started. */ - vPrintDisplayMessage( &pcTaskStartMsg ); - #endif - - xQueue = ( xQueueHandle ) pvParameters; - - for( ;; ) - { - /* The queue is empty, so sending an item to the back of the queue - should have the same efect as sending it to the front of the queue. - - First send to the front and check everything is as expected. */ - xQueueSendToFront( xQueue, ( void * ) &ulLoopCounter, genqNO_BLOCK ); - - if( uxQueueMessagesWaiting( xQueue ) != 1 ) - { - xErrorDetected = pdTRUE; - } - - if( xQueueReceive( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != pdPASS ) - { - xErrorDetected = pdTRUE; - } - - /* The data we sent to the queue should equal the data we just received - from the queue. */ - if( ulLoopCounter != ulData ) - { - xErrorDetected = pdTRUE; - } - - /* Then do the same, sending the data to the back, checking everything - is as expected. */ - if( uxQueueMessagesWaiting( xQueue ) != 0 ) - { - xErrorDetected = pdTRUE; - } - - xQueueSendToBack( xQueue, ( void * ) &ulLoopCounter, genqNO_BLOCK ); - - if( uxQueueMessagesWaiting( xQueue ) != 1 ) - { - xErrorDetected = pdTRUE; - } - - if( xQueueReceive( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != pdPASS ) - { - xErrorDetected = pdTRUE; - } - - if( uxQueueMessagesWaiting( xQueue ) != 0 ) - { - xErrorDetected = pdTRUE; - } - - /* The data we sent to the queue should equal the data we just received - from the queue. */ - if( ulLoopCounter != ulData ) - { - xErrorDetected = pdTRUE; - } - - #if configUSE_PREEMPTION == 0 - taskYIELD(); - #endif - - - - /* Place 2, 3, 4 into the queue, adding items to the back of the queue. */ - for( ulData = 2; ulData < 5; ulData++ ) - { - xQueueSendToBack( xQueue, ( void * ) &ulData, genqNO_BLOCK ); - } - - /* Now the order in the queue should be 2, 3, 4, with 2 being the first - thing to be read out. Now add 1 then 0 to the front of the queue. */ - if( uxQueueMessagesWaiting( xQueue ) != 3 ) - { - xErrorDetected = pdTRUE; - } - ulData = 1; - xQueueSendToFront( xQueue, ( void * ) &ulData, genqNO_BLOCK ); - ulData = 0; - xQueueSendToFront( xQueue, ( void * ) &ulData, genqNO_BLOCK ); - - /* Now the queue should be full, and when we read the data out we - should receive 0, 1, 2, 3, 4. */ - if( uxQueueMessagesWaiting( xQueue ) != 5 ) - { - xErrorDetected = pdTRUE; - } - - if( xQueueSendToFront( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != errQUEUE_FULL ) - { - xErrorDetected = pdTRUE; - } - - if( xQueueSendToBack( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != errQUEUE_FULL ) - { - xErrorDetected = pdTRUE; - } - - #if configUSE_PREEMPTION == 0 - taskYIELD(); - #endif - - /* Check the data we read out is in the expected order. */ - for( ulData = 0; ulData < genqQUEUE_LENGTH; ulData++ ) - { - /* Try peeking the data first. */ - if( xQueuePeek( xQueue, &ulData2, genqNO_BLOCK ) != pdPASS ) - { - xErrorDetected = pdTRUE; - } - - if( ulData != ulData2 ) - { - xErrorDetected = pdTRUE; - } - - - /* Now try receiving the data for real. The value should be the - same. Clobber the value first so we know we really received it. */ - ulData2 = ~ulData2; - if( xQueueReceive( xQueue, &ulData2, genqNO_BLOCK ) != pdPASS ) - { - xErrorDetected = pdTRUE; - } - - if( ulData != ulData2 ) - { - xErrorDetected = pdTRUE; - } - } - - /* The queue should now be empty again. */ - if( uxQueueMessagesWaiting( xQueue ) != 0 ) - { - xErrorDetected = pdTRUE; - } - - #if configUSE_PREEMPTION == 0 - taskYIELD(); - #endif - - - /* Our queue is empty once more, add 10, 11 to the back. */ - ulData = 10; - if( xQueueSend( xQueue, &ulData, genqNO_BLOCK ) != pdPASS ) - { - xErrorDetected = pdTRUE; - } - ulData = 11; - if( xQueueSend( xQueue, &ulData, genqNO_BLOCK ) != pdPASS ) - { - xErrorDetected = pdTRUE; - } - - if( uxQueueMessagesWaiting( xQueue ) != 2 ) - { - xErrorDetected = pdTRUE; - } - - /* Now we should have 10, 11 in the queue. Add 7, 8, 9 to the - front. */ - for( ulData = 9; ulData >= 7; ulData-- ) - { - if( xQueueSendToFront( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != pdPASS ) - { - xErrorDetected = pdTRUE; - } - } - - /* Now check that the queue is full, and that receiving data provides - the expected sequence of 7, 8, 9, 10, 11. */ - if( uxQueueMessagesWaiting( xQueue ) != 5 ) - { - xErrorDetected = pdTRUE; - } - - if( xQueueSendToFront( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != errQUEUE_FULL ) - { - xErrorDetected = pdTRUE; - } - - if( xQueueSendToBack( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != errQUEUE_FULL ) - { - xErrorDetected = pdTRUE; - } - - #if configUSE_PREEMPTION == 0 - taskYIELD(); - #endif - - /* Check the data we read out is in the expected order. */ - for( ulData = 7; ulData < ( 7 + genqQUEUE_LENGTH ); ulData++ ) - { - if( xQueueReceive( xQueue, &ulData2, genqNO_BLOCK ) != pdPASS ) - { - xErrorDetected = pdTRUE; - } - - if( ulData != ulData2 ) - { - xErrorDetected = pdTRUE; - } - } - - if( uxQueueMessagesWaiting( xQueue ) != 0 ) - { - xErrorDetected = pdTRUE; - } - - ulLoopCounter++; - } -} -/*-----------------------------------------------------------*/ - -static void prvLowPriorityMutexTask( void *pvParameters ) -{ -xSemaphoreHandle xMutex = ( xSemaphoreHandle ) pvParameters; - - #ifdef USE_STDIO - void vPrintDisplayMessage( const portCHAR * const * ppcMessageToSend ); - - const portCHAR * const pcTaskStartMsg = "Mutex with priority inheritance test started.\r\n"; - - /* Queue a message for printing to say the task has started. */ - vPrintDisplayMessage( &pcTaskStartMsg ); - #endif - - for( ;; ) - { - /* Take the mutex. It should be available now. */ - if( xSemaphoreTake( xMutex, genqNO_BLOCK ) != pdPASS ) - { - xErrorDetected = pdTRUE; - } - - /* Set our guarded variable to a known start value. */ - ulGuardedVariable = 0; - - /* Our priority should be as per that assigned when the task was - created. */ - if( uxTaskPriorityGet( NULL ) != genqMUTEX_LOW_PRIORITY ) - { - xErrorDetected = pdTRUE; - } - - /* Now unsuspend the high priority task. This will attempt to take the - mutex, and block when it finds it cannot obtain it. */ - vTaskResume( xHighPriorityMutexTask ); - - /* We should now have inherited the prioritoy of the high priority task, - as by now it will have attempted to get the mutex. */ - if( uxTaskPriorityGet( NULL ) != genqMUTEX_HIGH_PRIORITY ) - { - xErrorDetected = pdTRUE; - } - - /* We can attempt to set our priority to the test priority - between the - idle priority and the medium/high test priorities, but our actual - prioroity should remain at the high priority. */ - vTaskPrioritySet( NULL, genqMUTEX_TEST_PRIORITY ); - if( uxTaskPriorityGet( NULL ) != genqMUTEX_HIGH_PRIORITY ) - { - xErrorDetected = pdTRUE; - } - - /* Now unsuspend the medium priority task. This should not run as our - inherited priority is above that of the medium priority task. */ - vTaskResume( xMediumPriorityMutexTask ); - - /* If the did run then it will have incremented our guarded variable. */ - if( ulGuardedVariable != 0 ) - { - xErrorDetected = pdTRUE; - } - - /* When we give back the semaphore our priority should be disinherited - back to the priority to which we attempted to set ourselves. This means - that when the high priority task next blocks, the medium priority task - should execute and increment the guarded variable. When we next run - both the high and medium priority tasks will have been suspended again. */ - if( xSemaphoreGive( xMutex ) != pdPASS ) - { - xErrorDetected = pdTRUE; - } - - /* Check that the guarded variable did indeed increment... */ - if( ulGuardedVariable != 1 ) - { - xErrorDetected = pdTRUE; - } - - /* ... and that our priority has been disinherited to - genqMUTEX_TEST_PRIORITY. */ - if( uxTaskPriorityGet( NULL ) != genqMUTEX_TEST_PRIORITY ) - { - xErrorDetected = pdTRUE; - } - - /* Set our priority back to our original priority ready for the next - loop around this test. */ - vTaskPrioritySet( NULL, genqMUTEX_LOW_PRIORITY ); - - /* Just to show we are still running. */ - ulLoopCounter2++; - - #if configUSE_PREEMPTION == 0 - taskYIELD(); - #endif - } -} -/*-----------------------------------------------------------*/ - -static void prvMediumPriorityMutexTask( void *pvParameters ) -{ - ( void ) pvParameters; - - for( ;; ) - { - /* The medium priority task starts by suspending itself. The low - priority task will unsuspend this task when required. */ - vTaskSuspend( NULL ); - - /* When this task unsuspends all it does is increment the guarded - variable, this is so the low priority task knows that it has - executed. */ - ulGuardedVariable++; - } -} -/*-----------------------------------------------------------*/ - -static void prvHighPriorityMutexTask( void *pvParameters ) -{ -xSemaphoreHandle xMutex = ( xSemaphoreHandle ) pvParameters; - - for( ;; ) - { - /* The high priority task starts by suspending itself. The low - priority task will unsuspend this task when required. */ - vTaskSuspend( NULL ); - - /* When this task unsuspends all it does is attempt to obtain - the mutex. It should find the mutex is not available so a - block time is specified. */ - if( xSemaphoreTake( xMutex, portMAX_DELAY ) != pdPASS ) - { - xErrorDetected = pdTRUE; - } - - /* When we eventually obtain the mutex we just give it back then - return to suspend ready for the next test. */ - if( xSemaphoreGive( xMutex ) != pdPASS ) - { - xErrorDetected = pdTRUE; - } - } -} -/*-----------------------------------------------------------*/ - -/* This is called to check that all the created tasks are still running. */ -portBASE_TYPE xAreGenericQueueTasksStillRunning( void ) -{ -static unsigned portLONG ulLastLoopCounter = 0, ulLastLoopCounter2 = 0; - - /* If the demo task is still running then we expect the loopcounters to - have incremented since this function was last called. */ - if( ulLastLoopCounter == ulLoopCounter ) - { - xErrorDetected = pdTRUE; - } - - if( ulLastLoopCounter2 == ulLoopCounter2 ) - { - xErrorDetected = pdTRUE; - } - - ulLastLoopCounter = ulLoopCounter; - ulLastLoopCounter2 = ulLoopCounter2; - - /* Errors detected in the task itself will have latched xErrorDetected - to true. */ - - return !xErrorDetected; -} - - diff --git a/Demo/CORTEX_M0_LPC1114_LPCXpresso/RTOSDemo/Source/Common_Demo_Tasks/dynamic.c b/Demo/CORTEX_M0_LPC1114_LPCXpresso/RTOSDemo/Source/Common_Demo_Tasks/dynamic.c deleted file mode 100644 index 67512a784..000000000 --- a/Demo/CORTEX_M0_LPC1114_LPCXpresso/RTOSDemo/Source/Common_Demo_Tasks/dynamic.c +++ /dev/null @@ -1,427 +0,0 @@ -/* - FreeRTOS V7.1.0 - Copyright (C) 2011 Real Time Engineers Ltd. - - - *************************************************************************** - * * - * FreeRTOS tutorial books are available in pdf and paperback. * - * Complete, revised, and edited pdf reference manuals are also * - * available. * - * * - * 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! * - * * - * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * - * * - * Thank you for using FreeRTOS, and thank you for your support! * - * * - *************************************************************************** - - - 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. - >>>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 Richard Barry, contact details for whom are available on the - FreeRTOS WEB site. - - 1 tab == 4 spaces! - - http://www.FreeRTOS.org - Documentation, latest information, license and - contact details. - - http://www.SafeRTOS.com - A version that is certified for use in safety - critical systems. - - http://www.OpenRTOS.com - Commercial support, development, porting, - licensing and training services. -*/ - -/* - * The first test creates three tasks - two counter tasks (one continuous count - * and one limited count) and one controller. A "count" variable is shared - * between all three tasks. The two counter tasks should never be in a "ready" - * state at the same time. The controller task runs at the same priority as - * the continuous count task, and at a lower priority than the limited count - * task. - * - * One counter task loops indefinitely, incrementing the shared count variable - * on each iteration. To ensure it has exclusive access to the variable it - * raises it's priority above that of the controller task before each - * increment, lowering it again to it's original priority before starting the - * next iteration. - * - * The other counter task increments the shared count variable on each - * iteration of it's loop until the count has reached a limit of 0xff - at - * which point it suspends itself. It will not start a new loop until the - * controller task has made it "ready" again by calling vTaskResume (). - * This second counter task operates at a higher priority than controller - * task so does not need to worry about mutual exclusion of the counter - * variable. - * - * The controller task is in two sections. The first section controls and - * monitors the continuous count task. When this section is operational the - * limited count task is suspended. Likewise, the second section controls - * and monitors the limited count task. When this section is operational the - * continuous count task is suspended. - * - * In the first section the controller task first takes a copy of the shared - * count variable. To ensure mutual exclusion on the count variable it - * suspends the continuous count task, resuming it again when the copy has been - * taken. The controller task then sleeps for a fixed period - during which - * the continuous count task will execute and increment the shared variable. - * When the controller task wakes it checks that the continuous count task - * has executed by comparing the copy of the shared variable with its current - * value. This time, to ensure mutual exclusion, the scheduler itself is - * suspended with a call to vTaskSuspendAll (). This is for demonstration - * purposes only and is not a recommended technique due to its inefficiency. - * - * After a fixed number of iterations the controller task suspends the - * continuous count task, and moves on to its second section. - * - * At the start of the second section the shared variable is cleared to zero. - * The limited count task is then woken from it's suspension by a call to - * vTaskResume (). As this counter task operates at a higher priority than - * the controller task the controller task should not run again until the - * shared variable has been counted up to the limited value causing the counter - * task to suspend itself. The next line after vTaskResume () is therefore - * a check on the shared variable to ensure everything is as expected. - * - * - * The second test consists of a couple of very simple tasks that post onto a - * queue while the scheduler is suspended. This test was added to test parts - * of the scheduler not exercised by the first test. - * - */ - -#include - -/* Scheduler include files. */ -#include "FreeRTOS.h" -#include "task.h" -#include "semphr.h" - -/* Demo app include files. */ -#include "dynamic.h" - -/* Function that implements the "limited count" task as described above. */ -static portTASK_FUNCTION_PROTO( vLimitedIncrementTask, pvParameters ); - -/* Function that implements the "continuous count" task as described above. */ -static portTASK_FUNCTION_PROTO( vContinuousIncrementTask, pvParameters ); - -/* Function that implements the controller task as described above. */ -static portTASK_FUNCTION_PROTO( vCounterControlTask, pvParameters ); - -static portTASK_FUNCTION_PROTO( vQueueReceiveWhenSuspendedTask, pvParameters ); -static portTASK_FUNCTION_PROTO( vQueueSendWhenSuspendedTask, pvParameters ); - -/* Demo task specific constants. */ -#define priSTACK_SIZE ( configMINIMAL_STACK_SIZE ) -#define priSLEEP_TIME ( ( portTickType ) 128 / portTICK_RATE_MS ) -#define priLOOPS ( 5 ) -#define priMAX_COUNT ( ( unsigned long ) 0xff ) -#define priNO_BLOCK ( ( portTickType ) 0 ) -#define priSUSPENDED_QUEUE_LENGTH ( 1 ) - -/*-----------------------------------------------------------*/ - -/* Handles to the two counter tasks. These could be passed in as parameters -to the controller task to prevent them having to be file scope. */ -static xTaskHandle xContinousIncrementHandle, xLimitedIncrementHandle; - -/* The shared counter variable. This is passed in as a parameter to the two -counter variables for demonstration purposes. */ -static unsigned long ulCounter; - -/* Variables used to check that the tasks are still operating without error. -Each complete iteration of the controller task increments this variable -provided no errors have been found. The variable maintaining the same value -is therefore indication of an error. */ -static volatile unsigned short usCheckVariable = ( unsigned short ) 0; -static volatile portBASE_TYPE xSuspendedQueueSendError = pdFALSE; -static volatile portBASE_TYPE xSuspendedQueueReceiveError = pdFALSE; - -/* Queue used by the second test. */ -xQueueHandle xSuspendedTestQueue; - -/*-----------------------------------------------------------*/ -/* - * Start the three tasks as described at the top of the file. - * Note that the limited count task is given a higher priority. - */ -void vStartDynamicPriorityTasks( void ) -{ - xSuspendedTestQueue = xQueueCreate( priSUSPENDED_QUEUE_LENGTH, sizeof( unsigned long ) ); - - /* vQueueAddToRegistry() adds the queue to the queue registry, if one is - in use. The queue registry is provided as a means for kernel aware - debuggers to locate queues and has no purpose if a kernel aware debugger - is not being used. The call to vQueueAddToRegistry() will be removed - by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is - defined to be less than 1. */ - vQueueAddToRegistry( xSuspendedTestQueue, ( signed char * ) "Suspended_Test_Queue" ); - - xTaskCreate( vContinuousIncrementTask, ( signed char * ) "CNT_INC", priSTACK_SIZE, ( void * ) &ulCounter, tskIDLE_PRIORITY, &xContinousIncrementHandle ); - xTaskCreate( vLimitedIncrementTask, ( signed char * ) "LIM_INC", priSTACK_SIZE, ( void * ) &ulCounter, tskIDLE_PRIORITY + 1, &xLimitedIncrementHandle ); - xTaskCreate( vCounterControlTask, ( signed char * ) "C_CTRL", priSTACK_SIZE, NULL, tskIDLE_PRIORITY, NULL ); - xTaskCreate( vQueueSendWhenSuspendedTask, ( signed char * ) "SUSP_TX", priSTACK_SIZE, NULL, tskIDLE_PRIORITY, NULL ); - xTaskCreate( vQueueReceiveWhenSuspendedTask, ( signed char * ) "SUSP_RX", priSTACK_SIZE, NULL, tskIDLE_PRIORITY, NULL ); -} -/*-----------------------------------------------------------*/ - -/* - * Just loops around incrementing the shared variable until the limit has been - * reached. Once the limit has been reached it suspends itself. - */ -static portTASK_FUNCTION( vLimitedIncrementTask, pvParameters ) -{ -unsigned long *pulCounter; - - /* Take a pointer to the shared variable from the parameters passed into - the task. */ - pulCounter = ( unsigned long * ) pvParameters; - - /* This will run before the control task, so the first thing it does is - suspend - the control task will resume it when ready. */ - vTaskSuspend( NULL ); - - for( ;; ) - { - /* Just count up to a value then suspend. */ - ( *pulCounter )++; - - if( *pulCounter >= priMAX_COUNT ) - { - vTaskSuspend( NULL ); - } - } -} -/*-----------------------------------------------------------*/ - -/* - * Just keep counting the shared variable up. The control task will suspend - * this task when it wants. - */ -static portTASK_FUNCTION( vContinuousIncrementTask, pvParameters ) -{ -unsigned long *pulCounter; -unsigned portBASE_TYPE uxOurPriority; - - /* Take a pointer to the shared variable from the parameters passed into - the task. */ - pulCounter = ( unsigned long * ) pvParameters; - - /* Query our priority so we can raise it when exclusive access to the - shared variable is required. */ - uxOurPriority = uxTaskPriorityGet( NULL ); - - for( ;; ) - { - /* Raise our priority above the controller task to ensure a context - switch does not occur while we are accessing this variable. */ - vTaskPrioritySet( NULL, uxOurPriority + 1 ); - ( *pulCounter )++; - vTaskPrioritySet( NULL, uxOurPriority ); - } -} -/*-----------------------------------------------------------*/ - -/* - * Controller task as described above. - */ -static portTASK_FUNCTION( vCounterControlTask, pvParameters ) -{ -unsigned long ulLastCounter; -short sLoops; -short sError = pdFALSE; - - /* Just to stop warning messages. */ - ( void ) pvParameters; - - for( ;; ) - { - /* Start with the counter at zero. */ - ulCounter = ( unsigned long ) 0; - - /* First section : */ - - /* Check the continuous count task is running. */ - for( sLoops = 0; sLoops < priLOOPS; sLoops++ ) - { - /* Suspend the continuous count task so we can take a mirror of the - shared variable without risk of corruption. */ - vTaskSuspend( xContinousIncrementHandle ); - ulLastCounter = ulCounter; - vTaskResume( xContinousIncrementHandle ); - - /* Now delay to ensure the other task has processor time. */ - vTaskDelay( priSLEEP_TIME ); - - /* Check the shared variable again. This time to ensure mutual - exclusion the whole scheduler will be locked. This is just for - demo purposes! */ - vTaskSuspendAll(); - { - if( ulLastCounter == ulCounter ) - { - /* The shared variable has not changed. There is a problem - with the continuous count task so flag an error. */ - sError = pdTRUE; - } - } - xTaskResumeAll(); - } - - - /* Second section: */ - - /* Suspend the continuous counter task so it stops accessing the shared variable. */ - vTaskSuspend( xContinousIncrementHandle ); - - /* Reset the variable. */ - ulCounter = ( unsigned long ) 0; - - /* Resume the limited count task which has a higher priority than us. - We should therefore not return from this call until the limited count - task has suspended itself with a known value in the counter variable. */ - vTaskResume( xLimitedIncrementHandle ); - - /* Does the counter variable have the expected value? */ - if( ulCounter != priMAX_COUNT ) - { - sError = pdTRUE; - } - - if( sError == pdFALSE ) - { - /* If no errors have occurred then increment the check variable. */ - portENTER_CRITICAL(); - usCheckVariable++; - portEXIT_CRITICAL(); - } - - /* Resume the continuous count task and do it all again. */ - vTaskResume( xContinousIncrementHandle ); - } -} -/*-----------------------------------------------------------*/ - -static portTASK_FUNCTION( vQueueSendWhenSuspendedTask, pvParameters ) -{ -static unsigned long ulValueToSend = ( unsigned long ) 0; - - /* Just to stop warning messages. */ - ( void ) pvParameters; - - for( ;; ) - { - vTaskSuspendAll(); - { - /* We must not block while the scheduler is suspended! */ - if( xQueueSend( xSuspendedTestQueue, ( void * ) &ulValueToSend, priNO_BLOCK ) != pdTRUE ) - { - xSuspendedQueueSendError = pdTRUE; - } - } - xTaskResumeAll(); - - vTaskDelay( priSLEEP_TIME ); - - ++ulValueToSend; - } -} -/*-----------------------------------------------------------*/ - -static portTASK_FUNCTION( vQueueReceiveWhenSuspendedTask, pvParameters ) -{ -static unsigned long ulExpectedValue = ( unsigned long ) 0, ulReceivedValue; -portBASE_TYPE xGotValue; - - /* Just to stop warning messages. */ - ( void ) pvParameters; - - for( ;; ) - { - do - { - /* Suspending the scheduler here is fairly pointless and - undesirable for a normal application. It is done here purely - to test the scheduler. The inner xTaskResumeAll() should - never return pdTRUE as the scheduler is still locked by the - outer call. */ - vTaskSuspendAll(); - { - vTaskSuspendAll(); - { - xGotValue = xQueueReceive( xSuspendedTestQueue, ( void * ) &ulReceivedValue, priNO_BLOCK ); - } - if( xTaskResumeAll() ) - { - xSuspendedQueueReceiveError = pdTRUE; - } - } - xTaskResumeAll(); - - #if configUSE_PREEMPTION == 0 - { - taskYIELD(); - } - #endif - - } while( xGotValue == pdFALSE ); - - if( ulReceivedValue != ulExpectedValue ) - { - xSuspendedQueueReceiveError = pdTRUE; - } - - ++ulExpectedValue; - } -} -/*-----------------------------------------------------------*/ - -/* Called to check that all the created tasks are still running without error. */ -portBASE_TYPE xAreDynamicPriorityTasksStillRunning( void ) -{ -/* Keep a history of the check variables so we know if it has been incremented -since the last call. */ -static unsigned short usLastTaskCheck = ( unsigned short ) 0; -portBASE_TYPE xReturn = pdTRUE; - - /* Check the tasks are still running by ensuring the check variable - is still incrementing. */ - - if( usCheckVariable == usLastTaskCheck ) - { - /* The check has not incremented so an error exists. */ - xReturn = pdFALSE; - } - - if( xSuspendedQueueSendError == pdTRUE ) - { - xReturn = pdFALSE; - } - - if( xSuspendedQueueReceiveError == pdTRUE ) - { - xReturn = pdFALSE; - } - - usLastTaskCheck = usCheckVariable; - return xReturn; -} diff --git a/Demo/CORTEX_M0_LPC1114_LPCXpresso/RTOSDemo/Source/Common_Demo_Tasks/include/BlockQ.h b/Demo/CORTEX_M0_LPC1114_LPCXpresso/RTOSDemo/Source/Common_Demo_Tasks/include/BlockQ.h deleted file mode 100644 index 2e51b83a4..000000000 --- a/Demo/CORTEX_M0_LPC1114_LPCXpresso/RTOSDemo/Source/Common_Demo_Tasks/include/BlockQ.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - FreeRTOS V7.1.0 - Copyright (C) 2011 Real Time Engineers Ltd. - - - *************************************************************************** - * * - * FreeRTOS tutorial books are available in pdf and paperback. * - * Complete, revised, and edited pdf reference manuals are also * - * available. * - * * - * 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! * - * * - * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * - * * - * Thank you for using FreeRTOS, and thank you for your support! * - * * - *************************************************************************** - - - 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. - >>>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 Richard Barry, contact details for whom are available on the - FreeRTOS WEB site. - - 1 tab == 4 spaces! - - http://www.FreeRTOS.org - Documentation, latest information, license and - contact details. - - http://www.SafeRTOS.com - A version that is certified for use in safety - critical systems. - - http://www.OpenRTOS.com - Commercial support, development, porting, - licensing and training services. -*/ - -#ifndef BLOCK_Q_H -#define BLOCK_Q_H - -void vStartBlockingQueueTasks( unsigned portBASE_TYPE uxPriority ); -portBASE_TYPE xAreBlockingQueuesStillRunning( void ); - -#endif - - diff --git a/Demo/CORTEX_M0_LPC1114_LPCXpresso/RTOSDemo/Source/Common_Demo_Tasks/include/GenQTest.h b/Demo/CORTEX_M0_LPC1114_LPCXpresso/RTOSDemo/Source/Common_Demo_Tasks/include/GenQTest.h deleted file mode 100644 index c69c48130..000000000 --- a/Demo/CORTEX_M0_LPC1114_LPCXpresso/RTOSDemo/Source/Common_Demo_Tasks/include/GenQTest.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - FreeRTOS V7.1.0 - Copyright (C) 2011 Real Time Engineers Ltd. - - - *************************************************************************** - * * - * FreeRTOS tutorial books are available in pdf and paperback. * - * Complete, revised, and edited pdf reference manuals are also * - * available. * - * * - * 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! * - * * - * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * - * * - * Thank you for using FreeRTOS, and thank you for your support! * - * * - *************************************************************************** - - - 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. - >>>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 Richard Barry, contact details for whom are available on the - FreeRTOS WEB site. - - 1 tab == 4 spaces! - - http://www.FreeRTOS.org - Documentation, latest information, license and - contact details. - - http://www.SafeRTOS.com - A version that is certified for use in safety - critical systems. - - http://www.OpenRTOS.com - Commercial support, development, porting, - licensing and training services. -*/ - -#ifndef GEN_Q_TEST_H -#define GEN_Q_TEST_H - -void vStartGenericQueueTasks( unsigned portBASE_TYPE uxPriority ); -portBASE_TYPE xAreGenericQueueTasksStillRunning( void ); - -#endif /* GEN_Q_TEST_H */ - - - diff --git a/Demo/CORTEX_M0_LPC1114_LPCXpresso/RTOSDemo/Source/Common_Demo_Tasks/include/dynamic.h b/Demo/CORTEX_M0_LPC1114_LPCXpresso/RTOSDemo/Source/Common_Demo_Tasks/include/dynamic.h deleted file mode 100644 index 5da7c1e9c..000000000 --- a/Demo/CORTEX_M0_LPC1114_LPCXpresso/RTOSDemo/Source/Common_Demo_Tasks/include/dynamic.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - FreeRTOS V7.1.0 - Copyright (C) 2011 Real Time Engineers Ltd. - - - *************************************************************************** - * * - * FreeRTOS tutorial books are available in pdf and paperback. * - * Complete, revised, and edited pdf reference manuals are also * - * available. * - * * - * 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! * - * * - * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * - * * - * Thank you for using FreeRTOS, and thank you for your support! * - * * - *************************************************************************** - - - 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. - >>>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 Richard Barry, contact details for whom are available on the - FreeRTOS WEB site. - - 1 tab == 4 spaces! - - http://www.FreeRTOS.org - Documentation, latest information, license and - contact details. - - http://www.SafeRTOS.com - A version that is certified for use in safety - critical systems. - - http://www.OpenRTOS.com - Commercial support, development, porting, - licensing and training services. -*/ - -#ifndef DYNAMIC_MANIPULATION_H -#define DYNAMIC_MANIPULATION_H - -void vStartDynamicPriorityTasks( void ); -portBASE_TYPE xAreDynamicPriorityTasksStillRunning( void ); - -#endif - - diff --git a/Demo/CORTEX_M0_LPC1114_LPCXpresso/RTOSDemo/Source/FreeRTOSConfig.h b/Demo/CORTEX_M0_LPC1114_LPCXpresso/RTOSDemo/Source/FreeRTOSConfig.h index 9b9d9a80e..2f00c1243 100644 --- a/Demo/CORTEX_M0_LPC1114_LPCXpresso/RTOSDemo/Source/FreeRTOSConfig.h +++ b/Demo/CORTEX_M0_LPC1114_LPCXpresso/RTOSDemo/Source/FreeRTOSConfig.h @@ -77,7 +77,7 @@ extern uint32_t SystemCoreClock; #define configTICK_RATE_HZ ( ( portTickType ) 1000 ) #define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 5 ) #define configMINIMAL_STACK_SIZE ( ( unsigned short ) 70 ) -#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 6800 ) ) +#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 6500 ) ) #define configMAX_TASK_NAME_LEN ( 5 ) #define configUSE_TRACE_FACILITY 1 #define configUSE_16_BIT_TICKS 0 @@ -86,7 +86,7 @@ extern uint32_t SystemCoreClock; #define configQUEUE_REGISTRY_SIZE 8 #define configCHECK_FOR_STACK_OVERFLOW 2 #define configUSE_RECURSIVE_MUTEXES 1 -#define configUSE_MALLOC_FAILED_HOOK 2 +#define configUSE_MALLOC_FAILED_HOOK 1 #define configUSE_APPLICATION_TASK_TAG 0 #define configUSE_COUNTING_SEMAPHORES 1 #define configGENERATE_RUN_TIME_STATS 0 @@ -99,7 +99,7 @@ extern uint32_t SystemCoreClock; #define configUSE_TIMERS 1 #define configTIMER_TASK_PRIORITY ( 2 ) #define configTIMER_QUEUE_LENGTH 2 -#define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE ) +#define configTIMER_TASK_STACK_DEPTH ( 80 ) /* Set the following definitions to 1 to include the API function, or zero to exclude the API function. */ diff --git a/Demo/CORTEX_M0_LPC1114_LPCXpresso/RTOSDemo/Source/main-blinky.c b/Demo/CORTEX_M0_LPC1114_LPCXpresso/RTOSDemo/Source/main-blinky.c new file mode 100644 index 000000000..bb0aa9b03 --- /dev/null +++ b/Demo/CORTEX_M0_LPC1114_LPCXpresso/RTOSDemo/Source/main-blinky.c @@ -0,0 +1,225 @@ +/* + FreeRTOS V7.1.0 - Copyright (C) 2011 Real Time Engineers Ltd. + + + *************************************************************************** + * * + * FreeRTOS tutorial books are available in pdf and paperback. * + * Complete, revised, and edited pdf reference manuals are also * + * available. * + * * + * 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! * + * * + * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * + * * + * Thank you for using FreeRTOS, and thank you for your support! * + * * + *************************************************************************** + + + 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. + >>>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 Richard Barry, contact details for whom are available on the + FreeRTOS WEB site. + + 1 tab == 4 spaces! + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +/****************************************************************************** + * NOTE 1: This project provides two demo applications. A simple blinky style + * project, and a more comprehensive test and demo application. The + * mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting in main.c is used to select + * between the two. See the notes on using mainCREATE_SIMPLE_BLINKY_DEMO_ONLY + * in main.c. This file implements the simply blinky style version. + * + * NOTE 2: This file only contains the source code that is specific to the + * full demo. Generic functions, such FreeRTOS hook functions, and functions + * required to configure the hardware, are defined in main.c. + ****************************************************************************** + * + * main_blinky() creates one software timer, one queue, and two tasks. It then + * starts the scheduler. + * + * The Queue Send Task: + * The queue send task is implemented by the prvQueueSendTask() function in + * this file. prvQueueSendTask() sits in a loop that causes it to repeatedly + * block for 200 milliseconds, before sending the value 100 to the queue that + * was created within main_blinky(). Once the value is sent, the task loops + * back around to block for another 200 milliseconds. + * + * The Queue Receive Task: + * The queue receive task is implemented by the prvQueueReceiveTask() function + * in this file. prvQueueReceiveTask() sits in a loop where it repeatedly + * blocks on attempts to read data from the queue that was created within + * main_blinky(). When data is received, the task checks the value of the + * data, and if the value equals the expected 100, toggles the LED. The 'block + * time' parameter passed to the queue receive function specifies that the + * task should be held in the Blocked state indefinitely to wait for data to + * be available on the queue. The queue receive task will only leave the + * Blocked state when the queue send task writes to the queue. As the queue + * send task writes to the queue every 200 milliseconds, the queue receive + * task leaves the Blocked state every 200 milliseconds, and therefore toggles + * the LED every 200 milliseconds. + */ + +/* Kernel includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" + +/* Hardware specific includes. */ +#include "lpc11xx.h" + +/* Priorities at which the tasks are created. */ +#define mainQUEUE_RECEIVE_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 ) +#define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) + +/* The rate at which data is sent to the queue. The 200ms value is converted +to ticks using the portTICK_RATE_MS constant. */ +#define mainQUEUE_SEND_FREQUENCY_MS ( 200 / portTICK_RATE_MS ) + +/* The number of items the queue can hold. This is 1 as the receive task +will remove items as they are added, meaning the send task should always find +the queue empty. */ +#define mainQUEUE_LENGTH ( 1 ) + +/* Values passed to the two tasks just to check the task parameter +functionality. */ +#define mainQUEUE_SEND_PARAMETER ( 0x1111UL ) +#define mainQUEUE_RECEIVE_PARAMETER ( 0x22UL ) +/*-----------------------------------------------------------*/ + +/* + * The tasks as described in the comments at the top of this file. + */ +static void prvQueueReceiveTask( void *pvParameters ); +static void prvQueueSendTask( void *pvParameters ); + +/* + * Called by main() to create the simply blinky style application if + * mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 1. + */ +void main_blinky( void ); + +/* + * The hardware only has a single LED. Simply toggle it. + */ +extern void vMainToggleLED( void ); + +/*-----------------------------------------------------------*/ + +/* The queue used by both tasks. */ +static xQueueHandle xQueue = NULL; + +/*-----------------------------------------------------------*/ + +void main_blinky( void ) +{ + /* Create the queue. */ + xQueue = xQueueCreate( mainQUEUE_LENGTH, sizeof( unsigned long ) ); + + if( xQueue != NULL ) + { + /* Start the two tasks as described in the comments at the top of this + file. */ + xTaskCreate( prvQueueReceiveTask, /* The function that implements the task. */ + ( signed char * ) "Rx", /* The text name assigned to the task - for debug only as it is not used by the kernel. */ + configMINIMAL_STACK_SIZE, /* The size of the stack to allocate to the task. */ + ( void * ) mainQUEUE_RECEIVE_PARAMETER, /* The parameter passed to the task - just to check the functionality. */ + mainQUEUE_RECEIVE_TASK_PRIORITY, /* The priority assigned to the task. */ + NULL ); /* The task handle is not required, so NULL is passed. */ + + xTaskCreate( prvQueueSendTask, ( signed char * ) "TX", configMINIMAL_STACK_SIZE, ( void * ) mainQUEUE_SEND_PARAMETER, mainQUEUE_SEND_TASK_PRIORITY, NULL ); + + /* Start the tasks and timer running. */ + vTaskStartScheduler(); + } + + /* If all is well, the scheduler will now be running, and the following + line will never be reached. If the following line does execute, then + there was insufficient FreeRTOS heap memory available for the idle and/or + timer tasks to be created. See the memory management section on the + FreeRTOS web site for more details. */ + for( ;; ); +} +/*-----------------------------------------------------------*/ + +static void prvQueueSendTask( void *pvParameters ) +{ +portTickType xNextWakeTime; +const unsigned long ulValueToSend = 100UL; + + /* Check the task parameter is as expected. */ + configASSERT( ( ( unsigned long ) pvParameters ) == mainQUEUE_SEND_PARAMETER ); + + /* Initialise xNextWakeTime - this only needs to be done once. */ + xNextWakeTime = xTaskGetTickCount(); + + for( ;; ) + { + /* Place this task in the blocked state until it is time to run again. + The block time is specified in ticks, the constant used converts ticks + to ms. While in the Blocked state this task will not consume any CPU + time. */ + vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS ); + + /* Send to the queue - causing the queue receive task to unblock and + toggle the LED. 0 is used as the block time so the sending operation + will not block - it shouldn't need to block as the queue should always + be empty at this point in the code. */ + xQueueSend( xQueue, &ulValueToSend, 0U ); + } +} +/*-----------------------------------------------------------*/ + +static void prvQueueReceiveTask( void *pvParameters ) +{ +unsigned long ulReceivedValue; + + /* Check the task parameter is as expected. */ + configASSERT( ( ( unsigned long ) pvParameters ) == mainQUEUE_RECEIVE_PARAMETER ); + + for( ;; ) + { + /* Wait until something arrives in the queue - this task will block + indefinitely provided INCLUDE_vTaskSuspend is set to 1 in + FreeRTOSConfig.h. */ + xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY ); + + /* To get here something must have been received from the queue, but + is it the expected value? If it is, toggle the LED. */ + if( ulReceivedValue == 100UL ) + { + vMainToggleLED(); + ulReceivedValue = 0U; + } + } +} +/*-----------------------------------------------------------*/ + diff --git a/Demo/CORTEX_M0_LPC1114_LPCXpresso/RTOSDemo/Source/main-full.c b/Demo/CORTEX_M0_LPC1114_LPCXpresso/RTOSDemo/Source/main-full.c new file mode 100644 index 000000000..31739a04e --- /dev/null +++ b/Demo/CORTEX_M0_LPC1114_LPCXpresso/RTOSDemo/Source/main-full.c @@ -0,0 +1,293 @@ +/* + FreeRTOS V7.1.0 - Copyright (C) 2011 Real Time Engineers Ltd. + + + *************************************************************************** + * * + * FreeRTOS tutorial books are available in pdf and paperback. * + * Complete, revised, and edited pdf reference manuals are also * + * available. * + * * + * 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! * + * * + * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * + * * + * Thank you for using FreeRTOS, and thank you for your support! * + * * + *************************************************************************** + + + 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. + >>>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 Richard Barry, contact details for whom are available on the + FreeRTOS WEB site. + + 1 tab == 4 spaces! + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +/****************************************************************************** + * NOTE 1: This project provides two demo applications. A simple blinky style + * project, and a more comprehensive test and demo application. The + * mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting in main.c is used to select + * between the two. See the notes on using mainCREATE_SIMPLE_BLINKY_DEMO_ONLY + * in main.c. This file implements the comprehensive test and demo version. + * + * NOTE 2: This file only contains the source code that is specific to the + * full demo. Generic functions, such FreeRTOS hook functions, and functions + * required to configure the hardware, are defined in main.c. + ****************************************************************************** + * + * main_full() creates all the demo application tasks (including a set of tasks + * that test the interrupt nesting behaviour) and a timer, then starts the + * scheduler. The web documentation provides more details of the standard demo + * application tasks, which provide no particular functionality, but do provide + * a good example of how to use the FreeRTOS API. + * + * The interrupt nesting test tasks require that two timers are configured to + * generate interrupts. The interrupt service routines are defined in + * IntQueueTimer.c, and can be used as examples for application writers. They + * do not, however, directly demonstrate the use of FreeRTOS safe API functions + * (those that end in "FromISR"). Therefore, a dummy interrupt implementation + * called Dummy_IRQHandler() is provided at the end of main.c. + * + * In addition to the standard demo tasks, the following tasks and timer are + * defined and/or created within this file: + * + * "Reg test" tasks - These fill the registers with known values, then check + * that each register maintains its expected value for the lifetime of the + * task. Each task uses a different set of values. The reg test tasks execute + * with a very low priority, so get preempted very frequently. A register + * containing an unexpected value is indicative of an error in the context + * switching mechanism. + * + * "Check" software timer - The check timer period is initially set to three + * seconds. Its callback function checks that all the standard demo tasks, and + * the register check tasks, are not only still executing, but are executing + * without reporting any errors. If the check timer callback discovers that a + * task has either stalled, or reported an error, then it changes the period of + * the check timer from the initial three seconds, to just 200ms. The callback + * function also toggles an LED each time it is called. This provides a visual + * indication of the system status: If the LED toggles every three seconds, + * then no issues have been discovered. If the LED toggles every 200ms, then + * an issue has been discovered with at least one task. + */ + +/* Kernel includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "timers.h" + +/* Common demo includes. */ +#include "blocktim.h" +#include "countsem.h" +#include "recmutex.h" +#include "IntQueue.h" + +/* Hardware specific includes. */ +#include "lpc11xx.h" + +/* The period after which the check timer will expire 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 ) + +/* The period at which the check timer will expire 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 ) + +/* A block time of zero simply means "don't block". */ +#define mainDONT_BLOCK ( 0UL ) + +/*-----------------------------------------------------------*/ + +/* + * Register check tasks, as described at the top of this file. The nature of + * these files necessitates that they are written in an assembly. + */ +extern void vRegTest1Task( void *pvParameters ); +extern void vRegTest2Task( void *pvParameters ); + +/* + * The hardware only has a single LED. Simply toggle it. + */ +extern void vMainToggleLED( void ); + +/* + * The check timer callback function, as described at the top of this file. + */ +static void prvCheckTimerCallback( xTimerHandle xTimer ); + +/* + * Called by main() to create the comprehensive test/demo application if + * mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is not set to 1. + */ +void main_full( void ); + +/*-----------------------------------------------------------*/ + +/* The following two variables are used to communicate the status of the +register check tasks to the check software timer. If the variables keep +incrementing, then the register check tasks has not discovered any errors. If +a variable stops incrementing, then an error has been found. */ +volatile unsigned long ulRegTest1LoopCounter = 0UL, ulRegTest2LoopCounter = 0UL; + +/*-----------------------------------------------------------*/ + +void main_full( void ) +{ +xTimerHandle xCheckTimer = NULL; +/* The register test tasks are asm functions that don't use a stack. The +stack allocated just has to be large enough to hold the task context, and +for the additional required for the stack overflow checking to work (if +configured). */ +const size_t xRegTestStackSize = 25U; + + /* Create the standard demo tasks, including the interrupt nesting test + tasks. */ + vStartInterruptQueueTasks(); + vCreateBlockTimeTasks(); + vStartCountingSemaphoreTasks(); + vStartRecursiveMutexTasks(); + + /* Create the register test tasks as described at the top of this file. + These are naked functions that don't use any stack. A stack still has + to be allocated to hold the task context. */ + xTaskCreate( vRegTest1Task, /* Function that implements the task. */ + ( signed char * ) "Reg1", /* Text name of the task. */ + xRegTestStackSize, /* Stack allocated to the task. */ + NULL, /* The task parameter is not used. */ + tskIDLE_PRIORITY, /* The priority to assign to the task. */ + NULL ); /* Don't receive a handle back, it is not needed. */ + + xTaskCreate( vRegTest2Task, /* Function that implements the task. */ + ( signed char * ) "Reg2", /* Text name of the task. */ + xRegTestStackSize, /* Stack allocated to the task. */ + NULL, /* The task parameter is not used. */ + tskIDLE_PRIORITY, /* The priority to assign to the task. */ + NULL ); /* Don't receive a handle back, it is not needed. */ + + /* Create the software timer that performs the 'check' functionality, + as described at the top of this file. */ + xCheckTimer = xTimerCreate( ( const signed char * ) "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 the software timer was created successfully, start it. It won't + actually start running until the scheduler starts. A block time of + zero is used in this call, although any value could be used as the block + time will be ignored because the scheduler has not started yet. */ + if( xCheckTimer != NULL ) + { + xTimerStart( xCheckTimer, mainDONT_BLOCK ); + } + + /* Start the kernel. From here on, only tasks and interrupts will run. */ + vTaskStartScheduler(); + + /* If all is well, the scheduler will now be running, and the following + line will never be reached. If the following line does execute, then there + was insufficient FreeRTOS heap memory available for the idle and/or timer + tasks to be created. See the memory management section on the FreeRTOS web + site, or the FreeRTOS tutorial books for more details. */ + for( ;; ); +} +/*-----------------------------------------------------------*/ + +/* See the description at the top of this file. */ +static void prvCheckTimerCallback( xTimerHandle xTimer ) +{ +static long lChangedTimerPeriodAlready = pdFALSE; +static unsigned long ulLastRegTest1Value = 0, ulLastRegTest2Value = 0; +unsigned long ulErrorFound = pdFALSE; + + /* Check all the demo and test tasks to ensure that they are all still + running, and that none have detected an error. */ + if( xAreIntQueueTasksStillRunning() != pdPASS ) + { + ulErrorFound |= ( 0x01UL << 0UL ); + } + + if( xAreBlockTimeTestTasksStillRunning() != pdPASS ) + { + ulErrorFound |= ( 0x01UL << 1UL ); + } + + if( xAreCountingSemaphoreTasksStillRunning() != pdPASS ) + { + ulErrorFound |= ( 0x01UL << 2UL ); + } + + if( xAreRecursiveMutexTasksStillRunning() != pdPASS ) + { + ulErrorFound |= ( 0x01UL << 3UL ); + } + + /* Check that the register test 1 task is still running. */ + if( ulLastRegTest1Value == ulRegTest1LoopCounter ) + { + ulErrorFound |= ( 0x01UL << 4UL ); + } + ulLastRegTest1Value = ulRegTest1LoopCounter; + + /* Check that the register test 2 task is still running. */ + if( ulLastRegTest2Value == ulRegTest2LoopCounter ) + { + ulErrorFound |= ( 0x01UL << 5UL ); + } + ulLastRegTest2Value = ulRegTest2LoopCounter; + + /* Toggle the check LED to give an indication of the system status. If + the LED toggles every mainCHECK_TIMER_PERIOD_MS milliseconds then + everything is ok. A faster toggle indicates an error. */ + vMainToggleLED(); + + /* Have any errors been latched in ulErrorFound? If so, shorten the + period of the check timer to mainERROR_CHECK_TIMER_PERIOD_MS milliseconds. + This will result in an increase in the rate at which mainCHECK_LED + toggles. */ + if( ulErrorFound != pdFALSE ) + { + 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. */ + xTimerChangePeriod( xTimer, ( mainERROR_CHECK_TIMER_PERIOD_MS ), mainDONT_BLOCK ); + } + } +} +/*-----------------------------------------------------------*/ + diff --git a/Demo/CORTEX_M0_LPC1114_LPCXpresso/RTOSDemo/Source/main.c b/Demo/CORTEX_M0_LPC1114_LPCXpresso/RTOSDemo/Source/main.c index 1aa576cbd..f3401365b 100644 --- a/Demo/CORTEX_M0_LPC1114_LPCXpresso/RTOSDemo/Source/main.c +++ b/Demo/CORTEX_M0_LPC1114_LPCXpresso/RTOSDemo/Source/main.c @@ -51,57 +51,53 @@ licensing and training services. */ +/****************************************************************************** + * This project provides two demo applications. A simple blinky style project, + * and a more comprehensive test and demo application. The + * mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting (defined in this file) is used to + * select between the two. The simply blinky demo is implemented and described + * in main_blinky.c. The more comprehensive test and demo application is + * implemented and described in main_full.c. + * + * This file implements the code that is not demo specific, including the + * hardware setup and FreeRTOS hook functions. It also contains a dummy + * interrupt service routine called Dummy_IRQHandler() that is provided as an + * example of how to use interrupt safe FreeRTOS API functions (those that end + * in "FromISR"). + * + *****************************************************************************/ + /* Standard includes. */ #include "string.h" -/* Kernel includes. */ +/* FreeRTOS includes. */ #include "FreeRTOS.h" #include "task.h" -#include "queue.h" -#include "timers.h" - -/* Common demo includes. */ -#include "dynamic.h" -#include "blocktim.h" -#include "countsem.h" -#include "GenQTest.h" -#include "recmutex.h" -#include "IntQueue.h" /* Hardware specific includes. */ #include "lpc11xx.h" +/* Set mainCREATE_SIMPLE_BLINKY_DEMO_ONLY to one to run the simple blinky demo, +or 0 to run the more comprehensive test and demo application. */ +#define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 1 + /* The bit on port 0 to which the LED is wired. */ #define mainLED_BIT ( 1UL << 7UL ) -/* 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 ) - -/* 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 ) - -/* A block time of zero simply means "don't block". */ -#define mainDONT_BLOCK ( 0UL ) - +/* The configCHECK_FOR_STACK_OVERFLOW setting in FreeRTOSConifg can be used to +check task stacks for overflows. It does not however check the stack used by +interrupts. This demo has a simple addition that will also check the stack used +by interrupts if mainCHECK_INTERRUPT_STACK is set to 1. Note that this check is +only performed from the tick hook function (which runs in an interrupt context). +It is a good debugging aid - but won't catch interrupt stack problems until the +tick interrupt next executes. */ #define mainCHECK_INTERRUPT_STACK 1 - #if mainCHECK_INTERRUPT_STACK == 1 const unsigned char ucExpectedInterruptStackValues[] = { 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC }; #endif /*-----------------------------------------------------------*/ -/* - * Register check tasks, as described at the top of this file. The nature of - * these files necessitates that they are written in an assembly file. - */ -extern void vRegTest1Task( void *pvParameters ); -extern void vRegTest2Task( void *pvParameters ); - /* * Perform any application specific hardware configuration. The clocks, * memory, etc. are configured before main() is called. @@ -111,129 +107,52 @@ static void prvSetupHardware( void ); /* * The hardware only has a single LED. Simply toggle it. */ -static void prvToggleLED( void ); +void vMainToggleLED( void ); -/* - * The check timer callback function, as described at the top of this file. - */ -static void prvCheckTimerCallback( xTimerHandle xTimer ); +/* main_blinky() is used when mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 1. +main_full() is used when mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 0. */ +void main_blinky( void ); +void main_full( void ); /*-----------------------------------------------------------*/ /* The GPIO port to which the LED is attached. */ static LPC_GPIO_TypeDef * const xGPIO0 = LPC_GPIO0; -/* The following two variables are used to communicate the status of the -register check tasks to the check software timer. If the variables keep -incrementing, then the register check tasks has not discovered any errors. If -a variable stops incrementing, then an error has been found. */ -volatile unsigned long ulRegTest1LoopCounter = 0UL, ulRegTest2LoopCounter = 0UL; - /*-----------------------------------------------------------*/ - int main( void ) { -xTimerHandle xCheckTimer = NULL; - + /* Prepare the hardware to run this demo. */ prvSetupHardware(); - /* Create the standard demo tasks. */ -// vStartDynamicPriorityTasks(); -// vCreateBlockTimeTasks(); -// vStartCountingSemaphoreTasks(); -// vStartGenericQueueTasks( tskIDLE_PRIORITY ); -// vStartRecursiveMutexTasks(); - vStartInterruptQueueTasks(); - - /* Create the register test tasks as described at the top of this file. */ - xTaskCreate( vRegTest1Task, /* Function that implements the task. */ - ( signed char * ) "Reg1", /* Text name of the task. */ - configMINIMAL_STACK_SIZE, /* Stack allocated to the task. */ - NULL, /* The task parameter is not used. */ - tskIDLE_PRIORITY, /* The priority to assign to the task. */ - NULL ); /* Don't receive a handle back, it is not needed. */ - - xTaskCreate( vRegTest2Task, /* Function that implements the task. */ - ( signed char * ) "Reg2", /* Text name of the task. */ - configMINIMAL_STACK_SIZE, /* Stack allocated to the task. */ - NULL, /* The task parameter is not used. */ - tskIDLE_PRIORITY, /* The priority to assign to the task. */ - NULL ); /* Don't receive a handle back, it is not needed. */ - - /* Create the software timer that performs the 'check' functionality, - as described at the top of this file. */ - xCheckTimer = xTimerCreate( ( const signed char * ) "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( xCheckTimer != NULL ) + /* The mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting is described at the top + of this file. */ + #if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 { - xTimerStart( xCheckTimer, mainDONT_BLOCK ); + main_blinky(); } - - /* Start the kernel. From here on, only tasks and interrupts will run. */ - vTaskStartScheduler(); - - /* If all is well, the scheduler will now be running, and the following - line will never be reached. If the following line does execute, then there - was insufficient FreeRTOS heap memory available for the idle and/or timer - tasks to be created. See the memory management section on the FreeRTOS web - site, or the FreeRTOS tutorial books for more details. */ - for( ;; ); + #else + { + main_full(); + } + #endif } /*-----------------------------------------------------------*/ -static void prvCheckTimerCallback( xTimerHandle xTimer ) +void vMainToggleLED( void ) { -static long lChangedTimerPeriodAlready = pdFALSE; -static unsigned long ulLastRegTest1Value = 0, ulLastRegTest2Value = 0; -unsigned long ulErrorFound = pdFALSE; +static unsigned long ulLEDState = 0UL; - /* Check all the demo and test tasks to ensure that they are all still - running, and that none have detected an error. */ - if( xAreIntQueueTasksStillRunning() != pdPASS ) + if( ulLEDState == 0UL ) { - ulErrorFound |= ( 0x01UL << 0UL ); + xGPIO0->MASKED_ACCESS[ mainLED_BIT ] = 0UL; } - - /* Check that the register test 1 task is still running. */ - if( ulLastRegTest1Value == ulRegTest1LoopCounter ) + else { - ulErrorFound |= ( 0x01UL << 10UL ); + xGPIO0->MASKED_ACCESS[ mainLED_BIT ] = mainLED_BIT; } - ulLastRegTest1Value = ulRegTest1LoopCounter; - /* Check that the register test 2 task is still running. */ - if( ulLastRegTest2Value == ulRegTest2LoopCounter ) - { - ulErrorFound |= ( 0x01UL << 11UL ); - } - ulLastRegTest2Value = ulRegTest2LoopCounter; - - /* Toggle the check LED to give an indication of the system status. If - the LED toggles every mainCHECK_TIMER_PERIOD_MS milliseconds then - everything is ok. A faster toggle indicates an error. */ - prvToggleLED(); - - /* Have any errors been latched in ulErrorFound? If so, shorten the - period of the check timer to mainERROR_CHECK_TIMER_PERIOD_MS milliseconds. - This will result in an increase in the rate at which mainCHECK_LED - toggles. */ - if( ulErrorFound != pdFALSE ) - { - 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. */ - xTimerChangePeriod( xTimer, ( mainERROR_CHECK_TIMER_PERIOD_MS ), mainDONT_BLOCK ); - } - } + ulLEDState = !ulLEDState; } /*-----------------------------------------------------------*/ @@ -267,23 +186,6 @@ unsigned long ulInterruptStackSize; } /*-----------------------------------------------------------*/ -static void prvToggleLED( void ) -{ -static unsigned long ulLEDState = 0UL; - - if( ulLEDState == 0UL ) - { - xGPIO0->MASKED_ACCESS[ mainLED_BIT ] = 0UL; - } - else - { - xGPIO0->MASKED_ACCESS[ mainLED_BIT ] = mainLED_BIT; - } - - ulLEDState = !ulLEDState; -} -/*-----------------------------------------------------------*/ - void vApplicationMallocFailedHook( void ) { /* vApplicationMallocFailedHook() will only be called if @@ -348,6 +250,32 @@ extern unsigned long _pvHeapStart[]; } /*-----------------------------------------------------------*/ +#ifdef JUST_AN_EXAMPLE_ISR + +void Dummy_IRQHandler(void) +{ +long lHigherPriorityTaskWoken = pdFALSE; + + /* Clear the interrupt if necessary. */ + Dummy_ClearITPendingBit(); + + /* This interrupt does nothing more than demonstrate how to synchronise a + task with an interrupt. A semaphore is used for this purpose. Note + lHigherPriorityTaskWoken is initialised to zero. */ + xSemaphoreGiveFromISR( xTestSemaphore, &lHigherPriorityTaskWoken ); + + /* If there was a task that was blocked on the semaphore, and giving the + semaphore caused the task to unblock, and the unblocked task has a priority + higher than the current Running state task (the task that this interrupt + interrupted), then lHigherPriorityTaskWoken will have been set to pdTRUE + internally within xSemaphoreGiveFromISR(). Passing pdTRUE into the + portEND_SWITCHING_ISR() macro will result in a context switch being pended to + ensure this interrupt returns directly to the unblocked, higher priority, + task. Passing pdFALSE into portEND_SWITCHING_ISR() has no effect. */ + portEND_SWITCHING_ISR( lHigherPriorityTaskWoken ); +} + +#endif /* JUST_AN_EXAMPLE_ISR */ -- 2.39.5