Add in the comtest test tasks to the MicroBlaze demo.

This commit is contained in:
Richard Barry 2011-06-19 21:19:33 +00:00
parent 7b24b4c30c
commit a4de9fa8f6
5 changed files with 112 additions and 142 deletions

View file

@ -161,6 +161,9 @@ size_t xStringLength;
xStringLength = strlen( comTRANSACTED_STRING ); xStringLength = strlen( comTRANSACTED_STRING );
/* Include the null terminator in the string length. */
xStringLength++;
for( ;; ) for( ;; )
{ {
/* Send the string. Setting the last parameter to pdTRUE ensures /* Send the string. Setting the last parameter to pdTRUE ensures
@ -192,84 +195,91 @@ size_t xStringLength;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#define comtstWAITING_START_OF_STRING 0
#define comtstWAITING_END_OF_STRING 1
static void vComRxTask( void *pvParameters ) static void vComRxTask( void *pvParameters )
{ {
#if 0 portBASE_TYPE xState = comtstWAITING_START_OF_STRING, xErrorOccurred = pdFALSE;
signed char cExpectedByte, cByteRxed; char *pcExpectedByte, cRxedChar;
portBASE_TYPE xResyncRequired = pdFALSE, xErrorOccurred = pdFALSE; const xComPortHandle xPort = NULL;
/* Just to stop compiler warnings. */ /* Just to stop compiler warnings. */
( void ) pvParameters; ( void ) pvParameters;
pcExpectedByte = comTRANSACTED_STRING;
for( ;; ) for( ;; )
{ {
/* We expect to receive the characters from comFIRST_BYTE to /* Wait for the next character. */
comLAST_BYTE in an incrementing order. Loop to receive each byte. */ if( xSerialGetChar( xPort, &cRxedChar, ( comTX_MAX_BLOCK_TIME * 2 ) ) == pdFALSE )
for( cExpectedByte = comFIRST_BYTE; cExpectedByte <= comLAST_BYTE; cExpectedByte++ )
{ {
/* Block on the queue that contains received bytes until a byte is /* A character definitely should have been received by now. As a
available. */ character was not received an error must have occurred (which might
if( xSerialGetChar( xPort, &cByteRxed, comRX_BLOCK_TIME ) ) just be that the loopback connector is not fitted. */
xErrorOccurred = pdTRUE;
}
switch( xState )
{ {
/* Was this the byte we were expecting? If so, toggle the LED, case comtstWAITING_START_OF_STRING:
otherwise we are out on sync and should break out of the loop if( cRxedChar == *pcExpectedByte )
until the expected character sequence is about to restart. */
if( cByteRxed == cExpectedByte )
{ {
/* The received character was the first character of the
string. Move to the next state to check each character
as it comes in until the entire string has been received. */
xState = comtstWAITING_END_OF_STRING;
pcExpectedByte++;
}
break;
case comtstWAITING_END_OF_STRING:
if( cRxedChar == *pcExpectedByte )
{
/* The received character was the expected character. Was
it the last character in the string - i.e. the null
terminator? */
if( cRxedChar == 0x00 )
{
/* The entire string has been received. If no errors
have been latched, then increment the loop counter to
show that this task is still healthy. */
if( xErrorOccurred == pdFALSE )
{
uxRxLoops++;
/* Toggle an LED to give a visible sign that a
complete string has been received. */
vParTestToggleLED( uxBaseLED + comRX_LED_OFFSET ); vParTestToggleLED( uxBaseLED + comRX_LED_OFFSET );
} }
else
{
xResyncRequired = pdTRUE;
break; /*lint !e960 Non-switch break allowed. */
}
}
}
/* Turn the LED off while we are not doing anything. */ /* Go back to wait for the start of the next string. */
vParTestSetLED( uxBaseLED + comRX_LED_OFFSET, pdFALSE ); pcExpectedByte = comTRANSACTED_STRING;
xState = comtstWAITING_START_OF_STRING;
/* Did we break out of the loop because the characters were received in
an unexpected order? If so wait here until the character sequence is
about to restart. */
if( xResyncRequired == pdTRUE )
{
while( cByteRxed != comLAST_BYTE )
{
/* Block until the next char is available. */
xSerialGetChar( xPort, &cByteRxed, comRX_BLOCK_TIME );
}
/* Note that an error occurred which caused us to have to resync.
We use this to stop incrementing the loop counter so
sAreComTestTasksStillRunning() will return false - indicating an
error. */
xErrorOccurred++;
/* We have now resynced with the Tx task and can continue. */
xResyncRequired = pdFALSE;
} }
else else
{ {
if( xErrorOccurred < comTOTAL_PERMISSIBLE_ERRORS ) /* Wait for the next character in the string. */
pcExpectedByte++;
}
}
else
{ {
/* Increment the count of successful loops. As error /* The character received was not that expected. */
occurring (i.e. an unexpected character being received) will xErrorOccurred = pdTRUE;
prevent this counter being incremented for the rest of the }
execution. Don't worry about mutual exclusion on this break;
variable - it doesn't really matter as we just want it
to change. */ default:
uxRxLoops++; /* Should not get here. Stop the Rx loop counter from
incrementing to latch the error. */
xErrorOccurred = pdTRUE;
break;
} }
} }
} }
#else
for( ;; )
{
vTaskDelay( 10000 );
}
#endif
}
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
portBASE_TYPE xAreComTestTasksStillRunning( void ) portBASE_TYPE xAreComTestTasksStillRunning( void )
@ -289,7 +299,7 @@ portBASE_TYPE xReturn;
} }
/* Reset the count of successful Rx loops. When this function is called /* Reset the count of successful Rx loops. When this function is called
again we expect this to have been incremented. */ again it should have been incremented. */
uxRxLoops = comINITIAL_RX_COUNT_VALUE; uxRxLoops = comINITIAL_RX_COUNT_VALUE;
return xReturn; return xReturn;

View file

@ -114,7 +114,7 @@ typedef enum
xComPortHandle xSerialPortInitMinimal( unsigned long ulWantedBaud, unsigned portBASE_TYPE uxQueueLength ); xComPortHandle xSerialPortInitMinimal( unsigned long ulWantedBaud, unsigned portBASE_TYPE uxQueueLength );
xComPortHandle xSerialPortInit( eCOMPort ePort, eBaud eWantedBaud, eParity eWantedParity, eDataBits eWantedDataBits, eStopBits eWantedStopBits, unsigned portBASE_TYPE uxBufferLength ); xComPortHandle xSerialPortInit( eCOMPort ePort, eBaud eWantedBaud, eParity eWantedParity, eDataBits eWantedDataBits, eStopBits eWantedStopBits, unsigned portBASE_TYPE uxBufferLength );
void vSerialPutString( xComPortHandle pxPort, const signed char * const pcString, unsigned short usStringLength ); void vSerialPutString( xComPortHandle pxPort, const signed char * const pcString, unsigned portBASE_TYPE uxStringLength );
signed portBASE_TYPE xSerialGetChar( xComPortHandle pxPort, signed char *pcRxedChar, portTickType xBlockTime ); signed portBASE_TYPE xSerialGetChar( xComPortHandle pxPort, signed char *pcRxedChar, portTickType xBlockTime );
signed portBASE_TYPE xSerialPutChar( xComPortHandle pxPort, signed char cOutChar, portTickType xBlockTime ); signed portBASE_TYPE xSerialPutChar( xComPortHandle pxPort, signed char cOutChar, portTickType xBlockTime );
portBASE_TYPE xSerialWaitForSemaphore( xComPortHandle xPort ); portBASE_TYPE xSerialWaitForSemaphore( xComPortHandle xPort );

View file

@ -130,7 +130,7 @@ void vPortYield( void );
#define portYIELD() vPortYield() #define portYIELD() vPortYield()
void vTaskSwitchContext(); void vTaskSwitchContext();
#define portYIELD_FROM_ISR( x ) if( x != pdFALSE ) vTaskSwitchContext() #define portYIELD_FROM_ISR( x ) if( x != pdFALSE ) vTaskSwitchContext() //_RB_ This needs re-implementing so it does not get called multiple times as multiple peripherals are servied in a single ISR. */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Hardware specifics. */ /* Hardware specifics. */

View file

@ -388,6 +388,13 @@ static long lErrorAlreadyLatched = pdFALSE;
pcStatusMessage = "Error: Flop\r\n"; pcStatusMessage = "Error: Flop\r\n";
xPrintf( pcStatusMessage ); xPrintf( pcStatusMessage );
} }
if( xAreComTestTasksStillRunning() != pdPASS )
{
pcStatusMessage = "Error: Comtest\r\n";
xPrintf( pcStatusMessage );
}
/* Check the reg test tasks are still cycling. They will stop incrementing /* Check the reg test tasks are still cycling. They will stop incrementing
their loop counters if they encounter an error. */ their loop counters if they encounter an error. */
if( ulRegTest1CycleCount == ulLastRegTest1CycleCount ) if( ulRegTest1CycleCount == ulLastRegTest1CycleCount )

View file

@ -67,7 +67,6 @@
/* Scheduler includes. */ /* Scheduler includes. */
#include "FreeRTOS.h" #include "FreeRTOS.h"
#include "queue.h" #include "queue.h"
#include "semphr.h"
#include "task.h" /*_RB_ remove this when the file is working. */ #include "task.h" /*_RB_ remove this when the file is working. */
#include "comtest_strings.h" #include "comtest_strings.h"
@ -79,42 +78,34 @@
#include "serial.h" #include "serial.h"
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* 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;
static XUartLite xUartLiteInstance;
static void prvRxHandler( void *pvUnused, unsigned portBASE_TYPE uxByteCount ); static void prvRxHandler( void *pvUnused, unsigned portBASE_TYPE uxByteCount );
static void prvTxHandler( void *pvUnused, unsigned portBASE_TYPE uxByteCount ); static void prvTxHandler( void *pvUnused, unsigned portBASE_TYPE uxByteCount );
static XUartLite xUartLiteInstance;
/* The queue used to hold received characters. */
static xQueueHandle xRxedChars;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/*
* See the serial2.h header file.
*/
xComPortHandle xSerialPortInitMinimal( unsigned long ulWantedBaud, unsigned portBASE_TYPE uxQueueLength ) xComPortHandle xSerialPortInitMinimal( unsigned long ulWantedBaud, unsigned portBASE_TYPE uxQueueLength )
{ {
portBASE_TYPE xStatus; portBASE_TYPE xStatus;
/* Create the queues used to hold Rx/Tx characters. */ /* Create the queue used to hold Rx characters. */
xRxedChars = xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE ) sizeof( signed char ) ); 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 /* If the queue was created correctly then setup the serial port
hardware. */ hardware. */
if( ( xRxedChars != serINVALID_QUEUE ) && ( xCharsForTx != serINVALID_QUEUE ) ) if( xRxedChars != NULL )
{ {
xStatus = XUartLite_Initialize( &xUartLiteInstance, XPAR_UARTLITE_1_DEVICE_ID ); xStatus = XUartLite_Initialize( &xUartLiteInstance, XPAR_UARTLITE_1_DEVICE_ID );
if( xStatus == XST_SUCCESS ) if( xStatus == XST_SUCCESS )
{ {
/* Complete initialisation of the UART and its associated
interrupts. */
XUartLite_ResetFifos( &xUartLiteInstance ); XUartLite_ResetFifos( &xUartLiteInstance );
XUartLite_SetRecvHandler( &xUartLiteInstance, ( XUartLite_Handler ) prvRxHandler, NULL ); XUartLite_SetRecvHandler( &xUartLiteInstance, ( XUartLite_Handler ) prvRxHandler, NULL );
XUartLite_SetSendHandler( &xUartLiteInstance, ( XUartLite_Handler ) prvTxHandler, NULL ); XUartLite_SetSendHandler( &xUartLiteInstance, ( XUartLite_Handler ) prvTxHandler, NULL );
@ -134,13 +125,6 @@ portBASE_TYPE xStatus;
portBASE_TYPE xSerialGetChar( xComPortHandle pxPort, signed char *pcRxedChar, portTickType xBlockTime ) portBASE_TYPE xSerialGetChar( xComPortHandle pxPort, signed char *pcRxedChar, portTickType xBlockTime )
{ {
extern u8 XUartLite_RecvByte(u32 BaseAddress);
// *pcRxedChar = XUartLite_RecvByte( xUartLiteInstance.RegBaseAddress );
vTaskDelay( 1000 );
return pdTRUE;
#if 0
/* The port handle is not required as this driver only supports one port. */ /* The port handle is not required as this driver only supports one port. */
( void ) pxPort; ( void ) pxPort;
@ -154,66 +138,23 @@ extern u8 XUartLite_RecvByte(u32 BaseAddress);
{ {
return pdFALSE; return pdFALSE;
} }
#endif
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vSerialPutString( xComPortHandle pxPort, const signed char * const pcString, unsigned short usStringLength ) void vSerialPutString( xComPortHandle pxPort, const signed char * const pcString, unsigned portBASE_TYPE uxStringLength )
{ {
XUartLite_Send( &xUartLiteInstance, ( unsigned char * ) pcString, ( unsigned portBASE_TYPE ) usStringLength ); XUartLite_Send( &xUartLiteInstance, ( unsigned char * ) pcString, uxStringLength );
#if 0
unsigned portBASE_TYPE uxReturn = 0U;
char *pc = pc;
extern void XUartLite_SendByte(u32 BaseAddress, u8 Data);
/* Just to avoid compiler warnings. */
( void ) pxPort;
while( uxReturn != usStringLength )
{
XUartLite_SendByte( xUartLiteInstance.RegBaseAddress, *pc );
pc++;
uxReturn++;
// uxReturn += XUartLite_Send( &xUartLiteInstance, ( unsigned char * ) pcString, ( ( unsigned portBASE_TYPE ) usStringLength ) - uxReturn );
while( XUartLite_IsSending( &xUartLiteInstance ) != pdFALSE )
{
/*_RB_ This function is not yet written to make use of the RTOS. */
}
}
#endif
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
signed portBASE_TYPE xSerialPutChar( xComPortHandle pxPort, signed char cOutChar, portTickType xBlockTime ) signed portBASE_TYPE xSerialPutChar( xComPortHandle pxPort, signed char cOutChar, portTickType xBlockTime )
{ {
#if 1 /* Only vSerialPutString() is used in this demo. */
extern void XUartLite_SendByte(u32 BaseAddress, u8 Data); ( void ) pxPort;
( void ) cOutChar;
( void ) xBlockTime;
// for( ;; ) return pdFALSE;
// {
XUartLite_SendByte( xUartLiteInstance.RegBaseAddress, cOutChar );
// }
// vTaskDelay( 2 );
return 1;
#else
signed portBASE_TYPE xReturn;
if( xQueueSend( xCharsForTx, &cOutChar, xBlockTime ) == pdPASS )
{
xReturn = pdPASS;
/* Enable the UART Tx interrupt. */
XUartLite_EnableIntr( xUartLiteInstance.RegBaseAddress );
}
else
{
xReturn = pdFAIL;
}
return xReturn;
#endif
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -225,7 +166,16 @@ void vSerialClose( xComPortHandle xPort )
static void prvRxHandler( void *pvUnused, unsigned portBASE_TYPE uxByteCount ) static void prvRxHandler( void *pvUnused, unsigned portBASE_TYPE uxByteCount )
{ {
portNOP(); signed char cRxedChar;
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
while( XUartLite_IsReceiveEmpty( xUartLiteInstance.RegBaseAddress ) == pdFALSE )
{
cRxedChar = XUartLite_ReadReg( xUartLiteInstance.RegBaseAddress, XUL_RX_FIFO_OFFSET);
xQueueSendFromISR( xRxedChars, &cRxedChar, &xHigherPriorityTaskWoken );
}
portYIELD_FROM_ISR( xHigherPriorityTaskWoken ); //_RB_ This needs re-implementing so it does not get called multiple times as multiple peripherals are servied in a single ISR. */
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -239,3 +189,6 @@ static void prvTxHandler( void *pvUnused, unsigned portBASE_TYPE uxByteCount )