]> git.sur5r.net Git - freertos/blobdiff - Demo/CORTEX_A2F200_SoftConsole/main-full.c
Added BSP generation files to MicroBlaze directory.
[freertos] / Demo / CORTEX_A2F200_SoftConsole / main-full.c
index 35661670bd4181cf3ecb014b4e6a53a791e06ae2..244beaa6b245922e0f0998313037d45df750f4ae 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-    FreeRTOS V7.0.0 - Copyright (C) 2011 Real Time Engineers Ltd.\r
+    FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd.\r
 \r
 \r
        FreeRTOS supports many tools and architectures. V7.0.0 is sponsored by:\r
  *\r
  * The main() Function:\r
  * main() creates two demo specific software timers, one demo specific queue,\r
- * and two demo specific tasks.  It then creates a whole host of 'standard demo'\r
- * tasks/queues/semaphores, before starting the scheduler.  The demo specific\r
- * tasks and timers are described in the comments here.  The standard demo\r
- * tasks are described on the FreeRTOS.org web site.\r
+ * and three demo specific tasks.  It then creates a whole host of 'standard\r
+ * demo' tasks/queues/semaphores, before starting the scheduler.  The demo\r
+ * specific tasks and timers are described in the comments here.  The standard\r
+ * demo tasks are described on the FreeRTOS.org web site.\r
  *\r
  * The standard demo tasks provide no specific functionality.  They are\r
  * included to both test the FreeRTOS port, and provide examples of how the\r
  * the Blocked state every 200 milliseconds, and therefore toggles the LED\r
  * every 200 milliseconds.\r
  *\r
+ * The Demo Specific OLED Task:\r
+ * The OLED task is a very simple task that just scrolls a message across the\r
+ * OLED.  Ideally this would be done in a timer, but the OLED driver accesses\r
+ * the I2C which is time consuming.\r
+ *\r
  * The Demo Specific LED Software Timer and the Button Interrupt:\r
  * The user button SW1 is configured to generate an interrupt each time it is\r
  * pressed.  The interrupt service routine switches an LED on, and resets the\r
  * Therefore, pressing the user button will turn the LED on, and the LED will\r
  * remain on until a full five seconds pass without the button being pressed.\r
  *\r
- * The Demo Specific Idle Hook Function:\r
- * The idle hook function demonstrates how to query the amount of FreeRTOS heap\r
- * space that is remaining (see vApplicationIdleHook() defined in this file).\r
- *\r
  * The Demo Specific "Check" Callback Function:\r
  * This is called each time the 'check' timer expires.  The check timer\r
  * callback function inspects all the standard demo tasks to see if they are\r
  * is ever discovered.  The check timer callback toggles the LED defined by\r
  * the mainCHECK_LED definition each time it executes.  Therefore, if LED\r
  * mainCHECK_LED is toggling every three seconds, then no error have been found.\r
- * If LED mainCHECK_LED is toggling every 500ms, then at least one error has\r
+ * If LED mainCHECK_LED is toggling every 500ms, then at least one errors has\r
  * been found.  The task in which the error was discovered is displayed at the\r
  * bottom of the "task stats" page that is served by the embedded web server.\r
  *\r
+ * The Demo Specific Idle Hook Function:\r
+ * The idle hook function demonstrates how to query the amount of FreeRTOS heap\r
+ * space that is remaining (see vApplicationIdleHook() defined in this file).\r
+ *\r
  * The Web Server Task:\r
  * The IP address used by the SmartFusion target is configured by the\r
  * definitions configIP_ADDR0 to configIP_ADDR3, which are located in the\r
 /* Microsemi drivers/libraries includes. */\r
 #include "mss_gpio.h"\r
 #include "mss_watchdog.h"\r
-#include "OLED.h"\r
+#include "mss_timer.h"\r
+#include "mss_ace.h"\r
+#include "oled.h"\r
 \r
 /* Common demo includes. */\r
 #include "partest.h"\r
@@ -189,6 +196,7 @@ the queue empty. */
 #define mainCREATOR_TASK_PRIORITY   ( tskIDLE_PRIORITY + 3 )\r
 #define mainFLASH_TASK_PRIORITY                ( tskIDLE_PRIORITY + 1 )\r
 #define mainuIP_TASK_PRIORITY          ( tskIDLE_PRIORITY + 2 )\r
+#define mainOLED_TASK_PRIORITY         ( tskIDLE_PRIORITY + 1 )\r
 #define mainINTEGER_TASK_PRIORITY   ( tskIDLE_PRIORITY )\r
 #define mainGEN_QUEUE_TASK_PRIORITY    ( tskIDLE_PRIORITY )\r
 \r
@@ -198,11 +206,19 @@ stack than most of the other tasks. */
 \r
 /* The period at which the check timer will expire, in ms, provided no errors\r
 have been reported by any of the standard demo tasks. */\r
-#define mainCHECK_TIMER_PERIOD_ms      ( 3000UL )\r
+#define mainCHECK_TIMER_PERIOD_MS      ( 3000UL / portTICK_RATE_MS )\r
+\r
+/* The period at which the OLED timer will expire.  Each time it expires, it's\r
+callback function updates the OLED text. */\r
+#define mainOLED_PERIOD_MS                     ( 75UL / portTICK_RATE_MS )\r
 \r
 /* The period at which the check timer will expire, in ms, if an error has been\r
-reported in one of the standard demo tasks. */
-#define mainERROR_CHECK_TIMER_PERIOD_ms ( 500UL )\r
+reported in one of the standard demo tasks. */\r
+#define mainERROR_CHECK_TIMER_PERIOD_MS ( 500UL / portTICK_RATE_MS )\r
+\r
+/* The LED will remain on until the button has not been pushed for a full\r
+5000ms. */\r
+#define mainLED_TIMER_PERIOD_MS                ( 5000UL / portTICK_RATE_MS )\r
 \r
 /* A zero block time. */\r
 #define mainDONT_BLOCK                         ( 0UL )\r
@@ -220,19 +236,19 @@ static void prvQueueReceiveTask( void *pvParameters );
 static void prvQueueSendTask( void *pvParameters );\r
 \r
 /*\r
- * The LED timer callback function.  This does nothing but switch the red LED \r
+ * The LED timer callback function.  This does nothing but switch the red LED\r
  * off.\r
  */\r
-static void vLEDTimerCallback( xTimerHandle xTimer );\r
+static void prvLEDTimerCallback( xTimerHandle xTimer );\r
 \r
 /*\r
- * The check timer callback function, as described at the top of this file.
+ * The check timer callback function, as described at the top of this file.\r
  */\r
-static void vCheckTimerCallback( xTimerHandle xTimer );\r
+static void prvCheckTimerCallback( xTimerHandle xTimer );\r
 \r
 /*\r
  * This is not a 'standard' partest function, so the prototype is not in\r
- * partest.h, and is instead included here.
+ * partest.h, and is instead included here.\r
  */\r
 void vParTestSetLEDFromISR( unsigned portBASE_TYPE uxLED, signed portBASE_TYPE xValue );\r
 \r
@@ -241,16 +257,23 @@ void vParTestSetLEDFromISR( unsigned portBASE_TYPE uxLED, signed portBASE_TYPE x
  */\r
 extern void vuIP_Task( void *pvParameters );\r
 \r
+/*\r
+ * A very simply task that does nothing but scroll the OLED display.  Ideally\r
+ * this would be done within a timer, but it accesses the I2C port which is\r
+ * time consuming.\r
+ */\r
+static void prvOLEDTask( void * pvParameters);\r
+\r
 /*-----------------------------------------------------------*/\r
 \r
 /* The queue used by both application specific demo tasks defined in this file. */\r
 static xQueueHandle xQueue = NULL;\r
 \r
-/* The LED software timer.  This uses vLEDTimerCallback() as it's callback\r
+/* The LED software timer.  This uses prvLEDTimerCallback() as it's callback\r
 function. */\r
 static xTimerHandle xLEDTimer = NULL;\r
 \r
-/* The check timer.  This uses vCheckTimerCallback() as it's callback\r
+/* The check timer.  This uses prvCheckTimerCallback() as it's callback\r
 function. */\r
 static xTimerHandle xCheckTimer = NULL;\r
 \r
@@ -259,7 +282,6 @@ page, which is served by the uIP task.  This will report any errors picked up
 by the check timer callback. */\r
 static const char *pcStatusMessage = NULL;\r
 \r
-\r
 /*-----------------------------------------------------------*/\r
 \r
 int main(void)\r
@@ -272,28 +294,29 @@ int main(void)
 \r
        if( xQueue != NULL )\r
        {\r
-               /* Start the two application specific demo tasks, as described in the\r
+               /* Start the three application specific demo tasks, as described in the\r
                comments at the top of this     file. */\r
                xTaskCreate( prvQueueReceiveTask, ( signed char * ) "Rx", configMINIMAL_STACK_SIZE, NULL, mainQUEUE_RECEIVE_TASK_PRIORITY, NULL );\r
                xTaskCreate( prvQueueSendTask, ( signed char * ) "TX", configMINIMAL_STACK_SIZE, NULL, mainQUEUE_SEND_TASK_PRIORITY, NULL );\r
+               xTaskCreate( prvOLEDTask, ( signed char * ) "OLED", configMINIMAL_STACK_SIZE, NULL, mainOLED_TASK_PRIORITY, NULL );\r
 \r
-               /* Create the software timer that is responsible for turning off the LED \r
-               if the button is not pushed within 5000ms, as described at the top of \r
+               /* Create the software timer that is responsible for turning off the LED\r
+               if the button is not pushed within 5000ms, as described at the top of\r
                this file. */\r
                xLEDTimer = xTimerCreate(       ( const signed char * ) "LEDTimer", /* A text name, purely to help debugging. */\r
-                                                                       ( 5000 / portTICK_RATE_MS ),            /* The timer period, in this case 5000ms (5s). */\r
+                                                                       ( mainLED_TIMER_PERIOD_MS ),            /* The timer period, in this case 5000ms (5s). */\r
                                                                        pdFALSE,                                                        /* This is a one shot timer, so xAutoReload is set to pdFALSE. */\r
                                                                        ( void * ) 0,                                           /* The ID is not used, so can be set to anything. */\r
-                                                                       vLEDTimerCallback                                       /* The callback function that switches the LED off. */\r
+                                                                       prvLEDTimerCallback                                     /* The callback function that switches the LED off. */\r
                                                                );\r
 \r
                /* Create the software timer that performs the 'check' functionality,\r
                as described at the top of this file. */\r
-               xCheckTimer = xTimerCreate( ( const signed char * ) "CheckTimer",       /* A text name, purely to help debugging. */\r
-                                                                       ( mainCHECK_TIMER_PERIOD_ms / portTICK_RATE_MS ),/* The timer period, in this case 3000ms (3s). */\r
-                                                                       pdTRUE,                                                                 /* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */\r
-                                                                       ( void * ) 0,                                                   /* The ID is not used, so can be set to anything. */\r
-                                                                       vCheckTimerCallback                                             /* The callback function that inspects the status of all the other tasks. */\r
+               xCheckTimer = xTimerCreate( ( const signed char * ) "CheckTimer",/* A text name, purely to help debugging. */\r
+                                                                       ( mainCHECK_TIMER_PERIOD_MS ),          /* The timer period, in this case 3000ms (3s). */\r
+                                                                       pdTRUE,                                                         /* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */\r
+                                                                       ( void * ) 0,                                           /* The ID is not used, so can be set to anything. */\r
+                                                                       prvCheckTimerCallback                           /* The callback function that inspects the status of all the other tasks. */\r
                                                                  );\r
 \r
                /* Create a lot of 'standard demo' tasks. */\r
@@ -308,6 +331,12 @@ int main(void)
 \r
                /* Create the web server task. */\r
                xTaskCreate( vuIP_Task, ( signed char * ) "uIP", mainuIP_STACK_SIZE, NULL, mainuIP_TASK_PRIORITY, NULL );\r
+               \r
+               /* The suicide tasks must be created last, as they need to know how many\r
+               tasks were running prior to their creation in order to ascertain whether\r
+               or not the correct/expected number of tasks are running at any given\r
+               time. */\r
+               vCreateSuicidalTasks( mainCREATOR_TASK_PRIORITY );\r
 \r
                /* Start the tasks and timer running. */\r
                vTaskStartScheduler();\r
@@ -322,7 +351,7 @@ int main(void)
 }\r
 /*-----------------------------------------------------------*/\r
 \r
-static void vCheckTimerCallback( xTimerHandle xTimer )\r
+static void prvCheckTimerCallback( xTimerHandle xTimer )\r
 {\r
        /* Check the standard demo tasks are running without error.   Latch the\r
        latest reported error in the pcStatusMessage character pointer. */\r
@@ -361,18 +390,18 @@ static void vCheckTimerCallback( xTimerHandle xTimer )
                pcStatusMessage = "Error: RecMutex\r\n";\r
        }\r
 \r
-       if( xAreTimerDemoTasksStillRunning( ( mainCHECK_TIMER_PERIOD_ms / portTICK_RATE_MS ) ) != pdTRUE )\r
+       if( xAreTimerDemoTasksStillRunning( ( mainCHECK_TIMER_PERIOD_MS ) ) != pdTRUE )\r
        {\r
                pcStatusMessage = "Error: TimerDemo";\r
        }\r
 \r
        /* Toggle the check LED to give an indication of the system status.  If\r
-       the LED toggles every mainCHECK_TIMER_PERIOD_ms milliseconds then\r
+       the LED toggles every mainCHECK_TIMER_PERIOD_MS milliseconds then\r
        everything is ok.  A faster toggle indicates an error. */\r
        vParTestToggleLED( mainCHECK_LED );\r
 \r
        /* Have any errors been latch in pcStatusMessage?  If so, shorten the\r
-       period of the check timer to mainERROR_CHECK_TIMER_PERIOD_ms milliseconds.\r
+       period of the check timer to mainERROR_CHECK_TIMER_PERIOD_MS milliseconds.\r
        This will result in an increase in the rate at which mainCHECK_LED\r
        toggles. */\r
        if( pcStatusMessage != NULL )\r
@@ -380,12 +409,12 @@ static void vCheckTimerCallback( xTimerHandle xTimer )
                /* This call to xTimerChangePeriod() uses a zero block time.  Functions\r
                called from inside of a timer callback function must *never* attempt\r
                to block. */\r
-               xTimerChangePeriod( xCheckTimer, ( mainERROR_CHECK_TIMER_PERIOD_ms / portTICK_RATE_MS ), mainDONT_BLOCK );\r
+               xTimerChangePeriod( xCheckTimer, ( mainERROR_CHECK_TIMER_PERIOD_MS ), mainDONT_BLOCK );\r
        }\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
-static void vLEDTimerCallback( xTimerHandle xTimer )\r
+static void prvLEDTimerCallback( xTimerHandle xTimer )\r
 {\r
        /* The timer has expired - so no button pushes have occurred in the last\r
        five seconds - turn the LED off. */\r
@@ -425,19 +454,11 @@ static void prvQueueSendTask( void *pvParameters )
 portTickType xNextWakeTime;\r
 const unsigned long ulValueToSend = 100UL;\r
 \r
-       /* The suicide tasks must be created last, as they need to know how many\r
-       tasks were running prior to their creation in order to ascertain whether\r
-       or not the correct/expected number of tasks are running at any given time.\r
-       Therefore the standard demo 'death' tasks are not created in main(), but\r
-       instead created here. */\r
-       vCreateSuicidalTasks( mainCREATOR_TASK_PRIORITY );\r
-\r
-       /* The check timer command queue will have been filled when the timer test\r
-       tasks were created in main() (this is part of the test they perform).\r
-       Therefore, while the check timer can be created in main(), it could not be\r
-       started from main().  Once the scheduler has started, the timer service\r
-       task will have drained the command queue, and now the check task can be\r
-       started successfully. */
+       /* The timer command queue will have been filled when the timer test tasks\r
+       were created in main() (this is part of the test they perform).  Therefore,\r
+       while the check timer can be created in main(), it cannot be started from \r
+       main().  Once the scheduler has started, the timer service task will drain \r
+       the command queue, and now the check timer can be started successfully. */\r
        xTimerStart( xCheckTimer, portMAX_DELAY );\r
 \r
        /* Initialise xNextWakeTime - this only needs to be done once. */\r
@@ -455,7 +476,7 @@ const unsigned long ulValueToSend = 100UL;
                toggle an LED.  0 is used as the block time so the sending operation\r
                will not block - it shouldn't need to block as the queue should always\r
                be empty at this point in the code. */\r
-               xQueueSend( xQueue, &ulValueToSend, 0 );\r
+               xQueueSend( xQueue, &ulValueToSend, mainDONT_BLOCK );\r
        }\r
 }\r
 /*-----------------------------------------------------------*/\r
@@ -481,16 +502,58 @@ unsigned long ulReceivedValue;
 }\r
 /*-----------------------------------------------------------*/\r
 \r
+static void prvOLEDTask( void * pvParameters)\r
+{\r
+static struct oled_data xOLEDData;\r
+static unsigned char ucOffset1 = 0, ucOffset2 = 5;\r
+static portTickType xLastScrollTime = 0UL;\r
+\r
+       /* Initialise the display. */\r
+       OLED_init();\r
+\r
+       /* Initialise the parts of the oled_data structure that do not change. */\r
+       xOLEDData.line1          = FIRST_LINE;\r
+       xOLEDData.string1        = " www.FreeRTOS.org";\r
+       xOLEDData.line2          = SECOND_LINE;\r
+       xOLEDData.string2        = " www.FreeRTOS.org";\r
+       xOLEDData.contrast_val                 = OLED_CONTRAST_VAL;\r
+       xOLEDData.on_off                       = OLED_HORIZ_SCROLL_OFF;\r
+       xOLEDData.column_scrool_per_step       = OLED_HORIZ_SCROLL_STEP;\r
+       xOLEDData.start_page                   = OLED_START_PAGE;\r
+       xOLEDData.time_intrval_btw_scroll_step = OLED_HORIZ_SCROLL_TINVL;\r
+       xOLEDData.end_page                     = OLED_END_PAGE;\r
+\r
+\r
+       /* Initialise the last scroll time.  This only needs to be done once,\r
+       because from this point on it will get automatically updated in the\r
+       xTaskDelayUntil() API function. */\r
+       xLastScrollTime = xTaskGetTickCount();\r
+\r
+       for( ;; )\r
+       {\r
+               /* Wait until it is time to update the OLED again. */\r
+               vTaskDelayUntil( &xLastScrollTime, mainOLED_PERIOD_MS );\r
+               \r
+               xOLEDData.char_offset1   = ucOffset1++;\r
+               xOLEDData.char_offset2   = ucOffset2++;\r
+       \r
+               OLED_write_data( &xOLEDData, BOTH_LINES );\r
+       }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
 static void prvSetupHardware( void )\r
 {\r
+       SystemCoreClockUpdate();\r
+       \r
        /* Disable the Watch Dog Timer */\r
        MSS_WD_disable( );\r
 \r
        /* Configure the GPIO for the LEDs. */\r
        vParTestInitialise();\r
-\r
-       /* Initialise the display. */\r
-    OLED_init();\r
+       \r
+       /* ACE Initialization */\r
+       ACE_init();\r
 \r
        /* Setup the GPIO and the NVIC for the switch used in this simple demo. */\r
        NVIC_SetPriority( GPIO8_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY );\r
@@ -504,7 +567,7 @@ void vApplicationMallocFailedHook( void )
 {\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, software \r
+       internally by FreeRTOS API functions that create tasks, queues, software\r
        timers, and semaphores.  The size of the FreeRTOS heap is set by the\r
        configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */\r
        for( ;; );\r
@@ -557,5 +620,36 @@ char *pcGetTaskStatusMessage( void )
                return ( char * ) pcStatusMessage;\r
        }\r
 }\r
+/*-----------------------------------------------------------*/\r
 \r
+void vMainConfigureTimerForRunTimeStats( void )\r
+{\r
+const unsigned long ulMax32BitValue = 0xffffffffUL;\r
+\r
+       MSS_TIM64_init( MSS_TIMER_PERIODIC_MODE );\r
+       MSS_TIM64_load_immediate( ulMax32BitValue, ulMax32BitValue );\r
+       MSS_TIM64_start();\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+unsigned long ulGetRunTimeCounterValue( void )\r
+{\r
+unsigned long long ullCurrentValue;\r
+const unsigned long long ulMax64BitValue = 0xffffffffffffffffULL;\r
+unsigned long *pulHighWord, *pulLowWord;\r
+\r
+       pulHighWord = ( unsigned long * ) &ullCurrentValue;\r
+       pulLowWord = pulHighWord++;\r
+       \r
+       MSS_TIM64_get_current_value( ( uint32_t * ) pulHighWord, ( uint32_t * ) pulLowWord );\r
+       \r
+       /* Convert the down count into an upcount. */\r
+       ullCurrentValue = ulMax64BitValue - ullCurrentValue;\r
+       \r
+       /* Scale to a 32bit number of suitable frequency. */\r
+       ullCurrentValue >>= 13;\r
+\r
+       /* Just return 32 bits. */\r
+       return ( unsigned long ) ullCurrentValue;\r
+}\r
 \r