FreeRTOS Real Time Operating System, Modified from Kenji Arai's initial port. See freertos.org for full documentation.

Fork of FreeRTOS_on_mbed_v1 by Kenji Arai

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /*
00002     FreeRTOS V6.0.3 - Copyright (C) 2010 Real Time Engineers Ltd.
00003 
00004     ***************************************************************************
00005     *                                                                         *
00006     * If you are:                                                             *
00007     *                                                                         *
00008     *    + New to FreeRTOS,                                                   *
00009     *    + Wanting to learn FreeRTOS or multitasking in general quickly       *
00010     *    + Looking for basic training,                                        *
00011     *    + Wanting to improve your FreeRTOS skills and productivity           *
00012     *                                                                         *
00013     * then take a look at the FreeRTOS eBook                                  *
00014     *                                                                         *
00015     *        "Using the FreeRTOS Real Time Kernel - a Practical Guide"        *
00016     *                  http://www.FreeRTOS.org/Documentation                  *
00017     *                                                                         *
00018     * A pdf reference manual is also available.  Both are usually delivered   *
00019     * to your inbox within 20 minutes to two hours when purchased between 8am *
00020     * and 8pm GMT (although please allow up to 24 hours in case of            *
00021     * exceptional circumstances).  Thank you for your support!                *
00022     *                                                                         *
00023     ***************************************************************************
00024 
00025     This file is part of the FreeRTOS distribution.
00026 
00027     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.
00028     ***NOTE*** The exception to the GPL is included to allow you to distribute a combined work that includes FreeRTOS without being obliged to provide the
00029     source code for proprietary components outside of the FreeRTOS kernel.
00030     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
00031     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
00032     by writing to Richard Barry, contact details for whom are available on the FreeRTOS WEB site.
00033 
00034     1 tab == 4 spaces!
00035 
00036     http://www.FreeRTOS.org - Documentation, latest information, license and contact details.
00037 
00038     http://www.SafeRTOS.com - A version that is certified for use in safety critical systems.
00039 
00040     http://www.OpenRTOS.com - Commercial support, development, porting, licensing and training services.
00041 */
00042 
00043 //#error The batch file Demo\CORTEX_LPC1768_GCC_RedSuite\CreateProjectDirectoryStructure.bat must be executed before the first build.  After executing the batch file hit F5 to refrech the Eclipse project, then delete this line.
00044 
00045 /*
00046  * Creates all the demo application tasks, then starts the scheduler.  The WEB documentation provides more details of the standard demo application tasks
00047  * (which just exist to test the kernel port and provide an example of how to use each FreeRTOS API function).
00048  *
00049  * In addition to the standard demo tasks, the following tasks and tests are defined and/or created within this file:
00050  *
00051  * "Check" hook -  This only executes fully every five seconds from the tick hook.  Its main function is to check that all the standard demo tasks are
00052  * still operational.  The status can be viewed using on the Task Stats page served by the WEB server.
00053  *
00054  * "uIP" task -  This is the task that handles the uIP stack.  All TCP/IP processing is performed in this task.
00055  * 
00056  * "USB" task - Enumerates the USB device as a CDC class, then echoes back all received characters with a configurable offset (for example, if the offset
00057  * is 1 and 'A' is received then 'B' will be sent back).  A dumb terminal such as Hyperterminal can be used to talk to the USB task.
00058  */
00059 /*----------------------------------------------------------------------------------------------------------*/
00060 /*
00061  *  Modified for mbed IDE development environment
00062  *  By Kenji Arai / JH1PJL on October 28th,2010
00063  *      October 28th,2010
00064  */
00065 
00066 #include <stdio.h>
00067 
00068 #include "FreeRTOS.h"
00069 #include "task.h"
00070 
00071 #include "integer.h"
00072 #include "BlockQ.h"
00073 #include "blocktim.h"
00074 #include "flash.h"
00075 #include "partest.h"
00076 #include "semtest.h"
00077 #include "PollQ.h"
00078 #include "GenQTest.h"
00079 #include "QPeek.h"
00080 #include "queue.h"
00081 #include "recmutex.h"
00082 
00083 
00084 
00085 /* Task priorities. */
00086 #define mainQUEUE_POLL_PRIORITY                ( tskIDLE_PRIORITY + 2 )
00087 #define mainSEM_TEST_PRIORITY                ( tskIDLE_PRIORITY + 1 )
00088 #define mainBLOCK_Q_PRIORITY                ( tskIDLE_PRIORITY + 2 )
00089 #define mainUIP_TASK_PRIORITY                ( tskIDLE_PRIORITY + 3 )
00090 #define mainINTEGER_TASK_PRIORITY           ( tskIDLE_PRIORITY )
00091 #define mainGEN_QUEUE_TASK_PRIORITY            ( tskIDLE_PRIORITY )
00092 #define mainFLASH_TASK_PRIORITY                ( tskIDLE_PRIORITY + 2 )
00093 
00094 /* LED */
00095 #define LED1 0
00096 #define LED2 1
00097 #define LED3 2
00098 #define LED4 3
00099 
00100 // FLASH
00101 #define FLASH_SETUP           1
00102 #define FLASHCFG_Val          0x0000303A
00103 
00104 // Define clocks
00105 #define XTAL        (12000000UL)        /* Oscillator frequency               */
00106 #define OSC_CLK     (      XTAL)        /* Main oscillator frequency          */
00107 #define RTC_CLK     (   32000UL)        /* RTC oscillator frequency           */
00108 #define IRC_OSC     ( 4000000UL)        /* Internal RC oscillator frequency   */
00109 
00110 /*----------------------------------------------------------------------------------------------------------*/
00111 // Configure the hardware for mbed board
00112 static void prvSetupHardware( void );
00113 static void prvSetupSystem( void );
00114 
00115 //Control tasks for JH1PJL
00116 void vTask1( void *pvParameters );
00117 void vTask2( void *pvParameters );
00118 void vTask3( void *pvParameters );
00119 void vTask4( void *pvParameters );
00120 void vTask5( void *pvParameters );
00121 void vTask6( void *pvParameters );
00122 void vTask7( void *pvParameters );
00123 
00124 /*----------------------------------------------------------------------------------------------------------*/
00125 uint32_t SystemFrequency;    /*!< System Clock Frequency (Core Clock)  */
00126 
00127 unsigned portBASE_TYPE uxHiWtrMrk_tsk1, uxHiWtrMrk_tsk2;
00128 unsigned portBASE_TYPE uxHiWtrMrk_tsk3, uxHiWtrMrk_tsk4, uxHiWtrMrk_tsk5;
00129 unsigned portBASE_TYPE uxHiWtrMrk_tsk6, uxHiWtrMrk_tsk7;
00130 
00131 ////////////////////////////// Constant Data /////////////////////////////////////////////////////////////////
00132 /* ---------------------------< Copyright >---------------------------------------------------------------- */
00133 const uint8_t copyright[]    = "Arai,Kenji / JH1PJL(c)2010 kenjia@sannet.ne.jp "__DATE__" (" __TIME__ ")";
00134 #if ( USE_XPRESSO == 1 )
00135 /* ---------------------------< Board >---------------------------------------------------------------- */
00136 const uint8_t board[]        = "LPCXpresso LPC1768";
00137 /*----------------------------------------------------------------------------------------------------------*/
00138 #elif ( USE_MBED == 1 )
00139 /* ---------------------------< Board >---------------------------------------------------------------- */
00140 const uint8_t board[]        = "med LPC1768";
00141 #else
00142 /* ---------------------------< Board >---------------------------------------------------------------- */
00143 const uint8_t board[]        = "No identification";
00144 #endif
00145 
00146 int main( void ){
00147 //    char cIPAddress[ 16 ]; 
00148     /* Configure the hardware for mbed board */
00149     prvSetupHardware();
00150     prvSetupSystem();
00151 
00152     /* Start the standard demo tasks.  These are just here to exercise the kernel port and provide examples of how the FreeRTOS API can be used. */
00153     vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );
00154     vCreateBlockTimeTasks();
00155     vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );
00156     vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY );
00157     vStartIntegerMathTasks( mainINTEGER_TASK_PRIORITY );
00158     vStartGenericQueueTasks( mainGEN_QUEUE_TASK_PRIORITY );
00159     vStartQueuePeekTasks();
00160     vStartRecursiveMutexTasks();
00161 
00162     // ??? Task
00163     xTaskCreate( vTask1, ( signed char * ) "Task1", ( ( unsigned short ) 96 ), ( void * ) NULL, tskIDLE_PRIORITY, NULL );
00164     // ??? Task
00165     xTaskCreate( vTask2, ( signed char * ) "Task2", ( ( unsigned short ) 96 ), ( void * ) NULL, tskIDLE_PRIORITY, NULL );
00166     // ??? Task
00167     xTaskCreate( vTask3, ( signed char * ) "Task3", ( ( unsigned short ) 96 ), ( void * ) NULL, tskIDLE_PRIORITY, NULL );
00168     // ??? Task
00169     xTaskCreate( vTask4, ( signed char * ) "Task4", ( ( unsigned short ) 96 ), ( void * ) NULL, tskIDLE_PRIORITY, NULL );
00170     // ??? Task
00171     xTaskCreate( vTask5, ( signed char * ) "Task5", ( ( unsigned short ) 96 ), ( void * ) NULL, tskIDLE_PRIORITY, NULL );
00172     // ??? Task
00173     xTaskCreate( vTask6, ( signed char * ) "Task6", ( ( unsigned short ) 96 ), ( void * ) NULL, tskIDLE_PRIORITY, NULL );
00174     // ??? Task
00175     xTaskCreate( vTask7, ( signed char * ) "Task7", ( ( unsigned short ) 96 ), ( void * ) NULL, tskIDLE_PRIORITY, NULL );
00176 
00177     /* Start the scheduler. */
00178     vTaskStartScheduler();
00179 
00180     /* Will only get here if there was insufficient memory to create the idle task.  The idle task is created within vTaskStartScheduler(). */
00181     for( ;; );
00182 }
00183 /*----------------------------------------------------------------------------------------------------------*/
00184 
00185 /***** TASK #1 ******/
00186 // ????
00187 void vTask1 ( void *pvParameters ){
00188     portTickType xLastCheckTime;
00189     portTickType xDelayTime;
00190 
00191     xDelayTime = 125 / portTICK_RATE_MS;
00192     xLastCheckTime = xTaskGetTickCount();
00193     while(1){
00194         vTaskDelayUntil( &xLastCheckTime, xDelayTime );
00195         vParTestToggleLED( LED1 );
00196         uxHiWtrMrk_tsk1 = uxTaskGetStackHighWaterMark( NULL );
00197     }
00198 }
00199 /*----------------------------------------------------------------------------------------------------------*/
00200 
00201 /***** TASK #2 ******/
00202 // ???
00203 void vTask2 ( void *pvParameters ){
00204     portTickType xLastCheckTime;
00205     portTickType xDelayTime;
00206 
00207     xDelayTime = 250 / portTICK_RATE_MS;
00208     xLastCheckTime = xTaskGetTickCount();
00209     while(1){
00210         vTaskDelayUntil( &xLastCheckTime, xDelayTime );
00211         vParTestToggleLED( LED2 );
00212         uxHiWtrMrk_tsk2 = uxTaskGetStackHighWaterMark( NULL );
00213     }
00214 }
00215 /*----------------------------------------------------------------------------------------------------------*/
00216 
00217 /***** TASK #3 ******/
00218 // ???
00219 void vTask3 ( void *pvParameters ){
00220     portTickType xLastCheckTime;
00221     portTickType xDelayTime;
00222 
00223     xDelayTime = 500 / portTICK_RATE_MS;
00224     xLastCheckTime = xTaskGetTickCount();
00225     while(1){
00226         vTaskDelayUntil( &xLastCheckTime, xDelayTime );
00227         vParTestToggleLED( LED3 );
00228         uxHiWtrMrk_tsk2 = uxTaskGetStackHighWaterMark( NULL );
00229     }
00230 }
00231 /*----------------------------------------------------------------------------------------------------------*/
00232 
00233 /***** TASK #4 ******/
00234 // ???
00235 void vTask4(void *pvParameters) {
00236     portTickType xLastCheckTime;
00237     portTickType xDelayTime;
00238 
00239     xDelayTime = 1000 / portTICK_RATE_MS;
00240     xLastCheckTime = xTaskGetTickCount();
00241     while(1){
00242         vTaskDelayUntil( &xLastCheckTime, xDelayTime );
00243         vParTestToggleLED( LED4 );
00244         uxHiWtrMrk_tsk2 = uxTaskGetStackHighWaterMark( NULL );
00245     }
00246 }
00247 /*----------------------------------------------------------------------------------------------------------*/
00248 
00249 /***** TASK #5 ******/
00250 // ?????
00251 void vTask5 ( void *pvParameters ){
00252 
00253     vTaskDelay( 100 / portTICK_RATE_MS );            // Wait 0.1sec
00254     while(1){
00255         vTaskDelay( 10000 / portTICK_RATE_MS );        // Wait 10sec
00256         uxHiWtrMrk_tsk5 = uxTaskGetStackHighWaterMark( NULL );
00257     }
00258 }
00259 /*----------------------------------------------------------------------------------------------------------*/
00260 
00261 /***** TASK #6 ******/
00262 // ????
00263 void vTask6(void *pvParameters) {
00264     portTickType xLastCheckTime;
00265     portTickType xDelayTime;
00266 
00267     vTaskDelay(  200 / portTICK_RATE_MS );    // Wait
00268     xDelayTime = 25 / portTICK_RATE_MS;
00269     xLastCheckTime = xTaskGetTickCount();    // Need to initialize time prior to the first call to vTaskDelayUntil()
00270     while(1){
00271         vTaskDelayUntil( &xLastCheckTime, xDelayTime );
00272         uxHiWtrMrk_tsk6 = uxTaskGetStackHighWaterMark( NULL );
00273     }
00274 }
00275 
00276 /***** TASK #7******/
00277 // ????
00278 void vTask7(void *pvParameters) {
00279     portTickType xLastCheckTime;
00280     portTickType xDelayTime;
00281 
00282     xDelayTime = 10 / portTICK_RATE_MS;    // 10mS interval
00283     xLastCheckTime = xTaskGetTickCount();
00284     while(1){
00285         vTaskDelayUntil( &xLastCheckTime, xDelayTime );
00286         uxHiWtrMrk_tsk7 = uxTaskGetStackHighWaterMark( NULL );
00287     }
00288 }
00289 /*----------------------------------------------------------------------------------------------------------*/
00290 
00291 
00292 /*----------------------------------------------------------------------------------------------------------*/
00293 
00294 char *pcGetTaskStatusMessage( void ){
00295     /* Not bothered about a critical section here. */
00296     return 0;
00297 }
00298 /*----------------------------------------------------------------------------------------------------------*/
00299 
00300 void prvSetupSystem( void ){
00301     ;
00302 }
00303 /*----------------------------------------------------------------------------------------------------------*/
00304 
00305 void prvSetupHardware( void ){
00306     /* Disable peripherals power. */
00307     LPC_SC->PCONP = 0;
00308 
00309     /* Enable GPIO power. */
00310     LPC_SC->PCONP = PCONP_PCGPIO;
00311 
00312     /* Disable TPIU. */
00313     LPC_PINCON->PINSEL10 = 0;
00314 
00315     if ( LPC_SC->PLL0STAT & ( 1 << 25 ) ){
00316         /* Enable PLL, disconnected. */
00317         LPC_SC->PLL0CON = 1;
00318         LPC_SC->PLL0FEED = PLLFEED_FEED1;
00319         LPC_SC->PLL0FEED = PLLFEED_FEED2;
00320     }
00321     
00322     /* Disable PLL, disconnected. */
00323     LPC_SC->PLL0CON = 0;
00324     LPC_SC->PLL0FEED = PLLFEED_FEED1;
00325     LPC_SC->PLL0FEED = PLLFEED_FEED2;
00326         
00327     /* Enable main OSC. */
00328     LPC_SC->SCS |= 0x20;
00329     while( !( LPC_SC->SCS & 0x40 ) );
00330     
00331     /* select main OSC, 12MHz, as the PLL clock source. */
00332     LPC_SC->CLKSRCSEL = 0x1;
00333     
00334     LPC_SC->PLL0CFG = 0x20031;
00335     LPC_SC->PLL0FEED = PLLFEED_FEED1;
00336     LPC_SC->PLL0FEED = PLLFEED_FEED2;
00337           
00338     /* Enable PLL, disconnected. */
00339     LPC_SC->PLL0CON = 1;
00340     LPC_SC->PLL0FEED = PLLFEED_FEED1;
00341     LPC_SC->PLL0FEED = PLLFEED_FEED2;
00342     
00343     /* Set clock divider. */
00344     LPC_SC->CCLKCFG = 0x03;
00345     
00346     /* Configure flash accelerator. */
00347     LPC_SC->FLASHCFG = 0x403a;
00348     
00349     /* Check lock bit status. */
00350     while( ( ( LPC_SC->PLL0STAT & ( 1 << 26 ) ) == 0 ) );
00351         
00352     /* Enable and connect. */
00353     LPC_SC->PLL0CON = 3;
00354     LPC_SC->PLL0FEED = PLLFEED_FEED1;
00355     LPC_SC->PLL0FEED = PLLFEED_FEED2;
00356     while( ( ( LPC_SC->PLL0STAT & ( 1 << 25 ) ) == 0 ) );
00357     
00358     
00359     /* Configure the clock for the USB. */
00360       
00361     if( LPC_SC->PLL1STAT & ( 1 << 9 ) )
00362     {
00363         /* Enable PLL, disconnected. */
00364         LPC_SC->PLL1CON = 1;
00365         LPC_SC->PLL1FEED = PLLFEED_FEED1;
00366         LPC_SC->PLL1FEED = PLLFEED_FEED2;
00367     }
00368     
00369     /* Disable PLL, disconnected. */
00370     LPC_SC->PLL1CON = 0;
00371     LPC_SC->PLL1FEED = PLLFEED_FEED1;
00372     LPC_SC->PLL1FEED = PLLFEED_FEED2;
00373     
00374     LPC_SC->PLL1CFG = 0x23;
00375     LPC_SC->PLL1FEED = PLLFEED_FEED1;
00376     LPC_SC->PLL1FEED = PLLFEED_FEED2;
00377           
00378     /* Enable PLL, disconnected. */
00379     LPC_SC->PLL1CON = 1;
00380     LPC_SC->PLL1FEED = PLLFEED_FEED1;
00381     LPC_SC->PLL1FEED = PLLFEED_FEED2;
00382     while( ( ( LPC_SC->PLL1STAT & ( 1 << 10 ) ) == 0 ) );
00383     
00384     /* Enable and connect. */
00385     LPC_SC->PLL1CON = 3;
00386     LPC_SC->PLL1FEED = PLLFEED_FEED1;
00387     LPC_SC->PLL1FEED = PLLFEED_FEED2;
00388     while( ( ( LPC_SC->PLL1STAT & ( 1 << 9 ) ) == 0 ) );
00389 
00390     /*  Setup the peripheral bus to be the same as the PLL output (64 MHz). */
00391     LPC_SC->PCLKSEL0 = 0x05555555;
00392 
00393     /* Porting from system_LPC17xx.c void SystemInit()                            */
00394     /* Determine clock frequency according to clock register values             */
00395     if (((LPC_SC->PLL0STAT >> 24) & 3) == 3) {/* If PLL0 enabled and connected      */
00396         switch (LPC_SC->CLKSRCSEL & 0x03) {
00397             case 0:                           /* Internal RC oscillator => PLL0     */
00398             case 3:                           /* Reserved, default to Internal RC   */
00399                     SystemFrequency = (IRC_OSC *
00400                               (((2 * ((LPC_SC->PLL0STAT & 0x7FFF) + 1))) /
00401                               (((LPC_SC->PLL0STAT >> 16) & 0xFF) + 1))   /
00402                               ((LPC_SC->CCLKCFG & 0xFF)+ 1));
00403                     break;
00404             case 1:                           /* Main oscillator => PLL0            */
00405                     SystemFrequency = (OSC_CLK *
00406                               (((2 * ((LPC_SC->PLL0STAT & 0x7FFF) + 1))) /
00407                               (((LPC_SC->PLL0STAT >> 16) & 0xFF) + 1))   /
00408                               ((LPC_SC->CCLKCFG & 0xFF)+ 1));
00409                     break;
00410             case 2:                           /* RTC oscillator => PLL0             */
00411                     SystemFrequency = (RTC_CLK *
00412                               (((2 * ((LPC_SC->PLL0STAT & 0x7FFF) + 1))) /
00413                               (((LPC_SC->PLL0STAT >> 16) & 0xFF) + 1))   /
00414                               ((LPC_SC->CCLKCFG & 0xFF)+ 1));
00415                     break;
00416         }
00417     } else {
00418         switch (LPC_SC->CLKSRCSEL & 0x03) {
00419             case 0:                           /* Internal RC oscillator => PLL0     */
00420             case 3:                           /* Reserved, default to Internal RC   */
00421                     SystemFrequency = IRC_OSC / ((LPC_SC->CCLKCFG & 0xFF)+ 1);
00422                     break;
00423             case 1:                           /* Main oscillator => PLL0            */
00424                     SystemFrequency = OSC_CLK / ((LPC_SC->CCLKCFG & 0xFF)+ 1);
00425                     break;
00426             case 2:                           /* RTC oscillator => PLL0             */
00427                     SystemFrequency = RTC_CLK / ((LPC_SC->CCLKCFG & 0xFF)+ 1);
00428                     break;
00429         }
00430       }
00431 
00432     #if (FLASH_SETUP == 1)                  /* Flash Accelerator Setup            */
00433       LPC_SC->FLASHCFG  = FLASHCFG_Val;
00434     #endif
00435 
00436     /* Configure the LEDs. */
00437     vParTestInitialise();
00438 }
00439 
00440 /*----------------------------------------------------------------------------------------------------------*/
00441 
00442 void vConfigureTimerForRunTimeStats( void ){
00443     const unsigned long TCR_COUNT_RESET = 2, CTCR_CTM_TIMER = 0x00, TCR_COUNT_ENABLE = 0x01;
00444 
00445     /* This function configures a timer that is used as the time base when collecting run time
00446      *  statistical information - basically the percentage     of CPU time that each task is utilizing.
00447      *  It is called automatically when the scheduler is started
00448      *  (assuming configGENERATE_RUN_TIME_STATS is set to 1). */
00449 
00450     /* Power up and feed the timer. */
00451     LPC_SC->PCONP |= 0x02UL;
00452     LPC_SC->PCLKSEL0 = (LPC_SC->PCLKSEL0 & (~(0x3<<2))) | (0x01 << 2);
00453 
00454     /* Reset Timer 0 */
00455     LPC_TIM0->TCR = TCR_COUNT_RESET;
00456 
00457     /* Just count up. */
00458     LPC_TIM0->CTCR = CTCR_CTM_TIMER;
00459 
00460     /* Prescale to a frequency that is good enough to get a decent resolution,
00461     but not too fast so as to overflow all the time. */
00462     LPC_TIM0->PR =  ( configCPU_CLOCK_HZ / 10000UL ) - 1UL;
00463 
00464     /* Start the counter. */
00465     LPC_TIM0->TCR = TCR_COUNT_ENABLE;
00466 }
00467 /*----------------------------------------------------------------------------------------------------------*/
00468