From e27b5c20f9dcd8588427b70cc33cfab7dc55993d Mon Sep 17 00:00:00 2001 From: richardbarry Date: Sun, 19 Jun 2011 21:19:33 +0000 Subject: [PATCH] Add in the comtest test tasks to the MicroBlaze demo. git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@1468 1d2547de-c912-0410-9cb9-b8ca96c0e9e2 --- .../Demo_Source/comtest_strings.c | 132 ++++++++++-------- .../Demo_Source/include/serial.h | 2 +- .../portable/GCC/MicroBlaze/portmacro.h | 2 +- .../SDKProjects/RTOSDemoSource/main-full.c | 7 + .../SDKProjects/RTOSDemoSource/serial.c | 105 ++++---------- 5 files changed, 109 insertions(+), 139 deletions(-) diff --git a/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/Demo_Source/comtest_strings.c b/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/Demo_Source/comtest_strings.c index 7a84768fb..c1354e986 100644 --- a/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/Demo_Source/comtest_strings.c +++ b/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/Demo_Source/comtest_strings.c @@ -161,6 +161,9 @@ size_t xStringLength; xStringLength = strlen( comTRANSACTED_STRING ); + /* Include the null terminator in the string length. */ + xStringLength++; + for( ;; ) { /* Send the string. Setting the last parameter to pdTRUE ensures @@ -192,83 +195,90 @@ size_t xStringLength; } /*-----------------------------------------------------------*/ +#define comtstWAITING_START_OF_STRING 0 +#define comtstWAITING_END_OF_STRING 1 + + static void vComRxTask( void *pvParameters ) { -#if 0 -signed char cExpectedByte, cByteRxed; -portBASE_TYPE xResyncRequired = pdFALSE, xErrorOccurred = pdFALSE; +portBASE_TYPE xState = comtstWAITING_START_OF_STRING, xErrorOccurred = pdFALSE; +char *pcExpectedByte, cRxedChar; +const xComPortHandle xPort = NULL; + /* Just to stop compiler warnings. */ ( void ) pvParameters; + pcExpectedByte = comTRANSACTED_STRING; + for( ;; ) { - /* We expect to receive the characters from comFIRST_BYTE to - comLAST_BYTE in an incrementing order. Loop to receive each byte. */ - for( cExpectedByte = comFIRST_BYTE; cExpectedByte <= comLAST_BYTE; cExpectedByte++ ) + /* Wait for the next character. */ + if( xSerialGetChar( xPort, &cRxedChar, ( comTX_MAX_BLOCK_TIME * 2 ) ) == pdFALSE ) { - /* Block on the queue that contains received bytes until a byte is - available. */ - if( xSerialGetChar( xPort, &cByteRxed, comRX_BLOCK_TIME ) ) - { - /* Was this the byte we were expecting? If so, toggle the LED, - otherwise we are out on sync and should break out of the loop - until the expected character sequence is about to restart. */ - if( cByteRxed == cExpectedByte ) + /* A character definitely should have been received by now. As a + character was not received an error must have occurred (which might + just be that the loopback connector is not fitted. */ + xErrorOccurred = pdTRUE; + } + + switch( xState ) + { + case comtstWAITING_START_OF_STRING: + if( cRxedChar == *pcExpectedByte ) { - vParTestToggleLED( uxBaseLED + comRX_LED_OFFSET ); + /* 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 ); + } + + /* Go back to wait for the start of the next string. */ + pcExpectedByte = comTRANSACTED_STRING; + xState = comtstWAITING_START_OF_STRING; + } + else + { + /* Wait for the next character in the string. */ + pcExpectedByte++; + } } else { - xResyncRequired = pdTRUE; - break; /*lint !e960 Non-switch break allowed. */ + /* The character received was not that expected. */ + xErrorOccurred = pdTRUE; } - } - } - - /* Turn the LED off while we are not doing anything. */ - vParTestSetLED( uxBaseLED + comRX_LED_OFFSET, pdFALSE ); + break; - /* 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; + default: + /* Should not get here. Stop the Rx loop counter from + incrementing to latch the error. */ + xErrorOccurred = pdTRUE; + break; } - else - { - if( xErrorOccurred < comTOTAL_PERMISSIBLE_ERRORS ) - { - /* Increment the count of successful loops. As error - occurring (i.e. an unexpected character being received) will - prevent this counter being incremented for the rest of the - execution. Don't worry about mutual exclusion on this - variable - it doesn't really matter as we just want it - to change. */ - uxRxLoops++; - } - } - } -#else - for( ;; ) - { - vTaskDelay( 10000 ); } -#endif } /*-----------------------------------------------------------*/ @@ -289,7 +299,7 @@ portBASE_TYPE xReturn; } /* 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; return xReturn; diff --git a/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/Demo_Source/include/serial.h b/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/Demo_Source/include/serial.h index b7d27f90d..71433b81e 100644 --- a/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/Demo_Source/include/serial.h +++ b/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/Demo_Source/include/serial.h @@ -114,7 +114,7 @@ typedef enum 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 ); -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 xSerialPutChar( xComPortHandle pxPort, signed char cOutChar, portTickType xBlockTime ); portBASE_TYPE xSerialWaitForSemaphore( xComPortHandle xPort ); diff --git a/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/FreeRTOS_Source/portable/GCC/MicroBlaze/portmacro.h b/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/FreeRTOS_Source/portable/GCC/MicroBlaze/portmacro.h index 37aa3d607..15d9a0202 100644 --- a/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/FreeRTOS_Source/portable/GCC/MicroBlaze/portmacro.h +++ b/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/FreeRTOS_Source/portable/GCC/MicroBlaze/portmacro.h @@ -130,7 +130,7 @@ void vPortYield( void ); #define portYIELD() vPortYield() 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. */ diff --git a/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/main-full.c b/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/main-full.c index 9833ea7db..ed0792e80 100644 --- a/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/main-full.c +++ b/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/main-full.c @@ -388,6 +388,13 @@ static long lErrorAlreadyLatched = pdFALSE; pcStatusMessage = "Error: Flop\r\n"; xPrintf( pcStatusMessage ); } + + if( xAreComTestTasksStillRunning() != pdPASS ) + { + pcStatusMessage = "Error: Comtest\r\n"; + xPrintf( pcStatusMessage ); + } + /* Check the reg test tasks are still cycling. They will stop incrementing their loop counters if they encounter an error. */ if( ulRegTest1CycleCount == ulLastRegTest1CycleCount ) diff --git a/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/serial.c b/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/serial.c index bf3d36dba..605da484a 100644 --- a/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/serial.c +++ b/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/serial.c @@ -67,7 +67,6 @@ /* Scheduler includes. */ #include "FreeRTOS.h" #include "queue.h" -#include "semphr.h" #include "task.h" /*_RB_ remove this when the file is working. */ #include "comtest_strings.h" @@ -79,42 +78,34 @@ #include "serial.h" /*-----------------------------------------------------------*/ -/* Misc defines. */ -#define serINVALID_QUEUE ( ( xQueueHandle ) 0 ) -#define serNO_BLOCK ( ( portTickType ) 0 ) +static void prvRxHandler( 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; -static xQueueHandle xCharsForTx; -static XUartLite xUartLiteInstance; - -static void prvRxHandler( void *pvUnused, unsigned portBASE_TYPE uxByteCount ); -static void prvTxHandler( void *pvUnused, unsigned portBASE_TYPE uxByteCount ); /*-----------------------------------------------------------*/ -/* - * See the serial2.h header file. - */ xComPortHandle xSerialPortInitMinimal( unsigned long ulWantedBaud, unsigned portBASE_TYPE uxQueueLength ) { 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 ) ); - 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. */ - if( ( xRxedChars != serINVALID_QUEUE ) && ( xCharsForTx != serINVALID_QUEUE ) ) + if( xRxedChars != NULL ) { xStatus = XUartLite_Initialize( &xUartLiteInstance, XPAR_UARTLITE_1_DEVICE_ID ); if( xStatus == XST_SUCCESS ) { + /* Complete initialisation of the UART and its associated + interrupts. */ XUartLite_ResetFifos( &xUartLiteInstance ); XUartLite_SetRecvHandler( &xUartLiteInstance, ( XUartLite_Handler ) prvRxHandler, 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 ) { -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. */ ( void ) pxPort; @@ -154,66 +138,23 @@ extern u8 XUartLite_RecvByte(u32 BaseAddress); { 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 ); - -#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 + XUartLite_Send( &xUartLiteInstance, ( unsigned char * ) pcString, uxStringLength ); } /*-----------------------------------------------------------*/ signed portBASE_TYPE xSerialPutChar( xComPortHandle pxPort, signed char cOutChar, portTickType xBlockTime ) { -#if 1 - extern void XUartLite_SendByte(u32 BaseAddress, u8 Data); - -// for( ;; ) -// { - 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; - } + /* Only vSerialPutString() is used in this demo. */ + ( void ) pxPort; + ( void ) cOutChar; + ( void ) xBlockTime; - return xReturn; -#endif + return pdFALSE; } /*-----------------------------------------------------------*/ @@ -225,7 +166,16 @@ void vSerialClose( xComPortHandle xPort ) 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. */ } /*-----------------------------------------------------------*/ @@ -238,4 +188,7 @@ static void prvTxHandler( void *pvUnused, unsigned portBASE_TYPE uxByteCount ) + + + -- 2.39.5