From 0ae14111300df7a2f231c9e0d77018415ea9158d Mon Sep 17 00:00:00 2001 From: richardbarry Date: Thu, 3 Oct 2013 15:41:33 +0000 Subject: [PATCH] Complete CLI demo on SAMD20. git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@2048 1d2547de-c912-0410-9cb9-b8ca96c0e9e2 --- .../RTOSDemo/src/UARTCommandConsole.c | 23 ++++-- .../RTOSDemo/src/config/FreeRTOSConfig.h | 14 +++- .../RTOSDemo/src/main.c | 74 +++++++++++++++++++ 3 files changed, 105 insertions(+), 6 deletions(-) diff --git a/FreeRTOS/Demo/CORTEX_M0+_Atmel_SAMD20_XPlained/RTOSDemo/src/UARTCommandConsole.c b/FreeRTOS/Demo/CORTEX_M0+_Atmel_SAMD20_XPlained/RTOSDemo/src/UARTCommandConsole.c index 9bbdca2ec..8b0581f05 100644 --- a/FreeRTOS/Demo/CORTEX_M0+_Atmel_SAMD20_XPlained/RTOSDemo/src/UARTCommandConsole.c +++ b/FreeRTOS/Demo/CORTEX_M0+_Atmel_SAMD20_XPlained/RTOSDemo/src/UARTCommandConsole.c @@ -107,10 +107,21 @@ static void prvUARTCommandConsoleTask( void *pvParameters ); static void prvSendBuffer( struct usart_module *pxCDCUsart, uint8_t * pcBuffer, size_t xBufferLength ); /* - * A UART is used for printf() output and CLI input and output. Configure the - * UART and register prvUARTRxNotificationHandler() to handle UART Rx events. + * Register the 'standard' sample CLI commands with FreeRTOS+CLI. + */ +extern void vRegisterSampleCLICommands( void ); + +/* + * Configure the UART used for IO.and register prvUARTRxNotificationHandler() + * to handle UART Rx events. */ static void prvConfigureUART( struct usart_module *pxCDCUsart ); + +/* + * Callback functions registered with the Atmel UART driver. Both functions + * just 'give' a semaphore to unblock a task that may be waiting for a + * character to be received, or a transmission to complete. + */ static void prvUARTTxNotificationHandler( const struct usart_module *const pxUSART ); static void prvUARTRxNotificationHandler( const struct usart_module *const pxUSART ); @@ -133,6 +144,8 @@ static xSemaphoreHandle xRxCompleteSemaphore = NULL; void vUARTCommandConsoleStart( uint16_t usStackSize, unsigned portBASE_TYPE uxPriority ) { + vRegisterSampleCLICommands(); + /* Create that task that handles the console itself. */ xTaskCreate( prvUARTCommandConsoleTask, /* The task that implements the command console. */ ( const int8_t * const ) "CLI", /* Text name assigned to the task. This is just to assist debugging. The kernel does not use this name itself. */ @@ -251,7 +264,7 @@ static struct usart_module xCDCUsart; /* Static so it doesn't take up too much s static void prvSendBuffer( struct usart_module *pxCDCUsart, uint8_t * pcBuffer, size_t xBufferLength ) { -const portTickType xBlockMax50ms = 50 / portTICK_RATE_MS; +const portTickType xBlockMax100ms = 100UL / portTICK_RATE_MS; if( xBufferLength > 0 ) { @@ -259,7 +272,7 @@ const portTickType xBlockMax50ms = 50 / portTICK_RATE_MS; /* Wait for the Tx to complete so the buffer can be reused without corrupting the data that is being sent. */ - xSemaphoreTake( xTxCompleteSemaphore, xBlockMax50ms ); + xSemaphoreTake( xTxCompleteSemaphore, xBlockMax100ms ); } } /*-----------------------------------------------------------*/ @@ -279,7 +292,7 @@ struct usart_config xUARTConfig; configASSERT( xRxCompleteSemaphore ); /* Take the semaphores so they start in the wanted state. A block time is - not necessary, and is therefore set to 0, as it is known that the semaphore s + not necessary, and is therefore set to 0, as it is known that the semaphores exists - they have just been created. */ xSemaphoreTake( xTxCompleteSemaphore, 0 ); xSemaphoreTake( xRxCompleteSemaphore, 0 ); diff --git a/FreeRTOS/Demo/CORTEX_M0+_Atmel_SAMD20_XPlained/RTOSDemo/src/config/FreeRTOSConfig.h b/FreeRTOS/Demo/CORTEX_M0+_Atmel_SAMD20_XPlained/RTOSDemo/src/config/FreeRTOSConfig.h index 4b02ae2e2..9ce799cd3 100644 --- a/FreeRTOS/Demo/CORTEX_M0+_Atmel_SAMD20_XPlained/RTOSDemo/src/config/FreeRTOSConfig.h +++ b/FreeRTOS/Demo/CORTEX_M0+_Atmel_SAMD20_XPlained/RTOSDemo/src/config/FreeRTOSConfig.h @@ -100,9 +100,15 @@ extern uint32_t SystemCoreClock; #define configUSE_MALLOC_FAILED_HOOK 1 #define configUSE_APPLICATION_TASK_TAG 0 #define configUSE_COUNTING_SEMAPHORES 1 -#define configGENERATE_RUN_TIME_STATS 0 #define configUSE_QUEUE_SETS 1 +/* Run time stats related definitions. */ +void vMainConfigureTimerForRunTimeStats( void ); +unsigned long ulMainGetRunTimeCounterValue( void ); +#define configGENERATE_RUN_TIME_STATS 1 +#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() vMainConfigureTimerForRunTimeStats() +#define portGET_RUN_TIME_COUNTER_VALUE() ulMainGetRunTimeCounterValue() + /* Co-routine definitions. */ #define configUSE_CO_ROUTINES 0 #define configMAX_CO_ROUTINE_PRIORITIES ( 2 ) @@ -124,6 +130,12 @@ to exclude the API function. */ #define INCLUDE_vTaskDelay 1 #define INCLUDE_eTaskGetState 1 +/* This demo makes use of one or more example stats formatting functions. These +format the raw data provided by the uxTaskGetSystemState() function in to human +readable ASCII form. See the notes in the implementation of vTaskList() within +FreeRTOS/Source/tasks.c for limitations. */ +#define configUSE_STATS_FORMATTING_FUNCTIONS 1 + /* Normal assert() semantics without relying on the provision of an assert.h header file. */ #define configASSERT( x ) if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); for( ;; ); } diff --git a/FreeRTOS/Demo/CORTEX_M0+_Atmel_SAMD20_XPlained/RTOSDemo/src/main.c b/FreeRTOS/Demo/CORTEX_M0+_Atmel_SAMD20_XPlained/RTOSDemo/src/main.c index c69fc589f..b916b791e 100644 --- a/FreeRTOS/Demo/CORTEX_M0+_Atmel_SAMD20_XPlained/RTOSDemo/src/main.c +++ b/FreeRTOS/Demo/CORTEX_M0+_Atmel_SAMD20_XPlained/RTOSDemo/src/main.c @@ -72,12 +72,29 @@ /* Library includes. */ #include +/*-----------------------------------------------------------*/ + +/* + * Hardware and driver initialisation can be done in this function. + */ static void prvSetupHardware( void ); + +/* + * Prototypes for the FreeRTOS hook/callback functions. See the comments in + * the implementation of each function for more information. + */ void vApplicationMallocFailedHook( void ); void vApplicationIdleHook( void ); void vApplicationStackOverflowHook( xTaskHandle pxTask, signed char *pcTaskName ); void vApplicationTickHook( void ); +/*-----------------------------------------------------------*/ + +/* Used in the run time stats calculations. */ +static unsigned long ulClocksPer10thOfAMilliSecond = 0UL; + +/*-----------------------------------------------------------*/ + int main (void) { prvSetupHardware(); @@ -153,4 +170,61 @@ void vApplicationTickHook( void ) code must not attempt to block, and only the interrupt safe FreeRTOS API functions can be used (those that end in FromISR()). */ } +/*-----------------------------------------------------------*/ + +void vMainConfigureTimerForRunTimeStats( void ) +{ + /* How many clocks are there per tenth of a millisecond? */ + ulClocksPer10thOfAMilliSecond = configCPU_CLOCK_HZ / 10000UL; +} +/*-----------------------------------------------------------*/ + +unsigned long ulMainGetRunTimeCounterValue( void ) +{ +unsigned long ulSysTickCounts, ulTickCount, ulReturn; +const unsigned long ulSysTickReloadValue = ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL; +volatile unsigned long * const pulCurrentSysTickCount = ( ( volatile unsigned long *) 0xe000e018 ); +volatile unsigned long * const pulInterruptCTRLState = ( ( volatile unsigned long *) 0xe000ed04 ); +const unsigned long ulSysTickPendingBit = 0x04000000UL; + + /* NOTE: There are potentially race conditions here. However, it is used + anyway to keep the examples simple, and to avoid reliance on a separate + timer peripheral. */ + + + /* The SysTick is a down counter. How many clocks have passed since it was + last reloaded? */ + ulSysTickCounts = ulSysTickReloadValue - *pulCurrentSysTickCount; + + /* How many times has it overflowed? */ + ulTickCount = xTaskGetTickCountFromISR(); + + /* This is called from the context switch, so will be called from a + critical section. xTaskGetTickCountFromISR() contains its own critical + section, and the ISR safe critical sections are not designed to nest, + so reset the critical section. */ + portSET_INTERRUPT_MASK_FROM_ISR(); + + /* Is there a SysTick interrupt pending? */ + if( ( *pulInterruptCTRLState & ulSysTickPendingBit ) != 0UL ) + { + /* There is a SysTick interrupt pending, so the SysTick has overflowed + but the tick count not yet incremented. */ + ulTickCount++; + + /* Read the SysTick again, as the overflow might have occurred since + it was read last. */ + ulSysTickCounts = ulSysTickReloadValue - *pulCurrentSysTickCount; + } + + /* Convert the tick count into tenths of a millisecond. THIS ASSUMES + configTICK_RATE_HZ is 1000! */ + ulReturn = ( ulTickCount * 10UL ) ; + + /* Add on the number of tenths of a millisecond that have passed since the + tick count last got updated. */ + ulReturn += ( ulSysTickCounts / ulClocksPer10thOfAMilliSecond ); + + return ulReturn; +} -- 2.39.5