]> git.sur5r.net Git - freertos/commitdiff
Comment and spell check the STM32L152 demo project.
authorrichardbarry <richardbarry@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Thu, 23 Dec 2010 17:04:34 +0000 (17:04 +0000)
committerrichardbarry <richardbarry@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Thu, 23 Dec 2010 17:04:34 +0000 (17:04 +0000)
git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@1184 1d2547de-c912-0410-9cb9-b8ca96c0e9e2

Demo/Cortex_STM32L152_IAR/ParTest.c
Demo/Cortex_STM32L152_IAR/main.c
Demo/Cortex_STM32L152_IAR/serial.c
Demo/Cortex_STM32L152_IAR/settings/RTOSDemo.dbgdt
Demo/Cortex_STM32L152_IAR/settings/RTOSDemo.dni
Demo/Cortex_STM32L152_IAR/settings/RTOSDemo.wsdt

index 3009d685e0ef8ffa66b9d25cd24452f871d5e5dc..53353d6c64c9ef25ebd458723e615e7d976f5fc1 100644 (file)
@@ -68,6 +68,8 @@
 \r
 void vParTestInitialise( void )\r
 {\r
+       /* Configure the output LEDs.   Note that JP18 and JP19 must be closed on\r
+       the Eval board for LED3 and LED4 to work. */\r
        STM_EVAL_LEDInit( LED1 );\r
        STM_EVAL_LEDInit( LED2 );\r
        STM_EVAL_LEDInit( LED3 );\r
index 8dbf6daba66c9e62f020cc1182c2b7177bfa65d4..a47d0ce284336534ff8c6096bc4f21322ba7a1f7 100644 (file)
     licensing and training services.\r
 */\r
 \r
+/*\r
+ * The documentation page for this demo available on http://www.FreeRTOS.org\r
+ * documents the hardware configuration required to run this demo.  It also\r
+ * provides more information on the expected demo application behaviour.\r
+ *\r
+ * main() creates all the demo application tasks, then starts the scheduler.\r
+ * A lot of the created tasks are from the pool of "standard demo" tasks.  The\r
+ * web documentation provides more details of the standard demo application\r
+ * tasks, which provide no particular functionality but do provide a good\r
+ * example of how to use the FreeRTOS API.\r
+ *\r
+ * In addition to the standard demo tasks, the following tasks, interrupts and\r
+ * tests are defined and/or created within this file:\r
+ *\r
+ * "LCD" task - The LCD task is a 'gatekeeper' task.  It is the only task that\r
+ * is permitted to access the LCD and therefore ensures access to the LCD is\r
+ * always serialised and there are no mutual exclusion issues.  When a task or\r
+ * an interrupt wants to write to the LCD, it does not access the LCD directly\r
+ * but instead sends the message to the LCD task.  The LCD task then performs\r
+ * the actual LCD output.  This mechanism also allows interrupts to, in effect,\r
+ * write to the LCD by sending messages to the LCD task.\r
+ *\r
+ * The LCD task is also a demonstration of a controller task design pattern.\r
+ * Some tasks do not actually send a string to the LCD task directly, but\r
+ * instead send a command that is interpreted by the LCD task.  In a normal\r
+ * application these commands can be control values or set points, in this\r
+ * simple example the commands just result in messages being displayed on the\r
+ * LCD.\r
+ *\r
+ * "Button Poll" task - This task polls the state of the 'up' key on the\r
+ * joystick input device.  It uses the vTaskDelay() API function to control\r
+ * the poll rate to ensure debouncing is not necessary and that the task does\r
+ * not use all the available CPU processing time.\r
+ *\r
+ * Button Interrupt and run time stats display - The select button on the\r
+ * joystick input device is configured to generate an external interrupt.  The\r
+ * handler for this interrupt sends a message to LCD task, which interprets the\r
+ * message to mean, firstly write a message to the LCD, and secondly, generate\r
+ * a table of run time statistics.  The run time statistics are displayed as a\r
+ * table that contains information on how much processing time each task has\r
+ * been allocated since the application started to execute.  This information\r
+ * is provided both as an absolute time, and as a percentage of the total run\r
+ * time.  The information is displayed in the terminal IO window of the IAR\r
+ * embedded workbench.  The online documentation for this demo shows a screen\r
+ * shot demonstrating where the run time stats can be viewed.\r
+ *\r
+ * Idle Hook - The idle hook is a function that is called on each iteration of\r
+ * the idle task.  In this case it is used to place the processor into a low\r
+ * power mode.  Note however that this application is implemented using standard\r
+ * components, and is therefore not optimised for low power operation.  Lower\r
+ * power consumption would be achieved by converting polling tasks into event\r
+ * driven tasks, and slowing the tick interrupt frequency.\r
+ *\r
+ * "Check" function called from the tick hook - The tick hook is called during\r
+ * each tick interrupt.  It is called from an interrupt context so must execute\r
+ * quickly, not attempt to block, and not call any FreeRTOS API functions that\r
+ * do not end in "FromISR".  In this case the tick hook executes a 'check'\r
+ * function.  This only executes every five seconds.  Its main function is to\r
+ * check that all the standard demo tasks are still operational.  Each time it\r
+ * executes it sends a status code to the LCD task.  The LCD task interprets the\r
+ * code and displays an appropriate message - which will be PASS if no tasks\r
+ * have reported any errors, or a message stating which task has reported an\r
+ * error.\r
+*/\r
+\r
 /* Standard includes. */\r
 #include <stdio.h>\r
 \r
 #include "comtest2.h"\r
 #include "GenQTest.h"\r
 \r
-/* ST driver includes. */\r
-#include "stm32l1xx_usart.h"\r
-\r
 /* Eval board includes. */\r
 #include "stm32_eval.h"\r
 #include "stm32l152_eval_lcd.h"\r
 \r
+/* The priorities assigned to the tasks. */\r
 #define mainFLASH_TASK_PRIORITY                        ( tskIDLE_PRIORITY + 1 )\r
 #define mainLCD_TASK_PRIORITY                  ( tskIDLE_PRIORITY + 1 )\r
 #define mainCOM_TEST_PRIORITY                  ( tskIDLE_PRIORITY + 2 )\r
 #define mainGENERIC_QUEUE_TEST_PRIORITY        ( tskIDLE_PRIORITY )\r
 \r
-#define mainLCD_TASK_STACK_SIZE                        ( configMINIMAL_STACK_SIZE * 2 )\r
-\r
+/* The length of the queue (the number of items the queue can hold) that is used\r
+to send messages from tasks and interrupts the the LCD task. */\r
 #define mainQUEUE_LENGTH                               ( 5 )\r
 \r
+/* Codes sent within message to the LCD task so the LCD task can interrupt\r
+exactly what the message it just received was.  These are sent in the\r
+cMessageID member of the message structure (defined below). */\r
 #define mainMESSAGE_BUTTON_UP                  ( 1 )\r
-#define mainMESSAGE_BUTTON_DOWN                        ( 2 )\r
-#define mainMESSAGE_BUTTON_LEFT                        ( 3 )\r
-#define mainMESSAGE_BUTTON_RIGHT               ( 4 )\r
-#define mainMESSAGE_BUTTON_SEL                 ( 5 )\r
-#define mainMESSAGE_STATUS                             ( 6 )\r
-\r
-#define mainERROR_DYNAMIC_TASKS                        ( 2 )\r
-#define mainERROR_COM_TEST                             ( 3 )\r
-#define mainERROR_GEN_QUEUE_TEST               ( 4 )\r
+#define mainMESSAGE_BUTTON_SEL                 ( 2 )\r
+#define mainMESSAGE_STATUS                             ( 3 )\r
+\r
+/* When cMessageID member of the message sent to the LCD task is\r
+mainMESSAGE_STATUS then these definitions are sent in the lMessageValue member\r
+of the same message to indicate what the status actually is.  The value 1 is not\r
+used as this is globally defined as pdPASS, and indicates that no errors have\r
+been reported (the system is running as expected). */\r
+#define mainERROR_DYNAMIC_TASKS                        ( pdPASS + 1 )\r
+#define mainERROR_COM_TEST                             ( pdPASS + 2 )\r
+#define mainERROR_GEN_QUEUE_TEST               ( pdPASS + 3 )\r
 \r
 /* Baud rate used by the comtest tasks. */\r
-#define mainCOM_TEST_BAUD_RATE         ( 9600 )\r
+#define mainCOM_TEST_BAUD_RATE         ( 115200 )\r
 \r
 /* The LED used by the comtest tasks. See the comtest.c file for more\r
 information. */\r
 #define mainCOM_TEST_LED                       ( 3 )\r
 \r
+/*-----------------------------------------------------------*/\r
 \r
 /*\r
  * System configuration is performed prior to main() being called, this function\r
  * configures the peripherals used by the demo application.\r
  */\r
 static void prvSetupHardware( void );\r
+\r
+/*\r
+ * Definition of the LCD/controller task described in the comments at the top\r
+ * of this file.\r
+ */\r
 static void prvLCDTask( void *pvParameters );\r
-static void vTempTask( void *pv );\r
+\r
+/*\r
+ * Definition of the button poll task described in the comments at the top of\r
+ * this file.\r
+ */\r
+static void vButtonPollTask( void *pvParameters );\r
+\r
+/*\r
+ * Converts a status message value into an appropriate string for display on\r
+ * the LCD.  The string is written to pcBuffer.\r
+ */\r
 static void prvGenerateStatusMessage( char *pcBuffer, long lStatusValue );\r
 \r
+/*-----------------------------------------------------------*/\r
+\r
+/* The time base for the run time stats is generated by the 16 bit timer 6.\r
+Each time the timer overflows ulTIM6_OverflowCount is incremented.  Therefore,\r
+when converting the total run time to a 32 bit number, the most significant two\r
+bytes are given by ulTIM6_OverflowCount and the least significant two bytes are\r
+given by the current TIM6 counter value.  Care must be taken with data\r
+consistency when combining the two in case a timer overflow occurs as the\r
+value is being read. */\r
 unsigned long ulTIM6_OverflowCount = 0UL;\r
 \r
+/* The handle of the queue used to send messages from tasks and interrupts to\r
+the LCD task. */\r
 static xQueueHandle xLCDQueue = NULL;\r
 \r
+/* The definition of each message sent from tasks and interrupts to the LCD\r
+task. */\r
 typedef struct\r
 {\r
-       char cMessageID;\r
-       long lMessageValue;\r
+       char cMessageID;        /* << States what the message is. */\r
+       long lMessageValue; /* << States the message value (can be an integer, string pointer, etc. depending on the value of cMessageID. */\r
 } xQueueMessage;\r
 \r
+/*-----------------------------------------------------------*/\r
+\r
 void main( void )\r
 {\r
+       /* Configure the peripherals used by this demo application.  This includes\r
+       configuring the joystick input select button to generate interrupts. */\r
        prvSetupHardware();\r
        \r
        /* Create the queue used by tasks and interrupts to send strings to the LCD\r
        task. */\r
        xLCDQueue = xQueueCreate( mainQUEUE_LENGTH, sizeof( xQueueMessage ) );\r
        \r
+       /* If the queue could not be created then don't create any tasks that might\r
+       attempt to use the queue. */\r
        if( xLCDQueue != NULL )\r
        {\r
+               /* Add the created queue to the queue registry so it can be viewed in\r
+               the IAR FreeRTOS state viewer plug-in. */\r
                vQueueAddToRegistry( xLCDQueue, "LCDQueue" );\r
-               xTaskCreate( prvLCDTask, ( signed char * ) "LCD", mainLCD_TASK_STACK_SIZE, NULL, mainLCD_TASK_PRIORITY, NULL );\r
-               xTaskCreate( vTempTask, ( signed char * ) "Temp", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );\r
+               \r
+               /* Create the LCD and button poll tasks, as described at the top of this\r
+               file. */\r
+               xTaskCreate( prvLCDTask, ( signed char * ) "LCD", configMINIMAL_STACK_SIZE, NULL, mainLCD_TASK_PRIORITY, NULL );\r
+               xTaskCreate( vButtonPollTask, ( signed char * ) "Temp", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );\r
+               \r
+               /* Create a subset of the standard demo tasks. */\r
                vStartDynamicPriorityTasks();\r
                vStartLEDFlashTasks( mainFLASH_TASK_PRIORITY );\r
                vAltStartComTestTasks( mainCOM_TEST_PRIORITY, mainCOM_TEST_BAUD_RATE, mainCOM_TEST_LED );\r
                vStartGenericQueueTasks( mainGENERIC_QUEUE_TEST_PRIORITY );\r
                \r
+               /* Start the scheduler. */\r
                vTaskStartScheduler();\r
        }\r
        \r
+       /* If all is well then this line will never be reached.  If it is reached\r
+       then it is likely that there was insufficient (FreeRTOS) heap memory space\r
+       to create the idle task.  This may have been trapped by the malloc() failed\r
+       hook function, if one is configured. */\r
        for( ;; );\r
 }\r
 /*-----------------------------------------------------------*/\r
@@ -150,49 +265,88 @@ static void prvLCDTask( void *pvParameters )
 xQueueMessage xReceivedMessage;\r
 long lLine = Line1;\r
 const long lFontHeight = (((sFONT *)LCD_GetFont())->Height);\r
+\r
+/* Buffer into which strings are formatted and placed ready for display on the\r
+LCD.  Note this is a static variable to prevent it being allocated on the task\r
+stack, which is too small to hold such a variable.  The stack size is configured\r
+when the task is created. */\r
 static char cBuffer[ 512 ];\r
 \r
        /* This function is the only function that uses printf().  If printf() is\r
        used from any other function then some sort of mutual exclusion on stdout\r
-       will be necessary. */\r
-\r
+       will be necessary.\r
+       \r
+       This is also the only function that is permitted to access the LCD.\r
+       \r
+       First print out the number of bytes that remain in the FreeRTOS heap.  This\r
+       can be viewed in the terminal IO window within the IAR Embedded Workbench. */\r
        printf( "%d bytes of heap space remain unallocated\n", xPortGetFreeHeapSize() );\r
 \r
        for( ;; )\r
        {\r
+               /* Wait for a message to be received.  This will wait indefinitely if\r
+               INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h, therefore there\r
+               is no need to check the function return value. */\r
                xQueueReceive( xLCDQueue, &xReceivedMessage, portMAX_DELAY );\r
 \r
+               /* Clear the LCD if the last LCD message was output to the last\r
+               available line on the LCD. */\r
                if( lLine > Line9 )\r
                {\r
                        LCD_Clear( Blue );\r
                        lLine = 0;\r
                }\r
                                \r
+               /* What is this message?  What does it contain? */\r
                switch( xReceivedMessage.cMessageID )\r
                {\r
-                       case mainMESSAGE_BUTTON_UP              :       sprintf( cBuffer, "Button up = %d", xReceivedMessage.lMessageValue );\r
-                                                                                               break;\r
-                       case mainMESSAGE_BUTTON_DOWN    :       sprintf( cBuffer, "Button down = %d", xReceivedMessage.lMessageValue );\r
-                                                                                               break;\r
-                       case mainMESSAGE_BUTTON_LEFT    :       sprintf( cBuffer, "Button left = %d", xReceivedMessage.lMessageValue );\r
-                                                                                               break;\r
-                       case mainMESSAGE_BUTTON_RIGHT   :       sprintf( cBuffer, "Button right = %d", xReceivedMessage.lMessageValue );\r
+                       case mainMESSAGE_BUTTON_UP              :       /* The button poll task has just\r
+                                                                                               informed this task that the up\r
+                                                                                               button on the joystick input has\r
+                                                                                               been pressed or released. */\r
+                                                                                               sprintf( cBuffer, "Button up = %d", xReceivedMessage.lMessageValue );\r
                                                                                                break;\r
-                       case mainMESSAGE_BUTTON_SEL             :       printf( "\nTask\t     Abs Time\t     %%Time\n*****************************************" );\r
+\r
+                       case mainMESSAGE_BUTTON_SEL             :       /* The select button interrupt\r
+                                                                                               just informed this task that the\r
+                                                                                               select button was pressed.\r
+                                                                                               Generate a table of task run time\r
+                                                                                               statistics and output this to\r
+                                                                                               the terminal IO window in the IAR\r
+                                                                                               embedded workbench. */\r
+                                                                                               printf( "\nTask\t     Abs Time\t     %%Time\n*****************************************" );\r
                                                                                                vTaskGetRunTimeStats( ( signed char * ) cBuffer );\r
                                                                                                printf( cBuffer );\r
                                                                                                \r
-                                                                                               /* The select button passes its\r
-                                                                                               own string to print out. */\r
+                                                                                               /* Also print out a message to\r
+                                                                                               the LCD - in this case the\r
+                                                                                               pointer to the string to print\r
+                                                                                               is sent directly in the\r
+                                                                                               lMessageValue member of the\r
+                                                                                               message.  This just demonstrates\r
+                                                                                               a different communication\r
+                                                                                               technique. */\r
                                                                                                sprintf( cBuffer, "%s", ( char * ) xReceivedMessage.lMessageValue );\r
                                                                                                break;\r
-                       case mainMESSAGE_STATUS                 :       prvGenerateStatusMessage( cBuffer, xReceivedMessage.lMessageValue );\r
+                                                                                               \r
+                       case mainMESSAGE_STATUS                 :       /* The tick interrupt hook\r
+                                                                                               function has just informed this\r
+                                                                                               task of the system status.\r
+                                                                                               Generate a string in accordance\r
+                                                                                               with the status value. */\r
+                                                                                               prvGenerateStatusMessage( cBuffer, xReceivedMessage.lMessageValue );\r
                                                                                                break;\r
+                                                                                               \r
                        default                                                 :       sprintf( cBuffer, "Unknown message" );\r
                                                                                                break;\r
                }\r
                \r
+               /* Output the message that was placed into the cBuffer array within the\r
+               switch statement above. */\r
                LCD_DisplayStringLine( lLine, ( uint8_t * ) cBuffer );\r
+               \r
+               /* Move onto the next LCD line, ready for the next iteration of this\r
+               loop. */\r
                lLine += lFontHeight;\r
        }\r
 }\r
@@ -200,13 +354,15 @@ static char cBuffer[ 512 ];
 \r
 static void prvGenerateStatusMessage( char *pcBuffer, long lStatusValue )\r
 {\r
+       /* Just a utility function to convert a status value into a meaningful\r
+       string for output onto the LCD. */\r
        switch( lStatusValue )\r
        {\r
                case pdPASS                                             :       sprintf( pcBuffer, "Task status = PASS" );\r
                                                                                        break;\r
                case mainERROR_DYNAMIC_TASKS    :       sprintf( pcBuffer, "Error: Dynamic tasks" );\r
                                                                                        break;\r
-               case mainERROR_COM_TEST                 :       sprintf( pcBuffer, "Error: COM test" );\r
+               case mainERROR_COM_TEST                 :       sprintf( pcBuffer, "Err: loop connected?" ); /* Error in COM test - is the Loopback connector connected? */                                                                                                             \r
                                                                                        break;\r
                case mainERROR_GEN_QUEUE_TEST   :       sprintf( pcBuffer, "Error: Gen Q test" );\r
                                                                                        break;\r
@@ -218,11 +374,21 @@ static void prvGenerateStatusMessage( char *pcBuffer, long lStatusValue )
 \r
 void EXTI9_5_IRQHandler( void )\r
 {\r
+/* Define the message sent to the LCD task from this interrupt. */\r
 const xQueueMessage xMessage = { mainMESSAGE_BUTTON_SEL, ( unsigned long ) "Select Interrupt!" };\r
 long lHigherPriorityTaskWoken = pdFALSE;\r
 \r
+       /* This is the interrupt handler for the joystick select button input.\r
+       The button has been pushed, write a message to the LCD via the LCD task. */\r
        xQueueSendFromISR( xLCDQueue, &xMessage, &lHigherPriorityTaskWoken );\r
+       \r
        EXTI_ClearITPendingBit( SEL_BUTTON_EXTI_LINE );\r
+       \r
+       /* If writing to xLCDQueue caused a task to unblock, and the unblocked task\r
+       has a priority equal to or above the task that this interrupt interrupted,\r
+       then lHigherPriorityTaskWoken will have been set to pdTRUE internally within\r
+       xQueuesendFromISR(), and portEND_SWITCHING_ISR() will ensure that this\r
+       interrupt returns directly to the higher priority unblocked task. */\r
        portEND_SWITCHING_ISR( lHigherPriorityTaskWoken );\r
 }\r
 /*-----------------------------------------------------------*/\r
@@ -231,12 +397,22 @@ void vApplicationTickHook( void )
 {\r
 static unsigned long ulCounter = 0;\r
 static const unsigned long ulCheckFrequency = 5000UL / portTICK_RATE_MS;\r
+long lHigherPriorityTaskWoken = pdFALSE;\r
+\r
+/* Define the status message that is sent to the LCD task.  By default the\r
+status is PASS. */\r
 static xQueueMessage xStatusMessage = { mainMESSAGE_STATUS, pdPASS };\r
-long lHigherPriorityTaskWoken = pdFALSE; /* Not used in this case as this is the tick hook. */\r
 \r
+       /* This is called from within the tick interrupt and performs the 'check'\r
+       functionality as described in the comments at the top of this file.\r
+\r
+       Is it time to perform the 'check' functionality again? */\r
        ulCounter++;\r
        if( ulCounter >= ulCheckFrequency )\r
        {\r
+               /* See if the standard demo tasks are executing as expected, changing\r
+               the message that is sent to the LCD task from PASS to an error code if\r
+               any tasks set reports an error. */\r
                if( xAreDynamicPriorityTasksStillRunning() != pdPASS )\r
                {\r
                        xStatusMessage.lMessageValue = mainERROR_DYNAMIC_TASKS;\r
@@ -252,35 +428,47 @@ long lHigherPriorityTaskWoken = pdFALSE; /* Not used in this case as this is the
                        xStatusMessage.lMessageValue = mainERROR_GEN_QUEUE_TEST;\r
                }\r
                \r
+               /* As this is the tick hook the lHigherPriorityTaskWoken parameter is not\r
+               needed (a context switch is going to be performed anyway), but it must\r
+               still be provided. */\r
                xQueueSendFromISR( xLCDQueue, &xStatusMessage, &lHigherPriorityTaskWoken );\r
                ulCounter = 0;\r
        }\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
-static void vTempTask( void *pv )\r
+static void vButtonPollTask( void *pvParameters )\r
 {\r
 long lLastState = pdTRUE;\r
 long lState;\r
 xQueueMessage xMessage;\r
 \r
+       /* This tasks performs the button polling functionality as described at the\r
+       top of this file. */\r
        for( ;; )\r
        {\r
+               /* Check the button state. */\r
                lState = STM_EVAL_PBGetState( BUTTON_UP );\r
                if( lState != lLastState )\r
                {\r
+                       /* The state has changed, send a message to the LCD task. */\r
                        xMessage.cMessageID = mainMESSAGE_BUTTON_UP;\r
                        xMessage.lMessageValue = lState;\r
                        lLastState = lState;\r
                        xQueueSend( xLCDQueue, &xMessage, portMAX_DELAY );\r
-                       vTaskDelay( 10 );\r
                }\r
+               \r
+               /* Block for 10 milliseconds so this task does not utilise all the CPU\r
+               time and debouncing of the button is not necessary. */\r
+               vTaskDelay( 10 / portTICK_RATE_MS );\r
        }\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
 static void prvSetupHardware( void )\r
 {\r
+       /* Ensure that all 4 interrupt priority bits are used as the pre-emption\r
+       priority. */\r
        NVIC_PriorityGroupConfig( NVIC_PriorityGroup_4 );\r
        \r
        /* Initialise the LEDs. */\r
@@ -294,19 +482,18 @@ static void prvSetupHardware( void )
        \r
        /* The select button in the middle of the joystick is configured to generate\r
        an interrupt.  The Eval board library will configure the interrupt\r
-       priority to be the lowest priority available - this is important as the\r
-       interrupt service routine makes use of a FreeRTOS API function so must\r
-       therefore use a priority equal to or below that set by the\r
-       configMAX_SYSCALL_INTERRUPT_PRIORITY() value set in FreeRTOSConfig.h. */\r
+       priority to be the lowest priority available so the priority need not be\r
+       set here explicitly.  It is important that the priority is equal to or\r
+       below that set by the configMAX_SYSCALL_INTERRUPT_PRIORITY value set in\r
+       FreeRTOSConfig.h. */\r
        STM_EVAL_PBInit( BUTTON_SEL, BUTTON_MODE_EXTI );\r
 \r
        /* Initialize the LCD */\r
-       STM32L152_LCD_Init();\r
-       \r
-       LCD_Clear(Blue);\r
-       LCD_SetBackColor(Blue);\r
-       LCD_SetTextColor(White);\r
-       LCD_DisplayStringLine(Line0, "  www.FreeRTOS.org");\r
+       STM32L152_LCD_Init();   \r
+       LCD_Clear( Blue );\r
+       LCD_SetBackColor( Blue );\r
+       LCD_SetTextColor( White );\r
+       LCD_DisplayStringLine( Line0, "  www.FreeRTOS.org" );\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
@@ -315,6 +502,18 @@ void vConfigureTimerForRunTimeStats( void )
 TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;\r
 NVIC_InitTypeDef NVIC_InitStructure;\r
 \r
+       /* The time base for the run time stats is generated by the 16 bit timer 6.\r
+       Each time the timer overflows ulTIM6_OverflowCount is incremented.\r
+       Therefore, when converting the total run time to a 32 bit number, the most\r
+       significant two bytes are given by ulTIM6_OverflowCount and the least\r
+       significant two bytes are given by the current TIM6 counter value.  Care\r
+       must be taken with data consistency when combining the two in case a timer\r
+       overflow occurs as the value is being read.\r
+       \r
+       The portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() macro (in FreeRTOSConfig.h) is\r
+       defined to call this function, so the kernel will call this function\r
+       automatically at the appropriate time. */\r
+\r
        /* TIM6 clock enable */\r
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE);\r
 \r
@@ -330,22 +529,32 @@ NVIC_InitTypeDef NVIC_InitStructure;
        /* Only interrupt on overflow events. */\r
        TIM6->CR1 |= TIM_CR1_URS;\r
        \r
+       /* Enable the interrupt. */\r
        TIM_ITConfig( TIM6, TIM_IT_Update, ENABLE );\r
        \r
-       /* Enable the TIM6 gloabal Interrupt */\r
+       /* Enable the TIM6 global Interrupt */\r
        NVIC_InitStructure.NVIC_IRQChannel = TIM6_IRQn;\r
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = configLIBRARY_LOWEST_INTERRUPT_PRIORITY;\r
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00; /* Not used as 4 bits are used for the pre-emption priority. */\r
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;\r
+       NVIC_Init(&NVIC_InitStructure);\r
        \r
        TIM_ClearITPendingBit( TIM6, TIM_IT_Update );\r
-       NVIC_Init(&NVIC_InitStructure);\r
        TIM_Cmd( TIM6, ENABLE );\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
 void TIM6_IRQHandler( void )\r
 {\r
+       /* Interrupt handler for TIM 6\r
+       \r
+       The time base for the run time stats is generated by the 16 bit timer 6.\r
+       Each time the timer overflows ulTIM6_OverflowCount is incremented.\r
+       Therefore, when converting the total run time to a 32 bit number, the most\r
+       significant two bytes are given by ulTIM6_OverflowCount and the least\r
+       significant two bytes are given by the current TIM6 counter value.  Care\r
+       must be taken with data consistency when combining the two in case a timer\r
+       overflow occurs as the value is being read. */\r
        if( TIM_GetITStatus( TIM6, TIM_IT_Update) != RESET)\r
        {\r
                ulTIM6_OverflowCount++;\r
@@ -359,18 +568,27 @@ void vApplicationStackOverflowHook( xTaskHandle *pxTask, signed char *pcTaskName
        ( void ) pcTaskName;\r
        ( void ) pxTask;\r
        \r
+       /* Run time stack overflow checking is performed if\r
+       configconfigCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2.  This hook\r
+       function is called if a stack overflow is detected. */\r
        for( ;; );\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
 void vApplicationMallocFailedHook( void )\r
 {\r
+       /* Called if a call to pvPortMalloc() fails because there is insufficient\r
+       free memory available in the FreeRTOS heap.  pvPortMalloc() is called\r
+       internally by FreeRTOS API functions that create tasks, queues or\r
+       semaphores. */\r
        for( ;; );\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
 void vApplicationIdleHook( void )\r
 {\r
+       /* Called on each itteration of the idle task.  In this case the idle task\r
+       just enters a low(ish) power mode. */\r
        PWR_EnterSleepMode( PWR_Regulator_ON, PWR_SLEEPEntry_WFI );\r
 }\r
 \r
index fd3a15094b1fa64d7e204f6820817c05ddd85f7f..0668d49d137be384859f2ec7d25427997a738902 100644 (file)
 \r
 /*\r
        BASIC INTERRUPT DRIVEN SERIAL PORT DRIVER FOR UART0.\r
+       \r
+       ***Note*** This example uses queues to send each character into an interrupt\r
+       service routine and out of an interrupt service routine individually.  This\r
+       is done to demonstrate queues being used in an interrupt, and to deliberately\r
+       load the system to test the FreeRTOS port.  It is *NOT* meant to be an \r
+       example of an efficient implementation.  An efficient implementation should\r
+       use FIFO's or DMA if available, and only use FreeRTOS API functions when \r
+       enough has been received to warrant a task being unblocked to process the\r
+       data.\r
 */\r
 \r
 /* Scheduler includes. */\r
@@ -71,7 +80,6 @@
 /* Misc defines. */\r
 #define serINVALID_QUEUE                               ( ( xQueueHandle ) 0 )\r
 #define serNO_BLOCK                                            ( ( portTickType ) 0 )\r
-#define serTX_BLOCK_TIME                               ( 40 / portTICK_RATE_MS )\r
 \r
 /*-----------------------------------------------------------*/\r
 \r
@@ -94,7 +102,7 @@ NVIC_InitTypeDef NVIC_InitStructure;
        xRxedChars = xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE ) sizeof( signed portCHAR ) );\r
        xCharsForTx = xQueueCreate( uxQueueLength + 1, ( unsigned portBASE_TYPE ) sizeof( signed portCHAR ) );\r
        \r
-       /* If the queue/semaphore was created correctly then setup the serial port\r
+       /* If the queues were created correctly then setup the serial port\r
        hardware. */\r
        if( ( xRxedChars != serINVALID_QUEUE ) && ( xCharsForTx != serINVALID_QUEUE ) )\r
        {\r
@@ -200,12 +208,12 @@ portCHAR cChar;
 \r
        if( USART_GetITStatus( USART3, USART_IT_TXE ) == SET )\r
        {\r
-               /* The interrupt was caused by the THR becoming empty.  Are there any\r
-               more characters to transmit? */\r
+               /* The interrupt was caused by the TX register becoming empty.  Are \r
+               there any more characters to transmit? */\r
                if( xQueueReceiveFromISR( xCharsForTx, &cChar, &xHigherPriorityTaskWoken ) == pdTRUE )\r
                {\r
                        /* A character was retrieved from the queue so can be sent to the\r
-                       THR now. */\r
+                       USART now. */\r
                        USART_SendData( USART3, cChar );\r
                }\r
                else\r
@@ -216,10 +224,18 @@ portCHAR cChar;
        \r
        if( USART_GetITStatus( USART3, USART_IT_RXNE ) == SET )\r
        {\r
+               /* A character has been received on the USART, send it to the Rx\r
+               handler task. */\r
                cChar = USART_ReceiveData( USART3 );\r
                xQueueSendFromISR( xRxedChars, &cChar, &xHigherPriorityTaskWoken );\r
        }       \r
 \r
+       /* If sending or receiving from a queue has caused a task to unblock, and\r
+       the unblocked task has a priority equal to or higher than the currently \r
+       running task (the task this ISR interrupted), then xHigherPriorityTaskWoken \r
+       will have automatically been set to pdTRUE within the queue send or receive \r
+       function.  portEND_SWITCHING_ISR() will then ensure that this ISR returns \r
+       directly to the higher priority unblocked task. */\r
        portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );\r
 }\r
 \r
index f3fbd8620e1040d776bce8fe8c024516aed38270..be0489899bf5a53714434d5dcf481546a4f4eaca 100644 (file)
@@ -19,7 +19,7 @@
           \r
           \r
           \r
-        <Column0>279</Column0><Column1>27</Column1><Column2>27</Column2><Column3>27</Column3></ColumnWidths>\r
+        <Column0>295</Column0><Column1>27</Column1><Column2>27</Column2><Column3>27</Column3></ColumnWidths>\r
       </Workspace>\r
       <Disassembly>\r
         <PreferedWindows>\r
@@ -36,7 +36,7 @@
     <Windows>\r
       \r
       \r
-    <Wnd3>\r
+    <Wnd0>\r
         <Tabs>\r
           <Tab>\r
             <Identity>TabID-15530-21362</Identity>\r
             <Factory>Workspace</Factory>\r
             <Session>\r
               \r
-            <NodeDict><ExpandedNode>RTOSDemo</ExpandedNode><ExpandedNode>RTOSDemo/FreeRTOS_Source</ExpandedNode><ExpandedNode>RTOSDemo/FreeRTOS_Source/Portable</ExpandedNode><ExpandedNode>RTOSDemo/System_and_ST_Code</ExpandedNode><ExpandedNode>RTOSDemo/System_and_ST_Code/Eval_Board_Library</ExpandedNode><ExpandedNode>RTOSDemo/System_and_ST_Code/Peripheral_Library</ExpandedNode><ExpandedNode>RTOSDemo/System_and_ST_Code/Peripheral_Library/misc.c</ExpandedNode></NodeDict></Session>\r
+            <NodeDict><ExpandedNode>RTOSDemo</ExpandedNode><ExpandedNode>RTOSDemo/FreeRTOS_Source</ExpandedNode><ExpandedNode>RTOSDemo/FreeRTOS_Source/Portable</ExpandedNode></NodeDict></Session>\r
           </Tab>\r
         </Tabs>\r
         \r
-      <SelectedTab>0</SelectedTab></Wnd3><Wnd5><Tabs><Tab><Identity>TabID-10464-23570</Identity><TabName>Tasks</TabName><Factory>TASKVIEW</Factory><Session/></Tab></Tabs><SelectedTab>0</SelectedTab></Wnd5><Wnd6><Tabs><Tab><Identity>TabID-31438-23586</Identity><TabName>Queues</TabName><Factory>QUEUEVIEW</Factory><Session/></Tab></Tabs><SelectedTab>0</SelectedTab></Wnd6><Wnd7><Tabs><Tab><Identity>TabID-15541-875</Identity><TabName>Terminal I/O</TabName><Factory>TerminalIO</Factory><Session/></Tab></Tabs><SelectedTab>0</SelectedTab></Wnd7></Windows>\r
+      <SelectedTab>0</SelectedTab></Wnd0><Wnd1><Tabs><Tab><Identity>TabID-10464-23570</Identity><TabName>Tasks</TabName><Factory>TASKVIEW</Factory><Session/></Tab></Tabs><SelectedTab>0</SelectedTab></Wnd1><Wnd2><Tabs><Tab><Identity>TabID-31438-23586</Identity><TabName>Queues</TabName><Factory>QUEUEVIEW</Factory><Session/></Tab></Tabs><SelectedTab>0</SelectedTab></Wnd2><Wnd3><Tabs><Tab><Identity>TabID-15541-875</Identity><TabName>Terminal I/O</TabName><Factory>TerminalIO</Factory><Session/></Tab></Tabs><SelectedTab>0</SelectedTab></Wnd3></Windows>\r
     <Editor>\r
       \r
       \r
       \r
       \r
-    <Pane><Tab><Factory>TextEditor</Factory><Filename>$WS_DIR$\main.c</Filename><XPos>0</XPos><YPos>116</YPos><SelStart>4884</SelStart><SelEnd>4884</SelEnd></Tab><ActiveTab>0</ActiveTab><Tab><Factory>TextEditor</Factory><Filename>$WS_DIR$\..\Common\Minimal\GenQTest.c</Filename><XPos>0</XPos><YPos>531</YPos><SelStart>18205</SelStart><SelEnd>18238</SelEnd></Tab><Tab><Factory>TextEditor</Factory><Filename>$WS_DIR$\FreeRTOSConfig.h</Filename><XPos>0</XPos><YPos>61</YPos><SelStart>4359</SelStart><SelEnd>4359</SelEnd></Tab><Tab><Factory>TextEditor</Factory><Filename>$WS_DIR$\..\..\Source\portable\MemMang\heap_2.c</Filename><XPos>0</XPos><YPos>212</YPos><SelStart>9775</SelStart><SelEnd>9817</SelEnd></Tab><Tab><Factory>TextEditor</Factory><Filename>$WS_DIR$\..\..\Source\portable\IAR\ARM_CM3\port.c</Filename><XPos>0</XPos><YPos>161</YPos><SelStart>7094</SelStart><SelEnd>7094</SelEnd></Tab><Tab><Factory>TextEditor</Factory><Filename>$WS_DIR$\system_and_ST_code\stm32l1xx_it.c</Filename><XPos>0</XPos><YPos>45</YPos><SelStart>2244</SelStart><SelEnd>2244</SelEnd></Tab><Tab><Factory>TextEditor</Factory><Filename>$WS_DIR$\..\..\Source\portable\IAR\ARM_CM3\portasm.s</Filename><XPos>0</XPos><YPos>100</YPos><SelStart>4567</SelStart><SelEnd>4567</SelEnd></Tab></Pane><ActivePane>0</ActivePane><Sizes><Pane><X>1000000</X><Y>1000000</Y></Pane></Sizes><SplitMode>1</SplitMode></Editor>\r
+    <Pane><Tab><Factory>TextEditor</Factory><Filename>$WS_DIR$\system_and_ST_code\STM32L152_EVAL\stm32l152_eval.c</Filename><XPos>0</XPos><YPos>311</YPos><SelStart>11626</SelStart><SelEnd>11626</SelEnd></Tab><Tab><Factory>TextEditor</Factory><Filename>$WS_DIR$\system_and_ST_code\STM32L1xx_StdPeriph_Driver\src\stm32l1xx_gpio.c</Filename><XPos>0</XPos><YPos>203</YPos><SelStart>6070</SelStart><SelEnd>6070</SelEnd></Tab><Tab><Factory>TextEditor</Factory><Filename>$WS_DIR$\serial.c</Filename><XPos>0</XPos><YPos>0</YPos><SelStart>0</SelStart><SelEnd>0</SelEnd></Tab><Tab><Factory>TextEditor</Factory><Filename>$WS_DIR$\FreeRTOSConfig.h</Filename><XPos>0</XPos><YPos>59</YPos><SelStart>4250</SelStart><SelEnd>4280</SelEnd></Tab><Tab><Factory>TextEditor</Factory><Filename>$WS_DIR$\main.c</Filename><XPos>0</XPos><YPos>215</YPos><SelStart>10723</SelStart><SelEnd>10723</SelEnd></Tab><ActiveTab>4</ActiveTab><Tab><Factory>TextEditor</Factory><Filename>$WS_DIR$\..\..\Source\portable\IAR\ARM_CM3\port.c</Filename><XPos>0</XPos><YPos>160</YPos><SelStart>6950</SelStart><SelEnd>6950</SelEnd></Tab></Pane><ActivePane>0</ActivePane><Sizes><Pane><X>1000000</X><Y>1000000</Y></Pane></Sizes><SplitMode>1</SplitMode></Editor>\r
     <Positions>\r
       \r
       \r
       \r
       \r
       \r
-    <Top><Row0><Sizes><Toolbar-012aae60><key>iaridepm.enu1</key></Toolbar-012aae60><Toolbar-0cd13160><key>debuggergui.enu1</key></Toolbar-0cd13160></Sizes></Row0><Row1><Sizes><Toolbar-071cab80><key>armjlink.enu1</key></Toolbar-071cab80></Sizes></Row1></Top><Left><Row0><Sizes><Wnd3><Rect><Top>-2</Top><Left>-2</Left><Bottom>465</Bottom><Right>369</Right><x>-2</x><y>-2</y><xscreen>200</xscreen><yscreen>200</yscreen><sizeHorzCX>119048</sizeHorzCX><sizeHorzCY>203666</sizeHorzCY><sizeVertCX>220833</sizeVertCX><sizeVertCY>475560</sizeVertCY></Rect></Wnd3></Sizes></Row0></Left><Right><Row0><Sizes><Wnd7><Rect><Top>-2</Top><Left>-2</Left><Bottom>465</Bottom><Right>435</Right><x>-2</x><y>-2</y><xscreen>200</xscreen><yscreen>200</yscreen><sizeHorzCX>119048</sizeHorzCX><sizeHorzCY>203666</sizeHorzCY><sizeVertCX>260119</sizeVertCX><sizeVertCY>475560</sizeVertCY></Rect></Wnd7></Sizes></Row0></Right><Bottom><Row0><Sizes><Wnd5><Rect><Top>-2</Top><Left>-2</Left><Bottom>338</Bottom><Right>1682</Right><x>-2</x><y>-2</y><xscreen>1684</xscreen><yscreen>340</yscreen><sizeHorzCX>1002381</sizeHorzCX><sizeHorzCY>346232</sizeHorzCY><sizeVertCX>119048</sizeVertCX><sizeVertCY>203666</sizeVertCY></Rect></Wnd5></Sizes></Row0><Row1><Sizes><Wnd6><Rect><Top>336</Top><Left>-2</Left><Bottom>449</Bottom><Right>1682</Right><x>-2</x><y>336</y><xscreen>1684</xscreen><yscreen>113</yscreen><sizeHorzCX>1002381</sizeHorzCX><sizeHorzCY>115071</sizeHorzCY><sizeVertCX>119048</sizeVertCX><sizeVertCY>203666</sizeVertCY></Rect></Wnd6></Sizes></Row1></Bottom><Float><Sizes/></Float></Positions>\r
+    <Top><Row0><Sizes><Toolbar-012aae60><key>iaridepm.enu1</key></Toolbar-012aae60><Toolbar-06bb03e0><key>debuggergui.enu1</key></Toolbar-06bb03e0></Sizes></Row0><Row1><Sizes><Toolbar-06a867a0><key>armjlink.enu1</key></Toolbar-06a867a0></Sizes></Row1></Top><Left><Row0><Sizes><Wnd0><Rect><Top>-2</Top><Left>-2</Left><Bottom>465</Bottom><Right>369</Right><x>-2</x><y>-2</y><xscreen>200</xscreen><yscreen>200</yscreen><sizeHorzCX>119048</sizeHorzCX><sizeHorzCY>203666</sizeHorzCY><sizeVertCX>220833</sizeVertCX><sizeVertCY>475560</sizeVertCY></Rect></Wnd0></Sizes></Row0></Left><Right><Row0><Sizes><Wnd3><Rect><Top>-2</Top><Left>-2</Left><Bottom>465</Bottom><Right>435</Right><x>-2</x><y>-2</y><xscreen>200</xscreen><yscreen>200</yscreen><sizeHorzCX>119048</sizeHorzCX><sizeHorzCY>203666</sizeHorzCY><sizeVertCX>260119</sizeVertCX><sizeVertCY>475560</sizeVertCY></Rect></Wnd3></Sizes></Row0></Right><Bottom><Row0><Sizes><Wnd1><Rect><Top>-2</Top><Left>-2</Left><Bottom>338</Bottom><Right>1682</Right><x>-2</x><y>-2</y><xscreen>1684</xscreen><yscreen>340</yscreen><sizeHorzCX>1002381</sizeHorzCX><sizeHorzCY>346232</sizeHorzCY><sizeVertCX>119048</sizeVertCX><sizeVertCY>203666</sizeVertCY></Rect></Wnd1></Sizes></Row0><Row1><Sizes><Wnd2><Rect><Top>336</Top><Left>-2</Left><Bottom>449</Bottom><Right>1682</Right><x>-2</x><y>336</y><xscreen>1684</xscreen><yscreen>113</yscreen><sizeHorzCX>1002381</sizeHorzCX><sizeHorzCY>115071</sizeHorzCY><sizeVertCX>119048</sizeVertCX><sizeVertCY>203666</sizeVertCY></Rect></Wnd2></Sizes></Row1></Bottom><Float><Sizes/></Float></Positions>\r
   </Desktop>\r
 </Project>\r
 \r
index fab1365c8f9f04418cd89dcdec693d3751092703..f310663e684f32413bccb30fb104d767a23dbc87 100644 (file)
@@ -1,5 +1,5 @@
 [DebugChecksum]\r
-Checksum=818382432\r
+Checksum=2056793833\r
 [DisAssemblyWindow]\r
 NumStates=_ 1\r
 State 1=_ 1\r
@@ -70,10 +70,6 @@ ShowTimeLog=1
 ShowTimeSum=0\r
 Title0=Power [mA]\r
 Setup0=0 1 0 500 2 0 4 1 0\r
-[Disassemble mode]\r
-mode=0\r
-[Breakpoints]\r
-Count=0\r
 [Log file]\r
 LoggingEnabled=_ 0\r
 LogFile=_ ""\r
@@ -81,9 +77,6 @@ Category=_ 0
 [TermIOLog]\r
 LoggingEnabled=_ 0\r
 LogFile=_ ""\r
-[Aliases]\r
-Count=0\r
-SuppressDialog=0\r
 [SWOTraceWindow]\r
 PcSampling=0\r
 InterruptLogs=0\r
@@ -103,3 +96,10 @@ Enabled=0
 Mode=3\r
 Graph=0\r
 Symbiont=0\r
+[Disassemble mode]\r
+mode=0\r
+[Breakpoints]\r
+Count=0\r
+[Aliases]\r
+Count=0\r
+SuppressDialog=0\r
index 0b5da45aba14d506fc72c89787261afe5f1e3366..097c38fb6c23a0063a4670d8046153990e36b374 100644 (file)
@@ -17,7 +17,7 @@
     <Build><ColumnWidth0>20</ColumnWidth0><ColumnWidth1>1216</ColumnWidth1><ColumnWidth2>324</ColumnWidth2><ColumnWidth3>81</ColumnWidth3></Build><TerminalIO/><Debug-Log><ColumnWidth0>20</ColumnWidth0><ColumnWidth1>1622</ColumnWidth1></Debug-Log></Static>\r
     <Windows>\r
       \r
-    <Wnd0>\r
+    <Wnd2>\r
         <Tabs>\r
           <Tab>\r
             <Identity>TabID-27630-4718</Identity>\r
             <Factory>Workspace</Factory>\r
             <Session>\r
               \r
-            <NodeDict><ExpandedNode>RTOSDemo</ExpandedNode><ExpandedNode>RTOSDemo/FreeRTOS_Source</ExpandedNode><ExpandedNode>RTOSDemo/FreeRTOS_Source/Portable</ExpandedNode><ExpandedNode>RTOSDemo/Standard_Demo_Code</ExpandedNode><ExpandedNode>RTOSDemo/System_and_ST_Code</ExpandedNode><ExpandedNode>RTOSDemo/System_and_ST_Code/Peripheral_Library</ExpandedNode><ExpandedNode>RTOSDemo/System_and_ST_Code/Peripheral_Library/stm32l1xx_pwr.c</ExpandedNode></NodeDict></Session>\r
+            <NodeDict><ExpandedNode>RTOSDemo</ExpandedNode><ExpandedNode>RTOSDemo/FreeRTOS_Source</ExpandedNode><ExpandedNode>RTOSDemo/FreeRTOS_Source/Portable</ExpandedNode><ExpandedNode>RTOSDemo/Standard_Demo_Code</ExpandedNode><ExpandedNode>RTOSDemo/System_and_ST_Code</ExpandedNode><ExpandedNode>RTOSDemo/System_and_ST_Code/Peripheral_Library</ExpandedNode><ExpandedNode>RTOSDemo/System_and_ST_Code/Peripheral_Library/stm32l1xx_pwr.c</ExpandedNode><ExpandedNode>RTOSDemo/main.c</ExpandedNode></NodeDict></Session>\r
           </Tab>\r
         </Tabs>\r
         \r
-      <SelectedTab>0</SelectedTab></Wnd0><Wnd1><Tabs><Tab><Identity>TabID-10002-7709</Identity><TabName>Build</TabName><Factory>Build</Factory><Session/></Tab><Tab><Identity>TabID-18437-21512</Identity><TabName>Debug Log</TabName><Factory>Debug-Log</Factory><Session/></Tab></Tabs><SelectedTab>0</SelectedTab></Wnd1></Windows>\r
+      <SelectedTab>0</SelectedTab></Wnd2><Wnd3><Tabs><Tab><Identity>TabID-10002-7709</Identity><TabName>Build</TabName><Factory>Build</Factory><Session/></Tab><Tab><Identity>TabID-18437-21512</Identity><TabName>Debug Log</TabName><Factory>Debug-Log</Factory><Session/></Tab></Tabs><SelectedTab>0</SelectedTab></Wnd3></Windows>\r
     <Editor>\r
       \r
       \r
       \r
       \r
-    <Pane><Tab><Factory>TextEditor</Factory><Filename>$WS_DIR$\main.c</Filename><XPos>0</XPos><YPos>336</YPos><SelStart>13045</SelStart><SelEnd>13045</SelEnd></Tab><Tab><Factory>TextEditor</Factory><Filename>$WS_DIR$\..\Common\Minimal\GenQTest.c</Filename><XPos>0</XPos><YPos>531</YPos><SelStart>18205</SelStart><SelEnd>18238</SelEnd></Tab><Tab><Factory>TextEditor</Factory><Filename>$WS_DIR$\FreeRTOSConfig.h</Filename><XPos>0</XPos><YPos>61</YPos><SelStart>3665</SelStart><SelEnd>3665</SelEnd></Tab><Tab><Factory>TextEditor</Factory><Filename>$WS_DIR$\..\..\Source\portable\MemMang\heap_2.c</Filename><XPos>0</XPos><YPos>212</YPos><SelStart>9775</SelStart><SelEnd>9817</SelEnd></Tab><Tab><Factory>TextEditor</Factory><Filename>$WS_DIR$\..\..\Source\portable\IAR\ARM_CM3\port.c</Filename><XPos>0</XPos><YPos>161</YPos><SelStart>7094</SelStart><SelEnd>7094</SelEnd></Tab><Tab><Factory>TextEditor</Factory><Filename>$WS_DIR$\system_and_ST_code\stm32l1xx_it.c</Filename><XPos>0</XPos><YPos>45</YPos><SelStart>2244</SelStart><SelEnd>2244</SelEnd></Tab><Tab><Factory>TextEditor</Factory><Filename>$WS_DIR$\..\..\Source\portable\IAR\ARM_CM3\portasm.s</Filename><XPos>0</XPos><YPos>100</YPos><SelStart>4567</SelStart><SelEnd>4567</SelEnd></Tab><Tab><Factory>TextEditor</Factory><Filename>$WS_DIR$\system_and_ST_code\STM32L1xx_StdPeriph_Driver\src\stm32l1xx_pwr.c</Filename><XPos>0</XPos><YPos>389</YPos><SelStart>8212</SelStart><SelEnd>8230</SelEnd></Tab><Tab><Factory>TextEditor</Factory><Filename>$WS_DIR$\system_and_ST_code\stm32l1xx_conf.h</Filename><XPos>0</XPos><YPos>0</YPos><SelStart>1632</SelStart><SelEnd>1632</SelEnd></Tab><ActiveTab>8</ActiveTab></Pane><ActivePane>0</ActivePane><Sizes><Pane><X>1000000</X><Y>1000000</Y></Pane></Sizes><SplitMode>1</SplitMode></Editor>\r
+    <Pane><Tab><Factory>TextEditor</Factory><Filename>$WS_DIR$\system_and_ST_code\STM32L152_EVAL\stm32l152_eval.c</Filename><XPos>0</XPos><YPos>311</YPos><SelStart>11626</SelStart><SelEnd>11626</SelEnd></Tab><Tab><Factory>TextEditor</Factory><Filename>$WS_DIR$\system_and_ST_code\STM32L1xx_StdPeriph_Driver\src\stm32l1xx_gpio.c</Filename><XPos>0</XPos><YPos>203</YPos><SelStart>6070</SelStart><SelEnd>6070</SelEnd></Tab><Tab><Factory>TextEditor</Factory><Filename>$WS_DIR$\serial.c</Filename><XPos>0</XPos><YPos>0</YPos><SelStart>0</SelStart><SelEnd>0</SelEnd></Tab><Tab><Factory>TextEditor</Factory><Filename>$WS_DIR$\FreeRTOSConfig.h</Filename><XPos>0</XPos><YPos>59</YPos><SelStart>4250</SelStart><SelEnd>4280</SelEnd></Tab><Tab><Factory>TextEditor</Factory><Filename>$WS_DIR$\main.c</Filename><XPos>0</XPos><YPos>215</YPos><SelStart>10723</SelStart><SelEnd>10723</SelEnd></Tab><ActiveTab>4</ActiveTab><Tab><Factory>TextEditor</Factory><Filename>$WS_DIR$\..\..\Source\portable\IAR\ARM_CM3\port.c</Filename><XPos>0</XPos><YPos>160</YPos><SelStart>6950</SelStart><SelEnd>6950</SelEnd></Tab></Pane><ActivePane>0</ActivePane><Sizes><Pane><X>1000000</X><Y>1000000</Y></Pane></Sizes><SplitMode>1</SplitMode></Editor>\r
     <Positions>\r
       \r
       \r
       \r
       \r
       \r
-    <Top><Row0><Sizes><Toolbar-012aae60><key>iaridepm.enu1</key></Toolbar-012aae60></Sizes></Row0></Top><Left><Row0><Sizes><Wnd0><Rect><Top>-2</Top><Left>-2</Left><Bottom>740</Bottom><Right>438</Right><x>-2</x><y>-2</y><xscreen>200</xscreen><yscreen>200</yscreen><sizeHorzCX>119048</sizeHorzCX><sizeHorzCY>203666</sizeHorzCY><sizeVertCX>261905</sizeVertCX><sizeVertCY>755601</sizeVertCY></Rect></Wnd0></Sizes></Row0></Left><Right><Row0><Sizes/></Row0></Right><Bottom><Row0><Sizes><Wnd1><Rect><Top>-2</Top><Left>-2</Left><Bottom>198</Bottom><Right>1682</Right><x>-2</x><y>-2</y><xscreen>1684</xscreen><yscreen>200</yscreen><sizeHorzCX>1002381</sizeHorzCX><sizeHorzCY>203666</sizeHorzCY><sizeVertCX>119048</sizeVertCX><sizeVertCY>203666</sizeVertCY></Rect></Wnd1></Sizes></Row0></Bottom><Float><Sizes/></Float></Positions>\r
+    <Top><Row0><Sizes><Toolbar-012aae60><key>iaridepm.enu1</key></Toolbar-012aae60></Sizes></Row0><Row1><Sizes/></Row1></Top><Left><Row0><Sizes><Wnd2><Rect><Top>-2</Top><Left>-2</Left><Bottom>740</Bottom><Right>438</Right><x>-2</x><y>-2</y><xscreen>200</xscreen><yscreen>200</yscreen><sizeHorzCX>119048</sizeHorzCX><sizeHorzCY>203666</sizeHorzCY><sizeVertCX>261905</sizeVertCX><sizeVertCY>755601</sizeVertCY></Rect></Wnd2></Sizes></Row0></Left><Right><Row0><Sizes/></Row0></Right><Bottom><Row0><Sizes><Wnd3><Rect><Top>-2</Top><Left>-2</Left><Bottom>198</Bottom><Right>1682</Right><x>-2</x><y>-2</y><xscreen>1684</xscreen><yscreen>200</yscreen><sizeHorzCX>1002381</sizeHorzCX><sizeHorzCY>203666</sizeHorzCY><sizeVertCX>119048</sizeVertCX><sizeVertCY>203666</sizeVertCY></Rect></Wnd3></Sizes></Row0></Bottom><Float><Sizes/></Float></Positions>\r
   </Desktop>\r
 </Workspace>\r
 \r