From f2ec2fd13c086d14875f57d3d4923f42596f4a02 Mon Sep 17 00:00:00 2001 From: richardbarry Date: Fri, 6 May 2011 19:25:12 +0000 Subject: [PATCH] Complete the IAR FM3 demo. git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@1415 1d2547de-c912-0410-9cb9-b8ca96c0e9e2 --- Demo/CORTEX_MB9B500_IAR_Keil/FreeRTOSConfig.h | 4 +- Demo/CORTEX_MB9B500_IAR_Keil/RTOSDemo_IAR.ewd | 872 +++++++++++++++++ Demo/CORTEX_MB9B500_IAR_Keil/RTOSDemo_IAR.ewp | 914 ++++++++++++++++++ Demo/CORTEX_MB9B500_IAR_Keil/main-full.c | 175 ++-- Demo/CORTEX_MB9B500_IAR_Keil/main_blinky.c | 13 +- Demo/CORTEX_MB9B500_IAR_Keil/serial.c | 305 ++++++ 6 files changed, 2217 insertions(+), 66 deletions(-) create mode 100644 Demo/CORTEX_MB9B500_IAR_Keil/serial.c diff --git a/Demo/CORTEX_MB9B500_IAR_Keil/FreeRTOSConfig.h b/Demo/CORTEX_MB9B500_IAR_Keil/FreeRTOSConfig.h index b1b495433..d842f3378 100644 --- a/Demo/CORTEX_MB9B500_IAR_Keil/FreeRTOSConfig.h +++ b/Demo/CORTEX_MB9B500_IAR_Keil/FreeRTOSConfig.h @@ -82,7 +82,7 @@ assembly files that include this header file. */ #define configUSE_PREEMPTION 1 #define configUSE_IDLE_HOOK 1 -#define configUSE_TICK_HOOK 0 +#define configUSE_TICK_HOOK 1 #define configCPU_CLOCK_HZ ( SystemCoreClock ) #define configTICK_RATE_HZ ( ( portTickType ) 1000 ) #define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 5 ) @@ -99,7 +99,7 @@ assembly files that include this header file. */ #define configUSE_RECURSIVE_MUTEXES 1 #define configUSE_MALLOC_FAILED_HOOK 1 #define configUSE_APPLICATION_TASK_TAG 0 -#define configUSE_COUNTING_SEMAPHORES 0 +#define configUSE_COUNTING_SEMAPHORES 1 /* Co-routine definitions. */ #define configUSE_CO_ROUTINES 0 diff --git a/Demo/CORTEX_MB9B500_IAR_Keil/RTOSDemo_IAR.ewd b/Demo/CORTEX_MB9B500_IAR_Keil/RTOSDemo_IAR.ewd index 2c07a4021..2972febe9 100644 --- a/Demo/CORTEX_MB9B500_IAR_Keil/RTOSDemo_IAR.ewd +++ b/Demo/CORTEX_MB9B500_IAR_Keil/RTOSDemo_IAR.ewd @@ -1746,6 +1746,878 @@ + + Full_with_optimisation + + ARM + + 1 + + C-SPY + 2 + + 22 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 1 + + + + + + + + ANGEL_ID + 2 + + 0 + 1 + 1 + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 1 + + + + + + + + + + + IARROM_ID + 2 + + 1 + 1 + 1 + + + + + + + + + JLINK_ID + 2 + + 13 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 2 + 1 + 1 + + + + + + + + + + MACRAIGOR_ID + 2 + + 3 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + PEMICRO_ID + 2 + + 0 + 1 + 1 + + + + + + + + + + + + + + + + + RDI_ID + 2 + + 2 + 1 + 1 + + + + + + + + + + + + + + + + STLINK_ID + 2 + + 2 + 1 + 1 + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 1 + + + + + + + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\MQX\MQXRtosPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\PowerPac\PowerPacRTOS.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Quadros\Quadros_EWB6_Plugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\FreeRTOS\FreeRTOSPlugin.ewplugin + 0 + + + $EW_DIR$\common\plugins\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\Stack\Stack.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\SymList\SymList.ENU.ewplugin + 1 + + + diff --git a/Demo/CORTEX_MB9B500_IAR_Keil/RTOSDemo_IAR.ewp b/Demo/CORTEX_MB9B500_IAR_Keil/RTOSDemo_IAR.ewp index 501ca869e..4d5e4904c 100644 --- a/Demo/CORTEX_MB9B500_IAR_Keil/RTOSDemo_IAR.ewp +++ b/Demo/CORTEX_MB9B500_IAR_Keil/RTOSDemo_IAR.ewp @@ -1797,6 +1797,904 @@ + + Full_with_optimisation + + ARM + + 1 + + General + 3 + + 21 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 28 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 8 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 1 + + + + + + + + + CUSTOM + 3 + + + + + + + BICOMP + 0 + + + + BUILDACTION + 1 + + + + + + + ILINK + 0 + + 13 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 1 + + + + + + + BILINK + 0 + + + Common_Demo_Source @@ -1808,6 +2706,12 @@ $PROJ_DIR$\..\Common\Minimal\blocktim.c + + $PROJ_DIR$\..\Common\Minimal\comtest.c + + + $PROJ_DIR$\..\Common\Minimal\countsem.c + $PROJ_DIR$\..\Common\Minimal\death.c @@ -1820,6 +2724,9 @@ $PROJ_DIR$\..\Common\Minimal\GenQTest.c + + $PROJ_DIR$\..\Common\Minimal\PollQ.c + $PROJ_DIR$\..\Common\Minimal\QPeek.c @@ -1882,6 +2789,7 @@ $PROJ_DIR$\main_blinky.c Full + Full_with_optimisation @@ -1890,6 +2798,12 @@ Blinky + + $PROJ_DIR$\serial.c + + Blinky + + diff --git a/Demo/CORTEX_MB9B500_IAR_Keil/main-full.c b/Demo/CORTEX_MB9B500_IAR_Keil/main-full.c index 159843d4d..1c173ee1d 100644 --- a/Demo/CORTEX_MB9B500_IAR_Keil/main-full.c +++ b/Demo/CORTEX_MB9B500_IAR_Keil/main-full.c @@ -63,16 +63,14 @@ * * main-full.c (this file) defines a comprehensive demo that creates many * tasks, queues, semaphores and timers. It also demonstrates how Cortex-M3 - * interrupts can interact with FreeRTOS tasks/timers, and implements a simple - * and small interactive web server. + * interrupts can interact with FreeRTOS tasks/timers. * - * This project runs on the SmartFusion A2F-EVAL-KIT evaluation board, which - * is populated with an A2F200M3F SmartFusion mixed signal FPGA. The A2F200M3F - * incorporates a Cortex-M3 microcontroller. + * This project runs on the SK-FM3-100PMC evaluation board, which is populated + * with an MB9BF5006N Cortex-M3 based microcontroller. * * The main() Function: - * main() creates two demo specific software timers, one demo specific queue, - * and three demo specific tasks. It then creates a whole host of 'standard + * main() creates three demo specific software timers, one demo specific queue, + * and two demo specific tasks. It then creates a whole host of 'standard * demo' tasks/queues/semaphores, before starting the scheduler. The demo * specific tasks and timers are described in the comments here. The standard * demo tasks are described on the FreeRTOS.org web site. @@ -81,6 +79,9 @@ * included to both test the FreeRTOS port, and provide examples of how the * various FreeRTOS API functions can be used. * + * This demo creates 43 tasks in total. If you want a simpler demo, use the + * Blinky build configuration. + * * The Demo Specific Queue Send Task: * The queue send task is implemented by the prvQueueSendTask() function in * this file. prvQueueSendTask() sits in a loop that causes it to repeatedly @@ -93,22 +94,25 @@ * in this file. prvQueueReceiveTask() sits in a loop that causes it to * repeatedly attempt to read data from the queue that was created within * main(). When data is received, the task checks the value of the data, and - * if the value equals the expected 100, toggles the green LED. The 'block - * time' parameter passed to the queue receive function specifies that the task - * should be held in the Blocked state indefinitely to wait for data to be - * available on the queue. The queue receive task will only leave the Blocked - * state when the queue send task writes to the queue. As the queue send task - * writes to the queue every 200 milliseconds, the queue receive task leaves - * the Blocked state every 200 milliseconds, and therefore toggles the LED - * every 200 milliseconds. + * if the value equals the expected 100, toggles an LED in the 7 segment display + * (see the documentation page for this demo on the FreeRTOS.org site to see + * which LED is used). The 'block time' parameter passed to the queue receive + * function specifies that the task should be held in the Blocked state + * indefinitely to wait for data to be available on the queue. The queue + * receive task will only leave the Blocked state when the queue send task + * writes to the queue. As the queue send task writes to the queue every 200 + * milliseconds, the queue receive task leaves the Blocked state every 200 + * milliseconds, and therefore toggles the LED every 200 milliseconds. * * The Demo Specific LED Software Timer and the Button Interrupt: - * The user button SW1 is configured to generate an interrupt each time it is + * The user button SW2 is configured to generate an interrupt each time it is * pressed. The interrupt service routine switches an LED on, and resets the * LED software timer. The LED timer has a 5000 millisecond (5 second) period, * and uses a callback function that is defined to just turn the LED off again. * Therefore, pressing the user button will turn the LED on, and the LED will * remain on until a full five seconds pass without the button being pressed. + * See the documentation page for this demo on the FreeRTOS.org web site to see + * which LED is used. * * The Demo Specific "Check" Callback Function: * This is called each time the 'check' timer expires. The check timer @@ -119,18 +123,23 @@ * the mainCHECK_LED definition each time it executes. Therefore, if LED * mainCHECK_LED is toggling every three seconds, then no error have been found. * If LED mainCHECK_LED is toggling every 500ms, then at least one errors has - * been found. The task in which the error was discovered is displayed at the - * bottom of the "task stats" page that is served by the embedded web server. + * been found. The variable pcStatusMessage is set to a string that indicates + * which task reported an error. See the documentation page for this demo on + * the FreeRTOS.org web site to see which LED in the 7 segment display is used. + * + * The Demo Specific "Digit Counter" Callback Function: + * This is called each time the 'digit counter' timer expires. It causes the + * digits 0 to 9 to be displayed in turn as the first character of the two + * character display. The LEDs in the other digit of the two character + * display are used as general purpose LEDs, as described in this comment block. * * The Demo Specific Idle Hook Function: * The idle hook function demonstrates how to query the amount of FreeRTOS heap * space that is remaining (see vApplicationIdleHook() defined in this file). * - * The Web Server Task: - * The IP address used by the SmartFusion target is configured by the - * definitions configIP_ADDR0 to configIP_ADDR3, which are located in the - * FreeRTOSConfig.h header file. See the documentation page for this example - * on the http://www.FreeRTOS.org web site for further connection information. + * The Demo Specific Tick Hook Function: + * The tick hook function is used to test the interrupt safe software timer + * functionality. */ /* Kernel includes. */ @@ -154,33 +163,46 @@ #include "QPeek.h" #include "recmutex.h" #include "TimerDemo.h" - -/* Priorities at which the tasks are created. */ -#define mainQUEUE_RECEIVE_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 ) -#define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) +#include "comtest2.h" +#include "PollQ.h" +#include "countsem.h" +#include "dynamic.h" /* The rate at which data is sent to the queue, specified in milliseconds, and converted to ticks using the portTICK_RATE_MS constant. */ -#define mainQUEUE_SEND_FREQUENCY_MS ( 200 / portTICK_RATE_MS ) +#define mainQUEUE_SEND_FREQUENCY_MS ( 200 / portTICK_RATE_MS ) /* The number of items the queue can hold. This is 1 as the receive task will remove items as they are added, meaning the send task should always find the queue empty. */ #define mainQUEUE_LENGTH ( 1 ) -/* The LED toggled by the check timer callback function. */ +/* The LED toggled by the check timer callback function. This is an LED in the +second digit of the two digit 7 segment display. See the documentation page +for this demo on the FreeRTOS.org web site to see which LED this relates to. */ #define mainCHECK_LED 0x07UL -/* The LED toggle by the queue receive task. */ -#define mainTASK_CONTROLLED_LED 0x04UL +/* The LED toggle by the queue receive task. This is an LED in the second digit +of the two digit 7 segment display. See the documentation page for this demo on +the FreeRTOS.org web site to see which LED this relates to. */ +#define mainTASK_CONTROLLED_LED 0x06UL -/* The LED turned on by the button interrupt, and turned off by the LED timer. */ +/* The LED turned on by the button interrupt, and turned off by the LED timer. +This is an LED in the second digit of the two digit 7 segment display. See the +documentation page for this demo on the FreeRTOS.org web site to see which LED +this relates to. */ #define mainTIMER_CONTROLLED_LED 0x05UL +/* The LED used by the comtest tasks. See the comtest.c file for more +information. The LEDs used by the comtest task are in the second digit of the +two digit 7 segment display. See the documentation page for this demo on the +FreeRTOS.org web site to see which LEDs this relates to. */ +#define mainCOM_TEST_LED ( 3 ) + /* Constant used by the standard timer test functions. */ #define mainTIMER_TEST_PERIOD ( 50 ) -/* Priorities used by the various different tasks. */ +/* Priorities used by the various different standard demo tasks. */ #define mainCHECK_TASK_PRIORITY ( configMAX_PRIORITIES - 1 ) #define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 1 ) #define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 ) @@ -189,25 +211,36 @@ the queue empty. */ #define mainFLASH_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) #define mainINTEGER_TASK_PRIORITY ( tskIDLE_PRIORITY ) #define mainGEN_QUEUE_TASK_PRIORITY ( tskIDLE_PRIORITY ) +#define mainCOM_TEST_PRIORITY ( tskIDLE_PRIORITY + 2 ) + +/* Priorities defined in this main-full.c file. */ +#define mainQUEUE_RECEIVE_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 ) +#define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) /* The period at which the check timer will expire, in ms, provided no errors -have been reported by any of the standard demo tasks. */ -#define mainCHECK_TIMER_PERIOD_MS ( 3000UL / portTICK_RATE_MS ) +have been reported by any of the standard demo tasks. ms are converted to the +equivalent in ticks using the portTICK_RATE_MS constant. */ +#define mainCHECK_TIMER_PERIOD_MS ( 3000UL / portTICK_RATE_MS ) /* The period at which the check timer will expire, in ms, if an error has been -reported in one of the standard demo tasks. */ -#define mainERROR_CHECK_TIMER_PERIOD_MS ( 500UL / portTICK_RATE_MS ) +reported in one of the standard demo tasks. ms are converted to the equivalent +in ticks using the portTICK_RATE_MS constant. */ +#define mainERROR_CHECK_TIMER_PERIOD_MS ( 500UL / portTICK_RATE_MS ) /* The period at which the digit counter timer will expire, in ms, and converted to ticks using the portTICK_RATE_MS constant. */ -#define mainDIGIT_COUNTER_TIMER_PERIOD_MS ( 250UL / portTICK_RATE_MS ) +#define mainDIGIT_COUNTER_TIMER_PERIOD_MS ( 250UL / portTICK_RATE_MS ) /* The LED will remain on until the button has not been pushed for a full 5000ms. */ -#define mainLED_TIMER_PERIOD_MS ( 5000UL / portTICK_RATE_MS ) +#define mainLED_TIMER_PERIOD_MS ( 5000UL / portTICK_RATE_MS ) /* A zero block time. */ -#define mainDONT_BLOCK ( 0UL ) +#define mainDONT_BLOCK ( 0UL ) + +/* Baud rate used by the comtest tasks. */ +#define mainCOM_TEST_BAUD_RATE ( 115200UL ) + /*-----------------------------------------------------------*/ /* @@ -216,14 +249,14 @@ to ticks using the portTICK_RATE_MS constant. */ static void prvSetupHardware( void ); /* - * The tasks as described in the comments at the top of this file. + * The application specific (not common demo) tasks as described in the comments + * at the top of this file. */ static void prvQueueReceiveTask( void *pvParameters ); static void prvQueueSendTask( void *pvParameters ); /* - * The LED timer callback function. This does nothing but switch the red LED - * off. + * The LED timer callback function. This does nothing but switch an LED off. */ static void prvLEDTimerCallback( xTimerHandle xTimer ); @@ -252,11 +285,11 @@ static xQueueHandle xQueue = NULL; function. */ static xTimerHandle xLEDTimer = NULL; -/* The counter software timer. This displays a counting digit on one of the -seven segment displays. */ +/* The digit counter software timer. This displays a counting digit on one half +of the seven segment displays. */ static xTimerHandle xDigitCounterTimer = NULL; -/* The check timer. This uses prvCheckTimerCallback() as it's callback +/* The check timer. This uses prvCheckTimerCallback() as its callback function. */ static xTimerHandle xCheckTimer = NULL; @@ -277,7 +310,7 @@ int main(void) if( xQueue != NULL ) { - /* Start the three application specific demo tasks, as described in the + /* Start the two application specific demo tasks, as described in the comments at the top of this file. */ xTaskCreate( prvQueueReceiveTask, ( signed char * ) "Rx", configMINIMAL_STACK_SIZE, NULL, mainQUEUE_RECEIVE_TASK_PRIORITY, NULL ); xTaskCreate( prvQueueSendTask, ( signed char * ) "TX", configMINIMAL_STACK_SIZE, NULL, mainQUEUE_SEND_TASK_PRIORITY, NULL ); @@ -310,7 +343,9 @@ int main(void) prvDigitCounterTimerCallback /* The callback function that inspects the status of all the other tasks. */ ); - /* Create a lot of 'standard demo' tasks. */ + /* Create a lot of 'standard demo' tasks. Over 40 tasks are created in + this demo. For a much simpler demo, select the 'blinky' build + configuration. */ vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY ); vCreateBlockTimeTasks(); vStartSemaphoreTasks( mainSEM_TEST_PRIORITY ); @@ -319,7 +354,11 @@ int main(void) vStartQueuePeekTasks(); vStartRecursiveMutexTasks(); vStartTimerDemoTask( mainTIMER_TEST_PERIOD ); - + vAltStartComTestTasks( mainCOM_TEST_PRIORITY, mainCOM_TEST_BAUD_RATE, mainCOM_TEST_LED ); + vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY ); + vStartCountingSemaphoreTasks(); + vStartDynamicPriorityTasks(); + /* The suicide tasks must be created last, as they need to know how many tasks were running prior to their creation in order to ascertain whether or not the correct/expected number of tasks are running at any given @@ -378,11 +417,31 @@ static void prvCheckTimerCallback( xTimerHandle xTimer ) pcStatusMessage = "Error: RecMutex\r\n"; } + if( xAreComTestTasksStillRunning() != pdPASS ) + { + pcStatusMessage = "Error: ComTest\r\n"; + } + if( xAreTimerDemoTasksStillRunning( ( mainCHECK_TIMER_PERIOD_MS ) ) != pdTRUE ) { pcStatusMessage = "Error: TimerDemo"; } + if( xArePollingQueuesStillRunning() != pdTRUE ) + { + pcStatusMessage = "Error: PollQueue"; + } + + if( xAreCountingSemaphoreTasksStillRunning() != pdTRUE ) + { + pcStatusMessage = "Error: CountSem"; + } + + if( xAreDynamicPriorityTasksStillRunning() != pdTRUE ) + { + pcStatusMessage = "Error: DynamicPriority"; + } + /* Toggle the check LED to give an indication of the system status. If the LED toggles every mainCHECK_TIMER_PERIOD_MS milliseconds then everything is ok. A faster toggle indicates an error. */ @@ -589,19 +648,11 @@ volatile size_t xFreeStackSpace; } /*-----------------------------------------------------------*/ -char *pcGetTaskStatusMessage( void ) +void vApplicationTickHook( void ) { - /* Not bothered about a critical section here although technically because - of the task priorities the pointer could change it will be atomic if not - near atomic and its not critical. */ - if( pcStatusMessage == NULL ) - { - return "All tasks running without error"; - } - else - { - return ( char * ) pcStatusMessage; - } -} + /* Call the periodic timer test, which tests the timer API functions that + can be called from an ISR. */ + vTimerPeriodicISRTests(); +} /*-----------------------------------------------------------*/ diff --git a/Demo/CORTEX_MB9B500_IAR_Keil/main_blinky.c b/Demo/CORTEX_MB9B500_IAR_Keil/main_blinky.c index 9344299c5..f1604a2a8 100644 --- a/Demo/CORTEX_MB9B500_IAR_Keil/main_blinky.c +++ b/Demo/CORTEX_MB9B500_IAR_Keil/main_blinky.c @@ -100,7 +100,7 @@ * The LED Software Timer and the Button Interrupt: * The user button SW2 is configured to generate an interrupt each time it is * pressed. The interrupt service routine switches an LED in the 7 segment - * diplay on, and resets the LED software timer. The LED timer has a 5000 + * display on, and resets the LED software timer. The LED timer has a 5000 * millisecond (5 second) period, and uses a callback function that is defined * to just turn the LED off again. Therefore, pressing the user button will * turn the LED on, and the LED will remain on until a full five seconds pass @@ -368,12 +368,21 @@ void vApplicationStackOverflowHook( xTaskHandle *pxTask, signed char *pcTaskName } /*-----------------------------------------------------------*/ +void vApplicationTickHook( void ) +{ + /* A tick hook is used by the "Full" build configuration. The Full and + blinky build configurations share a FreeRTOSConfig.h header file, so this + simple build configuration also has to define a tick hook - even though it + does not actually use it for anything. */ +} +/*-----------------------------------------------------------*/ + void vApplicationIdleHook( void ) { volatile size_t xFreeHeapSpace; /* This function is called on each cycle of the idle task. In this case it - does nothing useful, other than report the amout of FreeRTOS heap that + does nothing useful, other than report the amount of FreeRTOS heap that remains unallocated. */ xFreeHeapSpace = xPortGetFreeHeapSize(); diff --git a/Demo/CORTEX_MB9B500_IAR_Keil/serial.c b/Demo/CORTEX_MB9B500_IAR_Keil/serial.c new file mode 100644 index 000000000..389bb9ed8 --- /dev/null +++ b/Demo/CORTEX_MB9B500_IAR_Keil/serial.c @@ -0,0 +1,305 @@ +/* + FreeRTOS V7.0.0 - Copyright (C) 2011 Real Time Engineers Ltd. + + + *************************************************************************** + * * + * FreeRTOS tutorial books are available in pdf and paperback. * + * Complete, revised, and edited pdf reference manuals are also * + * available. * + * * + * Purchasing FreeRTOS documentation will not only help you, by * + * ensuring you get running as quickly as possible and with an * + * in-depth knowledge of how to use FreeRTOS, it will also help * + * the FreeRTOS project to continue with its mission of providing * + * professional grade, cross platform, de facto standard solutions * + * for microcontrollers - completely free of charge! * + * * + * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * + * * + * Thank you for using FreeRTOS, and thank you for your support! * + * * + *************************************************************************** + + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation AND MODIFIED BY the FreeRTOS exception. + >>>NOTE<<< The modification to the GPL is included to allow you to + distribute a combined work that includes FreeRTOS without being obliged to + provide the source code for proprietary components outside of the FreeRTOS + kernel. FreeRTOS is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License and the FreeRTOS license exception along with FreeRTOS; if not it + can be viewed here: http://www.freertos.org/a00114.html and also obtained + by writing to Richard Barry, contact details for whom are available on the + FreeRTOS WEB site. + + 1 tab == 4 spaces! + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +/* + BASIC INTERRUPT DRIVEN SERIAL PORT DRIVER FOR UART0. + + ***Note*** This example uses queues to send each character into an interrupt + service routine and out of an interrupt service routine individually. This + is done to demonstrate queues being used in an interrupt, and to deliberately + load the system to test the FreeRTOS port. It is *NOT* meant to be an + example of an efficient implementation. An efficient implementation should + use FIFO's or DMA if available, and only use FreeRTOS API functions when + enough has been received to warrant a task being unblocked to process the + data. +*/ + +/* Scheduler includes. */ +#include "FreeRTOS.h" +#include "queue.h" +#include "semphr.h" +#include "comtest2.h" + +/* Library includes. */ +#include "mb9bf506n.h" +#include "system_mb9bf50x.h" + +/* Demo application includes. */ +#include "serial.h" +/*-----------------------------------------------------------*/ + +/* Register bit definitions. */ +#define serRX_INT_ENABLE 0x10 +#define serTX_INT_ENABLE 0x08 +#define serRX_ENABLE 0x02 +#define serTX_ENABLE 0x01 +#define serORE_ERROR_BIT 0x08 +#define serFRE_ERROR_BIT 0x10 +#define serPE_ERROR_BIT 0x20 +#define serRX_INT 0x04 +#define serTX_INT 0x02 + +/* Misc defines. */ +#define serINVALID_QUEUE ( ( xQueueHandle ) 0 ) +#define serNO_BLOCK ( ( portTickType ) 0 ) + +/*-----------------------------------------------------------*/ + +/* The queue used to hold received characters. */ +static xQueueHandle xRxedChars; +static xQueueHandle xCharsForTx; + +/*-----------------------------------------------------------*/ + +/* + * See the serial2.h header file. + */ +xComPortHandle xSerialPortInitMinimal( unsigned long ulWantedBaud, unsigned portBASE_TYPE uxQueueLength ) +{ +xComPortHandle xReturn; + + /* Create the queues used to hold Rx/Tx characters. */ + xRxedChars = xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE ) sizeof( signed char ) ); + xCharsForTx = xQueueCreate( uxQueueLength + 1, ( unsigned portBASE_TYPE ) sizeof( signed char ) ); + + /* If the queues were created correctly then setup the serial port + hardware. */ + if( ( xRxedChars != serINVALID_QUEUE ) && ( xCharsForTx != serINVALID_QUEUE ) ) + { + /* Ensure interrupts don't fire during the init process. Interrupts + will be enabled automatically when the first task start running. */ + portDISABLE_INTERRUPTS(); + + /* Configure P21 and P22 for use by the UART. */ + FM3_GPIO->PFR2 |= ( 1 << 0x01 ) | ( 1 << 0x02 ); + + /* SIN0_0 and SOT0_0. */ + FM3_GPIO->EPFR07 |= ( 1 << 6 ); + + /* Reset. */ + FM3_MFS0_UART->SCR = 0x80; + + /* Enable output in mode 0. */ + FM3_MFS0_UART->SMR = 0x01; + + /* Clear all errors that may already be present. */ + FM3_MFS0_UART->SSR = 0x00; + FM3_MFS0_UART->ESCR = 0x00; + + FM3_MFS0_UART->BGR = ( configCPU_CLOCK_HZ / 2UL ) / ( ulWantedBaud - 1UL ); + + /* Enable Rx, Tx, and the Rx interrupt. */ + FM3_MFS0_UART->SCR |= ( serRX_ENABLE | serTX_ENABLE | serRX_INT_ENABLE ); + + /* Configure the NVIC for UART interrupts. */ + NVIC_ClearPendingIRQ( MFS0RX_IRQn ); + NVIC_EnableIRQ( MFS0RX_IRQn ); + + /* The priority *MUST* be at or below + configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY as FreeRTOS API functions + are called in the interrupt handler. */ + NVIC_SetPriority( MFS0RX_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); + + /* Do the same for the Tx interrupts. */ + NVIC_ClearPendingIRQ( MFS0TX_IRQn ); + NVIC_EnableIRQ( MFS0TX_IRQn ); + + /* The priority *MUST* be at or below + configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY as FreeRTOS API functions + are called in the interrupt handler. */ + NVIC_SetPriority( MFS0TX_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); + } + else + { + xReturn = ( xComPortHandle ) 0; + } + + /* This demo file only supports a single port but we have to return + something to comply with the standard demo header file. */ + return xReturn; +} +/*-----------------------------------------------------------*/ + +signed portBASE_TYPE xSerialGetChar( xComPortHandle pxPort, signed char *pcRxedChar, portTickType xBlockTime ) +{ + /* The port handle is not required as this driver only supports one port. */ + ( void ) pxPort; + + /* Get the next character from the buffer. Return false if no characters + are available, or arrive before xBlockTime expires. */ + if( xQueueReceive( xRxedChars, pcRxedChar, xBlockTime ) ) + { + return pdTRUE; + } + else + { + return pdFALSE; + } +} +/*-----------------------------------------------------------*/ + +void vSerialPutString( xComPortHandle pxPort, const signed char * const pcString, unsigned short usStringLength ) +{ +signed char *pxNext; + + /* A couple of parameters that this port does not use. */ + ( void ) usStringLength; + ( void ) pxPort; + + /* NOTE: This implementation does not handle the queue being full as no + block time is used! */ + + /* The port handle is not required as this driver only supports one UART. */ + ( void ) pxPort; + + /* Send each character in the string, one at a time. */ + pxNext = ( signed char * ) pcString; + while( *pxNext ) + { + xSerialPutChar( pxPort, *pxNext, serNO_BLOCK ); + pxNext++; + } +} +/*-----------------------------------------------------------*/ + +signed portBASE_TYPE xSerialPutChar( xComPortHandle pxPort, signed char cOutChar, portTickType xBlockTime ) +{ +signed portBASE_TYPE xReturn; + + if( xQueueSend( xCharsForTx, &cOutChar, xBlockTime ) == pdPASS ) + { + xReturn = pdPASS; + + /* Enable the UART Tx interrupt. */ + FM3_MFS0_UART->SCR |= serTX_INT_ENABLE; + } + else + { + xReturn = pdFAIL; + } + + return xReturn; +} +/*-----------------------------------------------------------*/ + +void vSerialClose( xComPortHandle xPort ) +{ + /* Not supported as not required by the demo application. */ +} +/*-----------------------------------------------------------*/ + +void MFS0RX_IRQHandler( void ) +{ +portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; +char cChar; + + if( ( FM3_MFS0_UART->SSR & ( serORE_ERROR_BIT | serFRE_ERROR_BIT | serPE_ERROR_BIT ) ) != 0 ) + { + /* A PE, ORE or FRE error occurred. Clear it. */ + FM3_MFS0_UART->SSR |= ( 1 << 7 ); + cChar = FM3_MFS0_UART->RDR; + } + else if( FM3_MFS0_UART->SSR & serRX_INT ) + { + /* A character has been received on the USART, send it to the Rx + handler task. */ + cChar = FM3_MFS0_UART->RDR; + xQueueSendFromISR( xRxedChars, &cChar, &xHigherPriorityTaskWoken ); + } + + /* If sending or receiving from a queue has caused a task to unblock, and + the unblocked task has a priority equal to or higher than the currently + running task (the task this ISR interrupted), then xHigherPriorityTaskWoken + will have automatically been set to pdTRUE within the queue send or receive + function. portEND_SWITCHING_ISR() will then ensure that this ISR returns + directly to the higher priority unblocked task. */ + portEND_SWITCHING_ISR( xHigherPriorityTaskWoken ); +} +/*-----------------------------------------------------------*/ + +void MFS0TX_IRQHandler( void ) +{ +portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; +char cChar; + + if( FM3_MFS0_UART->SSR & serTX_INT ) + { + /* The interrupt was caused by the TX register becoming empty. Are + there any more characters to transmit? */ + if( xQueueReceiveFromISR( xCharsForTx, &cChar, &xHigherPriorityTaskWoken ) == pdTRUE ) + { + /* A character was retrieved from the queue so can be sent to the + USART now. */ + FM3_MFS0_UART->TDR = cChar; + } + else + { + /* Disable the Tx interrupt. */ + FM3_MFS0_UART->SCR &= ~serTX_INT_ENABLE; + } + } + + /* If sending or receiving from a queue has caused a task to unblock, and + the unblocked task has a priority equal to or higher than the currently + running task (the task this ISR interrupted), then xHigherPriorityTaskWoken + will have automatically been set to pdTRUE within the queue send or receive + function. portEND_SWITCHING_ISR() will then ensure that this ISR returns + directly to the higher priority unblocked task. */ + portEND_SWITCHING_ISR( xHigherPriorityTaskWoken ); +} + + + + + + -- 2.39.2