From 109b10ed7694ec3655e07c0c5ca101f1e54119a6 Mon Sep 17 00:00:00 2001 From: richardbarry Date: Thu, 30 Jun 2011 14:42:07 +0000 Subject: [PATCH] Comment the peripheral helper files for the new MicroBlaze demo application. git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@1477 1d2547de-c912-0410-9cb9-b8ca96c0e9e2 --- .../SDKProjects/RTOSDemoSource/ParTest.c | 11 ++- .../RTOSDemoSource/RegisterTests.c | 29 ++++---- .../SDKProjects/RTOSDemoSource/serial.c | 71 ++++++++++--------- 3 files changed, 66 insertions(+), 45 deletions(-) diff --git a/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/ParTest.c b/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/ParTest.c index 495804d43..40371814d 100644 --- a/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/ParTest.c +++ b/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/ParTest.c @@ -52,7 +52,7 @@ */ /*----------------------------------------------------------- - * Simple parallel port IO routines. + * Simple digital IO routines. *-----------------------------------------------------------*/ /* Kernel includes. */ @@ -64,13 +64,20 @@ /* Library includes. */ #include "xgpio.h" +/* The hardware design that accompanies this demo project has four LED +outputs. */ #define partstMAX_LED 4 /*-----------------------------------------------------------*/ +/* A hardware specific constant required to use the Xilinx driver library. */ static const unsigned portBASE_TYPE uxGPIOOutputChannel = 1UL; + +/* The current state of the output port. */ static unsigned char ucGPIOState = 0U; +/* Structure that hold the state of the ouptut peripheral used by this demo. +This is used by the Xilinx peripheral driver API functions. */ static XGpio xOutputGPIOInstance; /* @@ -101,6 +108,7 @@ void vParTestSetLED( unsigned portBASE_TYPE uxLED, signed portBASE_TYPE xValue ) { unsigned char ucLED = 1U; + /* Only attempt to set the LED if it is in range. */ if( uxLED < partstMAX_LED ) { ucLED <<= ( unsigned char ) uxLED; @@ -126,6 +134,7 @@ void vParTestToggleLED( unsigned portBASE_TYPE uxLED ) { unsigned char ucLED = 1U; + /* Only attempt to toggle the LED if it is in range. */ if( uxLED < partstMAX_LED ) { ucLED <<= ( unsigned char ) uxLED; diff --git a/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/RegisterTests.c b/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/RegisterTests.c index 906e306db..1aa696a93 100644 --- a/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/RegisterTests.c +++ b/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/RegisterTests.c @@ -56,27 +56,26 @@ #include "task.h" /* - * The register test task as described at the top of this file. + * The register test task as described in the comments at the top of main-full.c. */ void vRegisterTest1( void *pvParameters ); void vRegisterTest2( void *pvParameters ); /* Variables that are incremented on each iteration of the reg test tasks - -provided the tasks have not reported any errors. The check task inspects these +provided the tasks have not reported any errors. The check timer inspects these variables to ensure they are still incrementing as expected. If a variable -stops incrementing then it is likely that its associate task has stalled. */ +stops incrementing then it is likely that its associate task has stalled or +detected an error. */ volatile unsigned long ulRegTest1CycleCount = 0UL, ulRegTest2CycleCount = 0UL; /*-----------------------------------------------------------*/ void vRegisterTest1( void *pvParameters ) { -//_RB_ Why can R5 not be used in this test? - /* This task uses an infinite loop that is implemented in the assembly code. - First fill the registers with known values. */ + First fill the relevant registers with known values. */ asm volatile ( " addi r3, r0, 3 \n\t" \ " addi r4, r0, 4 \n\t" \ " addi r6, r0, 6 \n\t" \ @@ -105,7 +104,10 @@ void vRegisterTest1( void *pvParameters ) /* Now test the register values to ensure they contain the same value that was written to them above. This task will get preempted frequently so other tasks are likely to have executed since the register values were - written. */ + written. If any register contains an unexpected value then the task will + branch to Error_Loop_1, which in turn prevents it from incrementing its + loop counter, enabling the check timer to determine that all is not as it + should be. */ asm volatile ( "Loop_Start_1: \n\t" \ " xori r18, r3, 3 \n\t" \ @@ -157,9 +159,9 @@ void vRegisterTest1( void *pvParameters ) ); /* If this task has not branched to the error loop, then everything is ok, - and the check variable should be incremented to indicate that this task - is still running. Then, brach back to the top to check the registers - again. */ + and the check variable can be incremented to indicate that this task + is still running. Then, brach back to the top to check the register + contents again. */ asm volatile ( " lwi r18, r0, ulRegTest1CycleCount \n\t" \ " addik r18, r18, 1 \n\t" \ " swi r18, r0, ulRegTest1CycleCount \n\t" \ @@ -202,8 +204,13 @@ void vRegisterTest2( void *pvParameters ) "Loop_Start_2: " ); + /* Unlike vRegisterTest1, vRegisterTest2 performs a yield. This increases + the test coverage, but does mean volatile registers need re-loading with + their exepcted values. */ taskYIELD(); + /* taskYIELD() could have changed temporaries - set them back to those + expected by the reg test task. */ asm volatile ( " addi r3, r0, 103 \n\t" \ " addi r4, r0, 104 \n\t" \ " addi r6, r0, 106 \n\t" \ @@ -215,8 +222,6 @@ void vRegisterTest2( void *pvParameters ) " addi r12, r0, 1012 \n\t" \ ); - /* taskYIELD() could have changed temporaries - set them back to those - expected by the reg test task. */ /* Now test the register values to ensure they contain the same value that was written to them above. This task will get preempted frequently so diff --git a/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/serial.c b/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/serial.c index fc67d9b0f..66df57eb7 100644 --- a/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/serial.c +++ b/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/serial.c @@ -52,22 +52,12 @@ */ /* - BASIC INTERRUPT DRIVEN SERIAL PORT DRIVER FOR UART0. - - ***Note*** This example uses queues to send each character into an interrupt - service routine and out of an interrupt service routine individually. This - is done to demonstrate queues being used in an interrupt, and to deliberately - load the system to test the FreeRTOS port. It is *NOT* meant to be an - example of an efficient implementation. An efficient implementation should - use FIFOs or DMA if available, and only use FreeRTOS API functions when - enough has been received to warrant a task being unblocked to process the - data. + BASIC INTERRUPT DRIVEN SERIAL PORT DRIVER FOR a UARTLite peripheral. */ /* Scheduler includes. */ #include "FreeRTOS.h" #include "queue.h" -#include "task.h" /*_RB_ remove this when the file is working. */ #include "comtest_strings.h" /* Library includes. */ @@ -76,27 +66,36 @@ /* Demo application includes. */ #include "serial.h" + /*-----------------------------------------------------------*/ +/* Functions that are installed as the handler for interrupts that are caused by +Rx and Tx events respectively. */ static void prvRxHandler( void *pvUnused, unsigned portBASE_TYPE uxByteCount ); static void prvTxHandler( void *pvUnused, unsigned portBASE_TYPE uxByteCount ); +/* Structure that hold the state of the UARTLite peripheral used by this demo. +This is used by the Xilinx peripheral driver API functions. */ static XUartLite xUartLiteInstance; /* The queue used to hold received characters. */ static xQueueHandle xRxedChars; - /*-----------------------------------------------------------*/ xComPortHandle xSerialPortInitMinimal( unsigned long ulWantedBaud, unsigned portBASE_TYPE uxQueueLength ) { portBASE_TYPE xStatus; + /* The standard demo header file requires a baud rate to be passed into this + function. However, in this case the baud rate is configured when the + hardware is generated, leaving the ulWantedBaud parameter redundant. */ + ( void ) ulWantedBaud; + /* Create the queue used to hold Rx characters. */ xRxedChars = xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE ) sizeof( signed char ) ); - /* If the queue was created correctly then setup the serial port + /* If the queue was created correctly, then setup the serial port hardware. */ if( xRxedChars != NULL ) { @@ -107,10 +106,24 @@ portBASE_TYPE xStatus; /* Complete initialisation of the UART and its associated interrupts. */ XUartLite_ResetFifos( &xUartLiteInstance ); + + /* Install the handlers that the standard Xilinx library interrupt + service routine will call when Rx and Tx events occur + respectively. */ XUartLite_SetRecvHandler( &xUartLiteInstance, ( XUartLite_Handler ) prvRxHandler, NULL ); XUartLite_SetSendHandler( &xUartLiteInstance, ( XUartLite_Handler ) prvTxHandler, NULL ); + + /* Install the standard Xilinx library interrupt handler itself. + *NOTE* The xPortInstallInterruptHandler() API function must be used + for this purpose. */ xStatus = xPortInstallInterruptHandler( XPAR_INTC_0_UARTLITE_1_VEC_ID, ( XInterruptHandler ) XUartLite_InterruptHandler, &xUartLiteInstance ); + + /* Enable the interrupt in the peripheral. */ XUartLite_EnableIntr( xUartLiteInstance.RegBaseAddress ); + + /* Enable the interrupt in the interrupt controller. + *NOTE* The vPortEnableInterrupt() API function must be used for this + purpose. */ vPortEnableInterrupt( XPAR_INTC_0_UARTLITE_1_VEC_ID ); } @@ -128,8 +141,8 @@ portBASE_TYPE xSerialGetChar( xComPortHandle pxPort, signed char *pcRxedChar, po /* The port handle is not required as this driver only supports one port. */ ( void ) pxPort; - /* Get the next character from the buffer. Return false if no characters - are available, or arrive before xBlockTime expires. */ + /* Get the next character from the receive queue. Return false if no + characters are available, or arrive before xBlockTime expires. */ if( xQueueReceive( xRxedChars, pcRxedChar, xBlockTime ) ) { return pdTRUE; @@ -143,44 +156,38 @@ portBASE_TYPE xSerialGetChar( xComPortHandle pxPort, signed char *pcRxedChar, po void vSerialPutString( xComPortHandle pxPort, const signed char * const pcString, unsigned portBASE_TYPE uxStringLength ) { + /* Output uxStringLength bytes starting from pcString. */ XUartLite_Send( &xUartLiteInstance, ( unsigned char * ) pcString, uxStringLength ); } /*-----------------------------------------------------------*/ -signed portBASE_TYPE xSerialPutChar( xComPortHandle pxPort, signed char cOutChar, portTickType xBlockTime ) -{ - /* Only vSerialPutString() is used in this demo. */ - ( void ) pxPort; - ( void ) cOutChar; - ( void ) xBlockTime; - - return pdFALSE; -} -/*-----------------------------------------------------------*/ - -void vSerialClose( xComPortHandle xPort ) -{ - /* Not supported as not required by the demo application. */ -} -/*-----------------------------------------------------------*/ - static void prvRxHandler( void *pvUnused, unsigned portBASE_TYPE uxByteCount ) { signed char cRxedChar; portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; + /* Place any received characters into the receive queue. */ while( XUartLite_IsReceiveEmpty( xUartLiteInstance.RegBaseAddress ) == pdFALSE ) { cRxedChar = XUartLite_ReadReg( xUartLiteInstance.RegBaseAddress, XUL_RX_FIFO_OFFSET); xQueueSendFromISR( xRxedChars, &cRxedChar, &xHigherPriorityTaskWoken ); } + /* If calling xQueueSendFromISR() caused a task to unblock, and the task + that unblocked has a priority equal to or greater than the task currently + in the Running state (the task that was interrupted), then + xHigherPriorityTaskWoken will have been set to pdTRUE internally within the + xQueueSendFromISR() API function. If xHigherPriorityTaskWoken is equal to + pdTRUE then a context switch should be requested to ensure that the + interrupt returns to the highest priority task that is able to run. */ portYIELD_FROM_ISR( xHigherPriorityTaskWoken ); } /*-----------------------------------------------------------*/ static void prvTxHandler( void *pvUnused, unsigned portBASE_TYPE uxByteCount ) { + /* Nothing to do here. The Xilinx library function takes care of the + transmission. */ portNOP(); } -- 2.39.5