mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-04-19 21:11:57 -04:00
Convert SmartFusion2 CLI to use the interrupt UART driver functions instead of the polled UART driver functions.
This commit is contained in:
parent
5ff880fee8
commit
063c05ccad
|
@ -50,6 +50,7 @@
|
|||
</option>
|
||||
<option id="gnu.c.compiler.option.misc.verbose.1351799799" name="Verbose (-v)" superClass="gnu.c.compiler.option.misc.verbose" value="true" valueType="boolean"/>
|
||||
<option id="gnu.c.compiler.option.optimization.flags.435998408" name="Other optimization flags" superClass="gnu.c.compiler.option.optimization.flags" value="-ffunction-sections -fdata-sections" valueType="string"/>
|
||||
<option id="gnu.c.compiler.option.misc.other.1001754914" superClass="gnu.c.compiler.option.misc.other" value="-c -fmessage-length=0 -Wextra" valueType="string"/>
|
||||
<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.2036217646" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
|
||||
</tool>
|
||||
<tool id="cdt.managedbuild.tool.gnu.cpp.compiler.cross.cortexm3.exe.debug.612642130" name="GNU C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.cross.cortexm3.exe.debug">
|
||||
|
|
|
@ -98,18 +98,14 @@
|
|||
#include <stdint.h>
|
||||
extern uint32_t SystemCoreClock;
|
||||
|
||||
/* Driver includes required for UART IO. */
|
||||
#include "drivers/mss_uart/mss_uart.h"
|
||||
extern const mss_uart_instance_t * const pxUART;
|
||||
|
||||
#define configUSE_PREEMPTION 1
|
||||
#define configUSE_IDLE_HOOK 1
|
||||
#define configUSE_TICK_HOOK 0
|
||||
#define configCPU_CLOCK_HZ ( SystemCoreClock )
|
||||
#define configTICK_RATE_HZ ( ( portTickType ) 1000 )
|
||||
#define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 5 )
|
||||
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 130 )
|
||||
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 27648 ) )
|
||||
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 80 )
|
||||
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 25000 ) )
|
||||
#define configMAX_TASK_NAME_LEN ( 10 )
|
||||
#define configUSE_TRACE_FACILITY 1
|
||||
#define configUSE_16_BIT_TICKS 0
|
||||
|
|
|
@ -58,7 +58,7 @@
|
|||
/* FreeRTOS includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "semphr.h"
|
||||
#include "queue.h"
|
||||
|
||||
/* Driver includes. */
|
||||
#include "drivers/mss_uart/mss_uart.h"
|
||||
|
@ -73,6 +73,11 @@
|
|||
/* The maximum time in ticks to wait for the UART access mutex. */
|
||||
#define cmdMAX_MUTEX_WAIT ( 200 / portTICK_RATE_MS )
|
||||
|
||||
/* Characters are only ever received slowly on the CLI so it is ok to pass
|
||||
received characters from the UART interrupt to the task on a queue. This sets
|
||||
the length of the queue used for that purpose. */
|
||||
#define cmdRXED_CHARS_QUEUE_LENGTH ( 10 )
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
|
@ -80,6 +85,19 @@
|
|||
*/
|
||||
static void prvUARTCommandConsoleTask( void *pvParameters );
|
||||
|
||||
/*
|
||||
* Ensure a previous interrupt driven Tx has completed before sending the next
|
||||
* data block to the UART.
|
||||
*/
|
||||
static void prvSendBuffer( const 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.
|
||||
*/
|
||||
static void prvConfigureUART( void );
|
||||
static void prvUARTRxNotificationHandler( mss_uart_instance_t * this_uart );
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Const messages output by the command console. */
|
||||
|
@ -87,10 +105,24 @@ static const uint8_t * const pcWelcomeMessage = ( uint8_t * ) "\r\n\r\nFreeRTOS
|
|||
static const uint8_t * const pcEndOfOutputMessage = ( uint8_t * ) "\r\n[Press ENTER to execute the previous command again]\r\n>";
|
||||
static const uint8_t * const pcNewLine = ( uint8_t * ) "\r\n";
|
||||
|
||||
/* The UART used by the CLI. */
|
||||
static const mss_uart_instance_t * const pxUART = &g_mss_uart0;
|
||||
static const IRQn_Type xUART_IRQ = UART0_IRQn;
|
||||
|
||||
/* Because characters are received slowly (at the speed somebody can type) then
|
||||
it is ok to pass received characters from the Rx interrupt to the task on a
|
||||
queue. This is the queue used for that purpose. */
|
||||
static xQueueHandle xRxedChars = NULL;
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vUARTCommandConsoleStart( uint16_t usStackSize, unsigned portBASE_TYPE uxPriority )
|
||||
{
|
||||
/* A UART is used for printf() output and CLI input and output. Note there
|
||||
is no mutual exclusion on the UART, but the demo as it stands does not
|
||||
require mutual exclusion. */
|
||||
prvConfigureUART();
|
||||
|
||||
/* 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. */
|
||||
|
@ -106,7 +138,6 @@ static void prvUARTCommandConsoleTask( void *pvParameters )
|
|||
int8_t cRxedChar, cInputIndex = 0, *pcOutputString;
|
||||
static int8_t cInputString[ cmdMAX_INPUT_SIZE ], cLastInputString[ cmdMAX_INPUT_SIZE ];
|
||||
portBASE_TYPE xReturned;
|
||||
mss_uart_instance_t * const pxUART = &g_mss_uart0;
|
||||
|
||||
( void ) pvParameters;
|
||||
|
||||
|
@ -116,24 +147,21 @@ mss_uart_instance_t * const pxUART = &g_mss_uart0;
|
|||
pcOutputString = FreeRTOS_CLIGetOutputBuffer();
|
||||
|
||||
/* Send the welcome message. */
|
||||
MSS_UART_polled_tx_string( pxUART, ( uint8_t * ) pcWelcomeMessage );
|
||||
prvSendBuffer( pcWelcomeMessage, strlen( ( char * ) pcWelcomeMessage ) );
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
/* No characters received yet for the current input string. */
|
||||
cRxedChar = 0;
|
||||
|
||||
/* Only interested in reading one character at a time. */
|
||||
if( MSS_UART_get_rx( pxUART, ( uint8_t * ) &cRxedChar, sizeof( cRxedChar ) ) > 0 )
|
||||
/* Wait for the next character to arrive. */
|
||||
if( xQueueReceive( xRxedChars, &cRxedChar, portMAX_DELAY ) == pdPASS )
|
||||
{
|
||||
/* Echo the character back. */
|
||||
MSS_UART_polled_tx( pxUART, ( uint8_t * ) &cRxedChar, sizeof( cRxedChar ) );
|
||||
prvSendBuffer( ( uint8_t * ) &cRxedChar, sizeof( cRxedChar ) );
|
||||
|
||||
/* Was it the end of the line? */
|
||||
if( cRxedChar == '\n' || cRxedChar == '\r' )
|
||||
{
|
||||
/* Just to space the output from the input. */
|
||||
MSS_UART_polled_tx_string( pxUART, ( uint8_t * ) pcNewLine );
|
||||
prvSendBuffer( ( uint8_t * ) pcNewLine, strlen( ( char * ) pcNewLine ) );
|
||||
|
||||
/* See if the command is empty, indicating that the last command is
|
||||
to be executed again. */
|
||||
|
@ -153,8 +181,7 @@ mss_uart_instance_t * const pxUART = &g_mss_uart0;
|
|||
xReturned = FreeRTOS_CLIProcessCommand( cInputString, pcOutputString, configCOMMAND_INT_MAX_OUTPUT_SIZE );
|
||||
|
||||
/* Write the generated string to the UART. */
|
||||
MSS_UART_polled_tx_string( pxUART, ( uint8_t * ) pcOutputString );
|
||||
vTaskDelay( 1 );
|
||||
prvSendBuffer( ( uint8_t * ) pcOutputString, strlen( ( char * ) pcOutputString ) );
|
||||
|
||||
} while( xReturned != pdFALSE );
|
||||
|
||||
|
@ -166,7 +193,7 @@ mss_uart_instance_t * const pxUART = &g_mss_uart0;
|
|||
cInputIndex = 0;
|
||||
memset( cInputString, 0x00, cmdMAX_INPUT_SIZE );
|
||||
|
||||
MSS_UART_polled_tx_string( pxUART, ( uint8_t * ) pcEndOfOutputMessage );
|
||||
prvSendBuffer( ( uint8_t * ) pcEndOfOutputMessage, strlen( ( char * ) pcEndOfOutputMessage ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -204,3 +231,60 @@ mss_uart_instance_t * const pxUART = &g_mss_uart0;
|
|||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvSendBuffer( const uint8_t * pcBuffer, size_t xBufferLength )
|
||||
{
|
||||
const portTickType xVeryShortDelay = 2UL;
|
||||
|
||||
MSS_UART_irq_tx( ( mss_uart_instance_t * ) pxUART, pcBuffer, xBufferLength );
|
||||
|
||||
/* Ensure any previous transmissions have completed. The default UART
|
||||
interrupt does not provide an event based method of signally the end of a Tx
|
||||
- this is therefore a crude poll of the Tx end status. Replacing the
|
||||
default UART handler with one that 'gives' a semaphore when the Tx is
|
||||
complete would allow this poll loop to be replaced by a simple semaphore
|
||||
block. */
|
||||
while( MSS_UART_tx_complete( ( mss_uart_instance_t * ) pxUART ) == pdFALSE )
|
||||
{
|
||||
vTaskDelay( xVeryShortDelay );
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvConfigureUART( void )
|
||||
{
|
||||
/* Initialise the UART which is used for printf() and CLI IO. */
|
||||
MSS_UART_init( ( mss_uart_instance_t * ) pxUART, MSS_UART_115200_BAUD, MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT );
|
||||
|
||||
/* Characters are only ever received slowly on the CLI so it is ok to pass
|
||||
received characters from the UART interrupt to the task on a queue. Create
|
||||
the queue used for that purpose. */
|
||||
xRxedChars = xQueueCreate( cmdRXED_CHARS_QUEUE_LENGTH, sizeof( char ) );
|
||||
|
||||
/* The interrupt handler makes use of FreeRTOS API functions, so its
|
||||
priority must be at or below the configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY
|
||||
setting (the higher the numeric priority, the lower the logical priority). */
|
||||
NVIC_SetPriority( xUART_IRQ, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY );
|
||||
|
||||
/* Set the UART Rx notification function. */
|
||||
MSS_UART_set_rx_handler( ( mss_uart_instance_t * ) pxUART, prvUARTRxNotificationHandler, MSS_UART_FIFO_SINGLE_BYTE );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvUARTRxNotificationHandler( mss_uart_instance_t * pxUART )
|
||||
{
|
||||
uint8_t cRxed;
|
||||
portBASE_TYPE xHigherPriorityTaskWoken;
|
||||
|
||||
/* The command console receives data very slowly (at the speed of somebody
|
||||
typing), therefore it is ok to just handle one character at a time and use
|
||||
a queue to send the characters to the task. */
|
||||
if( MSS_UART_get_rx( pxUART, &cRxed, sizeof( cRxed ) ) == sizeof( cRxed ) )
|
||||
{
|
||||
xHigherPriorityTaskWoken = pdFALSE;
|
||||
xQueueSendFromISR( xRxedChars, &cRxed, &xHigherPriorityTaskWoken );
|
||||
|
||||
/* portEND_SWITCHING_ISR() or portYIELD_FROM_ISR() can be used here. */
|
||||
portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -104,6 +104,21 @@
|
|||
* been discovered. If the green LED toggles every 200ms, then an issue has
|
||||
* been discovered with at least one task.
|
||||
*
|
||||
* FreeRTOS+CLI command console. The command console is access through UART0
|
||||
* using 115200 baud and the Microsemi MSS UART drivers. Type "help" to see a
|
||||
* list of registered commands, which include some basic file system commands
|
||||
* (see FreeRTOS+FAT SL comments below). The FreeRTOS+CLI license is different
|
||||
* to the FreeRTOS license, see http://www.FreeRTOS.org/cli for license and
|
||||
* usage details.
|
||||
*
|
||||
* FreeRTOS+FAT SL. FreeRTOS+FAT SL is demonstrated using a RAM disk. [At the
|
||||
* time of writing] The functionality of the file system demo is identical to
|
||||
* the functionality of the FreeRTOS Win32 simulator file system demo with the
|
||||
* command console being accessed via the UART (as described above) instead of
|
||||
* a network terminal. The FreeRTOS+FAT SL license is different to the FreeRTOS
|
||||
* license, see http://www.FreeRTOS.org/fat_sl for license and usage details,
|
||||
* and a description of the file system demo functionality.
|
||||
*
|
||||
* See the documentation page for this demo on the FreeRTOS.org web site for
|
||||
* full information, including hardware setup requirements.
|
||||
*/
|
||||
|
@ -115,7 +130,7 @@
|
|||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "timers.h"
|
||||
#include "semphr.h"
|
||||
#include "queue.h"
|
||||
|
||||
/* Standard demo application includes. */
|
||||
#include "integer.h"
|
||||
|
@ -163,7 +178,7 @@ standard demo flash timers. */
|
|||
|
||||
/* The size of the stack and the priority used by the UART command console
|
||||
task. */
|
||||
#define mainUART_COMMAND_CONSOLE_STACK_SIZE ( configMINIMAL_STACK_SIZE * 3 )
|
||||
#define mainUART_COMMAND_CONSOLE_STACK_SIZE ( configMINIMAL_STACK_SIZE * 2 )
|
||||
#define mainUART_COMMAND_CONSOLE_TASK_PRIORITY ( tskIDLE_PRIORITY )
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
@ -180,31 +195,28 @@ static void prvCheckTimerCallback( xTimerHandle xTimer );
|
|||
extern void vRegisterSampleCLICommands( void );
|
||||
extern void vRegisterFileSystemCLICommands( void );
|
||||
|
||||
/* Prepare to run the full demo: Configure the IO, register the CLI
|
||||
* commands, and depending on configuration, generate a set of sample files on
|
||||
* a RAM disk.
|
||||
*/
|
||||
static void prvPrepareForFullDemo( void );
|
||||
|
||||
/*
|
||||
* Creates and verifies different files on the volume, demonstrating the use of
|
||||
* various different API functions.
|
||||
*/
|
||||
extern void vCreateAndVerifySampleFiles( void );
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void main_full( void )
|
||||
{
|
||||
xTimerHandle xCheckTimer = NULL;
|
||||
|
||||
/* If the file system is only going to be accessed from one task then
|
||||
F_FS_THREAD_AWARE can be set to 0 and the set of example files are created
|
||||
before the RTOS scheduler is started. If the file system is going to be
|
||||
access from more than one task then F_FS_THREAD_AWARE must be set to 1 and
|
||||
the set of sample files are created from the idle task hook function
|
||||
vApplicationIdleHook() - which is defined in this file. */
|
||||
#if F_FS_THREAD_AWARE == 0
|
||||
{
|
||||
/* Initialise the drive and file system, then create a few example
|
||||
files. The output from this function just goes to the stdout window,
|
||||
allowing the output to be viewed when the UDP command console is not
|
||||
connected. */
|
||||
vCreateAndVerifySampleFiles();
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Register both the standard and file system related CLI commands. */
|
||||
vRegisterSampleCLICommands();
|
||||
vRegisterFileSystemCLICommands();
|
||||
/* Prepare to run the full demo: Configure the IO, register the CLI
|
||||
commands, and depending on configuration, generate a set of sample files on
|
||||
a RAM disk. */
|
||||
prvPrepareForFullDemo();
|
||||
|
||||
/* Start all the other standard demo/test tasks. The have not particular
|
||||
functionality, but do demonstrate how to use the FreeRTOS API and test the
|
||||
|
@ -331,3 +343,25 @@ unsigned long ulErrorFound = pdFALSE;
|
|||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvPrepareForFullDemo( void )
|
||||
{
|
||||
/* If the file system is only going to be accessed from one task then
|
||||
F_FS_THREAD_AWARE can be set to 0 and the set of example files are created
|
||||
before the RTOS scheduler is started. If the file system is going to be
|
||||
access from more than one task then F_FS_THREAD_AWARE must be set to 1 and
|
||||
the set of sample files are created from the idle task hook function
|
||||
vApplicationIdleHook() - which is defined in this file. */
|
||||
#if F_FS_THREAD_AWARE == 0
|
||||
{
|
||||
/* Initialise the drive and file system, then create a few example
|
||||
files. The output from this function just goes to the stdout window,
|
||||
allowing the output to be viewed when the UDP command console is not
|
||||
connected. */
|
||||
vCreateAndVerifySampleFiles();
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Register both the standard and file system related CLI commands. */
|
||||
vRegisterSampleCLICommands();
|
||||
vRegisterFileSystemCLICommands();
|
||||
}
|
||||
|
|
|
@ -119,8 +119,6 @@ void vApplicationIdleHook( void );
|
|||
void vApplicationStackOverflowHook( xTaskHandle pxTask, signed char *pcTaskName );
|
||||
void vApplicationTickHook( void );
|
||||
|
||||
/* The UART used for printf() and CLI IO. */
|
||||
const mss_uart_instance_t * const pxUART = &g_mss_uart0;
|
||||
/*-----------------------------------------------------------*/
|
||||
/* See the documentation page for this demo on the FreeRTOS.org web site for
|
||||
full information - including hardware setup requirements. */
|
||||
|
@ -152,9 +150,6 @@ static void prvSetupHardware( void )
|
|||
functions. The name ParTest is now somewhat obsolete - originally it
|
||||
stood for PARallel port Test. */
|
||||
vParTestInitialise();
|
||||
|
||||
/* Initialise the UART which is used for printf() and CLI IO. */
|
||||
MSS_UART_init( pxUART, MSS_UART_115200_BAUD, MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ static void printchar(char **str, int c)
|
|||
}
|
||||
else
|
||||
{
|
||||
MSS_UART_polled_tx( pxUART, ( uint8_t * ) &c, sizeof( uint8_t ) );
|
||||
/* Output char here. */
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue