/* FreeRTOS.org V5.0.0 - Copyright (C) 2003-2008 Richard Barry. This file is part of the FreeRTOS.org distribution. FreeRTOS.org is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. FreeRTOS.org 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 along with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA A special exception to the GPL can be applied should you wish to distribute a combined work that includes FreeRTOS.org, without being obliged to provide the source code for any proprietary components. See the licensing section of http://www.FreeRTOS.org for full details of how and when the exception can be applied. *************************************************************************** *************************************************************************** * * * SAVE TIME AND MONEY! We can port FreeRTOS.org to your own hardware, * * and even write all or part of your application on your behalf. * * See http://www.OpenRTOS.com for details of the services we provide to * * expedite your project. * * * *************************************************************************** *************************************************************************** Please ensure to read the configuration and relevant port sections of the online documentation. 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. */ /* Environment includes. */ #include /* Scheduler includes. */ #include "FreeRTOS.h" #include "task.h" #include "queue.h" #include "semphr.h" /* Demo app includes. */ #include "BlockQ.h" #include "death.h" #include "integer.h" #include "blocktim.h" #include "portlcd.h" #include "flash.h" #include "partest.h" #include "semtest.h" #include "PollQ.h" /* Demo application definitions. */ #define mainQUEUE_SIZE ( 3 ) #define mainCHECK_DELAY ( ( portTickType ) 5000 / portTICK_RATE_MS ) #define mainBASIC_WEB_STACK_SIZE ( configMINIMAL_STACK_SIZE * 2 ) /* Task priorities. */ #define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 ) #define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 ) #define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainFLASH_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainCREATOR_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 ) #define mainINTEGER_TASK_PRIORITY ( tskIDLE_PRIORITY ) /* * Checks the status of all the demo tasks then prints a message to the * CrossStudio terminal IO windows. The message will be either PASS or FAIL * depending on the status of the demo applications tasks. A FAIL status will * be latched. * * Messages are not written directly to the terminal, but passed to vPrintTask * via a queue. */ static void vCheckTask( void *pvParameters ); /* * The task that handles the uIP stack. All TCP/IP processing is performed in * this task. */ extern void vuIP_Task( void *pvParameters ); /* * The LCD is written two by more than one task so is controlled by a * 'gatekeeper' task. This is the only task that is actually permitted to * access the LCD directly. Other tasks wanting to display a message send * the message to the gatekeeper. */ static void vLCDTask( void *pvParameters ); /* The queue used to send messages to the LCD task. */ xQueueHandle xLCDQueue; /*-----------------------------------------------------------*/ int main (void) { /* Setup the led's on the MCB2300 board */ vParTestInitialise(); /* Create the queue used by the LCD task. Messages for display on the LCD are received via this queue. */ xLCDQueue = xQueueCreate( mainQUEUE_SIZE, sizeof( xLCDMessage ) ); /* Create the lwIP task. This uses the lwIP RTOS abstraction layer.*/ xTaskCreate( vuIP_Task, ( signed portCHAR * ) "uIP", mainBASIC_WEB_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY - 1, NULL ); /* Start the standard demo tasks. */ vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY ); vCreateBlockTimeTasks(); vStartLEDFlashTasks( mainFLASH_PRIORITY ); vStartSemaphoreTasks( mainSEM_TEST_PRIORITY ); vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY ); vStartIntegerMathTasks( mainINTEGER_TASK_PRIORITY ); /* Start the tasks defined within this file/specific to this demo. */ xTaskCreate( vCheckTask, ( signed portCHAR * ) "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL ); xTaskCreate( vLCDTask, ( signed portCHAR * ) "LCD", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY - 1, NULL ); /* The suicide tasks must be created last as they need to know how many tasks were running prior to their creation in order to ascertain whether or not the correct/expected number of tasks are running at any given time. */ vCreateSuicidalTasks( mainCREATOR_TASK_PRIORITY ); /* Start the scheduler. */ vTaskStartScheduler(); /* Will only get here if there was insufficient memory to create the idle task. */ return 0; } /*-----------------------------------------------------------*/ static void vCheckTask( void *pvParameters ) { portBASE_TYPE xErrorOccurred = pdFALSE; portTickType xLastExecutionTime; unsigned portBASE_TYPE uxColumn = 0; xLCDMessage xMessage; xLastExecutionTime = xTaskGetTickCount(); xMessage.xColumn = 0; xMessage.pcMessage = "PASS"; for( ;; ) { /* Perform this check every mainCHECK_DELAY milliseconds. */ vTaskDelayUntil( &xLastExecutionTime, mainCHECK_DELAY ); /* Has an error been found in any task? */ if( xAreBlockingQueuesStillRunning() != pdTRUE ) { xErrorOccurred = pdTRUE; } if( xAreBlockTimeTestTasksStillRunning() != pdTRUE ) { xErrorOccurred = pdTRUE; } if( xAreSemaphoreTasksStillRunning() != pdTRUE ) { xErrorOccurred = pdTRUE; } if( xArePollingQueuesStillRunning() != pdTRUE ) { xErrorOccurred = pdTRUE; } if( xIsCreateTaskStillRunning() != pdTRUE ) { xErrorOccurred = pdTRUE; } if( xAreIntegerMathsTaskStillRunning() != pdTRUE ) { xErrorOccurred = pdTRUE; } LCD_cls(); xMessage.xColumn++; LCD_gotoxy( ( uxColumn & 0x07 ) + 1, ( uxColumn & 0x01 ) + 1 ); if( xErrorOccurred == pdTRUE ) { xMessage.pcMessage = "FAIL"; } /* Send the message to the LCD gatekeeper for display. */ xQueueSend( xLCDQueue, &xMessage, portMAX_DELAY ); } } /*-----------------------------------------------------------*/ void vLCDTask( void *pvParameters ) { xLCDMessage xMessage; /* Initialise the LCD and display a startup message. */ LCD_init(); LCD_cur_off(); LCD_cls(); LCD_gotoxy( 1, 1 ); LCD_puts( ( signed portCHAR * ) "www.FreeRTOS.org" ); for( ;; ) { /* Wait for a message to arrive that requires displaying. */ while( xQueueReceive( xLCDQueue, &xMessage, portMAX_DELAY ) != pdPASS ); /* Display the message. Print each message to a different position. */ LCD_cls(); LCD_gotoxy( ( xMessage.xColumn & 0x07 ) + 1, ( xMessage.xColumn & 0x01 ) + 1 ); LCD_puts( xMessage.pcMessage ); } } /*-----------------------------------------------------------*/ /* Keep the compiler quiet. */ #include int __putchar( int c ) { return EOF; }