Content originally posted in LPCWare by tvink on Fri Feb 06 11:57:43 MST 2015
Below is the main console task in CDCCommandConsole.c with some "vTaskDelay( 1 )" added.
I played around with this proceedure a lot commenting stuff out and back in, looking for memcpy() that may have run away, etc. Everything looked good except it started feeling like timing somehow. Even with the main command processing commented out it would fail after I pressed CR on the CLI with only a few tries. It never failed with just holding an alpha key down on the CLI.
I noticed a 1 tick delay after one of the USB_WriteEP() calls.
So I put a similar delay after each USB_WriteEP() call in this procedure.
I have not seen a failure since. 200+ runs of task-stats and 200+ runs of ip-config. These would fail after only a few.
What do you think?
static void prvCDCCommandConsoleTask( void *pvParameters )
{
char cRxedChar;
uint8_t ucInputIndex = 0;
char *pcOutputString;
static char cInputString[ cmdMAX_INPUT_SIZE ], cLastInputString[ cmdMAX_INPUT_SIZE ];
BaseType_t xReturned;
( void ) pvParameters;
/* Obtain the address of the output buffer. Note there is no mutual
exclusion on this buffer as it is assumed only one command console
interface will be used at any one time. */
pcOutputString = FreeRTOS_CLIGetOutputBuffer();
/* Initialise the virtual com port (CDC) interface. */
prvSetupUSBDrivers();
/* Send the welcome message. This probably won't be seen as the console
will not have been connected yet. */
USB_WriteEP( CDC_DEP_IN, ( uint8_t * ) pcWelcomeMessage, strlen( pcWelcomeMessage ) );
vTaskDelay( 1 ); // 777
for( ;; )
{
/* No characters received yet for the current input string. */
cRxedChar = 0;
/* Only interested in reading one character at a time. */
cRxedChar = cGetCDCChar();
if( xSemaphoreTake( xCDCMutex, cmdMAX_MUTEX_WAIT ) == pdPASS )
{
/* Echo the character back. */
USB_WriteEP( CDC_DEP_IN, ( uint8_t * ) &cRxedChar, sizeof( uint8_t ) );
vTaskDelay( 1 ); // 777
/* Was it the end of the line? */
if( cRxedChar == '\n' || cRxedChar == '\r' )
{
/* Just to space the output from the input. */
USB_WriteEP( CDC_DEP_IN, ( uint8_t * ) pcNewLine, strlen( pcNewLine ) );
vTaskDelay( 1 ); // 777
/* See if the command is empty, indicating that the last command is
to be executed again. */
if( ucInputIndex == 0 )
{
/* Copy the last command back into the input string. */
strcpy( cInputString, cLastInputString );
}
/* Pass the received command to the command interpreter. The
command interpreter is called repeatedly until it returns pdFALSE
(indicating there is no more output) as it might generate more than
one string. */
do
{
/* Get the next output string from the command interpreter. */
xReturned = FreeRTOS_CLIProcessCommand( cInputString, pcOutputString, configCOMMAND_INT_MAX_OUTPUT_SIZE );
/* Write the generated string to the CDC. */
USB_WriteEP( CDC_DEP_IN, ( uint8_t * ) pcOutputString, strlen( pcOutputString ) );
vTaskDelay( 1 ); // 777 was 1
} while( xReturned != pdFALSE );
/* All the strings generated by the input command have been sent.
Clear the inputstring ready to receive the next command. Remember
the command that was just processed first in case it is to be
processed again. */
strcpy( cLastInputString, cInputString );
ucInputIndex = 0;
memset( cInputString, 0x00, cmdMAX_INPUT_SIZE );
USB_WriteEP( CDC_DEP_IN, ( uint8_t * ) pcEndOfOutputMessage, strlen( pcEndOfOutputMessage ) );
vTaskDelay( 1 ); // 777 put a delay here too
}
else
{
if( cRxedChar == '\r' )
{
/* Ignore the character. */
}
else if( cRxedChar == '\b' )
{
/* Backspace was pressed. Erase the last character in the
string - if any. */
if( ucInputIndex > 0 )
{
ucInputIndex--;
cInputString[ ucInputIndex ] = '\0';
}
}
else
{
/* A character was entered. Add it to the string
entered so far. When a \n is entered the complete
string will be passed to the command interpreter. */
if( ( cRxedChar >= ' ' ) && ( cRxedChar <= '~' ) )
{
if( ucInputIndex < cmdMAX_INPUT_SIZE )
{
cInputString[ ucInputIndex ] = cRxedChar;
ucInputIndex++;
}
}
}
}
/* Must ensure to give the mutex back. */
xSemaphoreGive( xCDCMutex );
}
}
}