From 1f5e2a944c79ba622701077c4b0850eb4c60950d Mon Sep 17 00:00:00 2001 From: Richard Barry Date: Mon, 4 Jul 2011 18:13:09 +0000 Subject: [PATCH] Add vSemaphoreDelete(), xTaskGetIdleTaskHandle(), xTimerGetTimerTaskHandle() API functions. Change vTickISR() to vPortTickISR(). Partially comment portmacro.h. All for the new MicroBlaze port. --- .../FreeRTOS_Source/include/semphr.h | 13 +++ .../FreeRTOS_Source/include/task.h | 10 ++- .../FreeRTOS_Source/include/timers.h | 9 ++ .../portable/GCC/MicroBlaze/port.c | 2 +- .../portable/GCC/MicroBlaze/portmacro.h | 89 ++++++++++++++++++- .../RTOSDemoSource/FreeRTOS_Source/tasks.c | 30 ++++++- .../RTOSDemoSource/FreeRTOS_Source/timers.c | 32 ++++++- 7 files changed, 178 insertions(+), 7 deletions(-) diff --git a/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/FreeRTOS_Source/include/semphr.h b/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/FreeRTOS_Source/include/semphr.h index 0130f1d79..3ccce2726 100644 --- a/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/FreeRTOS_Source/include/semphr.h +++ b/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/FreeRTOS_Source/include/semphr.h @@ -711,6 +711,19 @@ typedef xQueueHandle xSemaphoreHandle; */ #define xSemaphoreCreateCounting( uxMaxCount, uxInitialCount ) xQueueCreateCountingSemaphore( ( uxMaxCount ), ( uxInitialCount ) ) +/** + * semphr. h + *
void vSemaphoreDelete( xSemaphoreHandle xSemaphore );
+ * + * Delete a semaphore. This function must be used with care. For example, + * do not delete a mutex type semaphore if the mutex is held by a task. + * + * @param xSemaphore A handle to the semaphore to be deleted. + * + * \page vSemaphoreDelete vSemaphoreDelete + * \ingroup Semaphores + */ +#define vSemaphoreDelete( xSemaphore ) vQueueDelete( ( xQueueHandle ) xSemaphore ) #endif /* SEMAPHORE_H */ diff --git a/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/FreeRTOS_Source/include/task.h b/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/FreeRTOS_Source/include/task.h index 781e1d457..670d13d43 100644 --- a/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/FreeRTOS_Source/include/task.h +++ b/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/FreeRTOS_Source/include/task.h @@ -202,7 +202,7 @@ typedef struct xTASK_PARAMTERS *
  portBASE_TYPE xTaskCreate(
 							  pdTASK_CODE pvTaskCode,
-							  const char * const pcName,
+							  const signed char * const pcName,
 							  unsigned short usStackDepth,
 							  void *pvParameters,
 							  unsigned portBASE_TYPE uxPriority,
@@ -1170,6 +1170,14 @@ constant. */
  */
 portBASE_TYPE xTaskCallApplicationTaskHook( xTaskHandle xTask, void *pvParameter ) PRIVILEGED_FUNCTION;
 
+/**
+ * xTaskGetIdleTaskHandle() is only available if 
+ * INCLUDE_xTaskGetIdleTaskHandle is set to 1 in FreeRTOSConfig.h.
+ *
+ * Simply returns the handle of the idle task.  It is not valid to call
+ * xTaskGetIdleTaskHandle() before the scheduler has been started.
+ */
+xTaskHandle xTaskGetIdleTaskHandle( void );
 
 /*-----------------------------------------------------------
  * SCHEDULER INTERNALS AVAILABLE FOR PORTING PURPOSES
diff --git a/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/FreeRTOS_Source/include/timers.h b/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/FreeRTOS_Source/include/timers.h
index 3faef90d8..578f05b43 100644
--- a/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/FreeRTOS_Source/include/timers.h
+++ b/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/FreeRTOS_Source/include/timers.h
@@ -283,6 +283,15 @@ void *pvTimerGetTimerID( xTimerHandle xTimer ) PRIVILEGED_FUNCTION;
  */
 portBASE_TYPE xTimerIsTimerActive( xTimerHandle xTimer ) PRIVILEGED_FUNCTION;
 
+/**
+ * xTimerGetTimerTaskHandle() is only available if 
+ * INCLUDE_xTimerGetTimerTaskHandle is set to 1 in FreeRTOSConfig.h.
+ *
+ * Simply returns the handle of the timer service/daemon task.  It it not valid
+ * to call xTimerGetTimerTaskHandle() before the scheduler has been started.
+ */
+xTaskHandle xTimerGetTimerTaskHandle( void );
+
 /**
  * portBASE_TYPE xTimerStart( xTimerHandle xTimer, portTickType xBlockTime );
  *
diff --git a/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/FreeRTOS_Source/portable/GCC/MicroBlaze/port.c b/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/FreeRTOS_Source/portable/GCC/MicroBlaze/port.c
index 63fdb467a..77b330129 100644
--- a/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/FreeRTOS_Source/portable/GCC/MicroBlaze/port.c
+++ b/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/FreeRTOS_Source/portable/GCC/MicroBlaze/port.c
@@ -396,7 +396,7 @@ long lReturn;
  * Handler for the timer interrupt.  This is the handler that the application
  * defined callback function vApplicationSetupTimerInterrupt() should install.
  */
-void vTickISR( void *pvUnused )
+void vPortTickISR( void *pvUnused )
 {
 extern void vApplicationClearTimerInterrupt( void );
 
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 cf89cc985..940dd7936 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
@@ -96,8 +96,82 @@ void microblaze_enable_interrupts( void );
 #define portDISABLE_INTERRUPTS()	microblaze_disable_interrupts()
 #define portENABLE_INTERRUPTS()		microblaze_enable_interrupts()
 
+/*
+ * Installs pxHandler as the interrupt handler for the peripheral specified by 
+ * the ucInterruptID parameter.
+ *
+ * ucInterruptID:
+ * 
+ * The ID of the peripheral that will have pxHandler assigned as its interrupt
+ * handler.  Peripheral IDs are defined in the xparameters.h header file, which 
+ * is itself part of the BSP project.  For example, in the official demo 
+ * application for this port, xparameters.h defines the following IDs for the 
+ * four possible interrupt sources:
+ *
+ * XPAR_INTC_0_UARTLITE_1_VEC_ID  -  for the UARTlite peripheral.
+ * XPAR_INTC_0_TMRCTR_0_VEC_ID    -  for the AXI Timer 0 peripheral.
+ * XPAR_INTC_0_EMACLITE_0_VEC_ID  -  for the Ethernet lite peripheral.
+ * XPAR_INTC_0_GPIO_1_VEC_ID      -  for the button inputs.
+ *
+ *
+ * pxHandler:
+ * 
+ * A pointer to the interrupt handler function itself.  This must be a void
+ * function that takes a (void *) parameter.
+ *
+ *
+ * pvCallBackRef:
+ *
+ * The parameter passed into the handler function.  In many cases this will not
+ * be used and can be NULL.  Some times it is used to pass in a reference to
+ * the peripheral instance variable, so it can be accessed from inside the
+ * handler function.
+ *
+ * 
+ * pdPASS is returned if the function executes successfully.  Any other value
+ * being returned indicates that the function did not execute correctly.
+ */
 portBASE_TYPE xPortInstallInterruptHandler( unsigned char ucInterruptID, XInterruptHandler pxHandler, void *pvCallBackRef );
+
+
+/*
+ * Enables the interrupt, within the interrupt controller, for the peripheral 
+ * specified by the ucInterruptID parameter.
+ *
+ * ucInterruptID:
+ * 
+ * The ID of the peripheral that will have its interrupt enabled in the
+ * interrupt controller.  Peripheral IDs are defined in the xparameters.h header 
+ * file, which is itself part of the BSP project.  For example, in the official 
+ * demo application for this port, xparameters.h defines the following IDs for 
+ * the four possible interrupt sources:
+ *
+ * XPAR_INTC_0_UARTLITE_1_VEC_ID  -  for the UARTlite peripheral.
+ * XPAR_INTC_0_TMRCTR_0_VEC_ID    -  for the AXI Timer 0 peripheral.
+ * XPAR_INTC_0_EMACLITE_0_VEC_ID  -  for the Ethernet lite peripheral.
+ * XPAR_INTC_0_GPIO_1_VEC_ID      -  for the button inputs.
+ *
+ */
 void vPortEnableInterrupt( unsigned char ucInterruptID );
+
+/*
+ * Disables the interrupt, within the interrupt controller, for the peripheral 
+ * specified by the ucInterruptID parameter.
+ *
+ * ucInterruptID:
+ * 
+ * The ID of the peripheral that will have its interrupt disabled in the
+ * interrupt controller.  Peripheral IDs are defined in the xparameters.h header 
+ * file, which is itself part of the BSP project.  For example, in the official 
+ * demo application for this port, xparameters.h defines the following IDs for 
+ * the four possible interrupt sources:
+ *
+ * XPAR_INTC_0_UARTLITE_1_VEC_ID  -  for the UARTlite peripheral.
+ * XPAR_INTC_0_TMRCTR_0_VEC_ID    -  for the AXI Timer 0 peripheral.
+ * XPAR_INTC_0_EMACLITE_0_VEC_ID  -  for the Ethernet lite peripheral.
+ * XPAR_INTC_0_GPIO_1_VEC_ID      -  for the button inputs.
+ *
+ */
 void vPortDisableInterrupt( unsigned char ucInterruptID );
 
 void vApplicationSetupTimerInterrupt( void );
@@ -128,11 +202,16 @@ void vPortExitCritical( void );
 
 /*-----------------------------------------------------------*/
 
-/* Task utilities. */
+/* The yield macro maps directly to the vPortYield() function. */
 void vPortYield( void );
 #define portYIELD() vPortYield()
 
-void vTaskSwitchContext();
+/* portYIELD_FROM_ISR() does not directly call vTaskSwitchContext(), but instead
+sets a flag to say that a yield has been requested.  The interrupt exit code
+then checks this flag, and calls vTaskSwitchContext() before restoring a task
+context, if the flag is not false.  This is done to prevent multiple calls to
+vTaskSwitchContext() being made from a single interrupt, as a single interrupt
+can result in multiple peripherals being serviced. */
 extern volatile unsigned long ulTaskSwitchRequested;
 #define portYIELD_FROM_ISR( x ) if( x != pdFALSE ) ulTaskSwitchRequested = 1
 /*-----------------------------------------------------------*/
@@ -147,7 +226,11 @@ extern volatile unsigned long ulTaskSwitchRequested;
 /* Task function macros as described on the FreeRTOS.org WEB site. */
 #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
 #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
+/*-----------------------------------------------------------*/
 
+/* The following structure is used by the FreeRTOS exception handler.  It is
+filled with the MicroBlaze context as it was at the time the exception occurred.
+This is done as an aid to debugging exception occurrences. */
 typedef struct PORT_REGISTER_DUMP
 {
 	/* The following structure members hold the values of the MicroBlaze
@@ -168,7 +251,7 @@ typedef struct PORT_REGISTER_DUMP
 	unsigned long ulR14_return_address_from_interrupt;
 	unsigned long ulR15_return_address_from_subroutine;
 	unsigned long ulR16_return_address_from_trap;
-	unsigned long ulR17_return_address_from_exceptions; /* The exception entry code can copy the BTR in here for exceptions that occur in the delay slot of branch instructions. */
+	unsigned long ulR17_return_address_from_exceptions; /* The exception entry code will copy the BTR into R17 if the exception occurred in the delay slot of a branch instruction. */
 	unsigned long ulR18;
 	unsigned long ulR19;
 	unsigned long ulR20;
diff --git a/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/FreeRTOS_Source/tasks.c b/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/FreeRTOS_Source/tasks.c
index 056f557ef..d8b397bd3 100644
--- a/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/FreeRTOS_Source/tasks.c
+++ b/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/FreeRTOS_Source/tasks.c
@@ -157,6 +157,12 @@ PRIVILEGED_DATA static xList xPendingReadyList;							/*< Tasks that have been r
 
 #endif
 
+#if ( INCLUDE_xTaskGetIdleTaskHandle == 1 )
+	
+	PRIVILEGED_DATA static xTaskHandle xIdleTaskHandle = NULL;
+	
+#endif
+
 /* File private variables. --------------------------------*/
 PRIVILEGED_DATA static volatile unsigned portBASE_TYPE uxCurrentNumberOfTasks 	= ( unsigned portBASE_TYPE ) 0;
 PRIVILEGED_DATA static volatile portTickType xTickCount 						= ( portTickType ) 0;
@@ -1090,7 +1096,18 @@ void vTaskStartScheduler( void )
 portBASE_TYPE xReturn;
 
 	/* Add the idle task at the lowest priority. */
-	xReturn = xTaskCreate( prvIdleTask, ( signed char * ) "IDLE", tskIDLE_STACK_SIZE, ( void * ) NULL, ( tskIDLE_PRIORITY | portPRIVILEGE_BIT ), ( xTaskHandle * ) NULL );
+	#if ( INCLUDE_xTaskGetIdleTaskHandle == 1 )
+	{
+		/* Create the idle task, storing its handle in xIdleTaskHandle so it can
+		be returned by the xTaskGetIdleTaskhandle() function. */
+		xReturn = xTaskCreate( prvIdleTask, ( signed char * ) "IDLE", tskIDLE_STACK_SIZE, ( void * ) NULL, ( tskIDLE_PRIORITY | portPRIVILEGE_BIT ), &xIdleTaskHandle );
+	}
+	#else
+	{
+		/* Create the idle task without storing its handle. */
+		xReturn = xTaskCreate( prvIdleTask, ( signed char * ) "IDLE", tskIDLE_STACK_SIZE, ( void * ) NULL, ( tskIDLE_PRIORITY | portPRIVILEGE_BIT ), NULL );
+	}
+	#endif
 
 	#if ( configUSE_TIMERS == 1 )
 	{
@@ -1466,8 +1483,19 @@ tskTCB *pxTCB;
 	}
 
 #endif
+/*----------------------------------------------------------*/
 
+#if ( INCLUDE_xTaskGetIdleTaskHandle == 1 )
 
+	xTaskHandle xTaskGetIdleTaskHandle( void )
+	{
+		/* If xTaskGetIdleTaskHandle() is called before the scheduler has been
+		started, then xIdleTaskHandle will be NULL. */
+		configASSERT( ( xIdleTaskHandle != NULL ) );
+		return xIdleTaskHandle;
+	}
+	
+#endif
 
 /*-----------------------------------------------------------
  * SCHEDULER INTERNALS AVAILABLE FOR PORTING PURPOSES
diff --git a/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/FreeRTOS_Source/timers.c b/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/FreeRTOS_Source/timers.c
index 7e5ef22ad..2d3f3bad8 100644
--- a/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/FreeRTOS_Source/timers.c
+++ b/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/FreeRTOS_Source/timers.c
@@ -110,6 +110,12 @@ PRIVILEGED_DATA static xList *pxOverflowTimerList;
 /* A queue that is used to send commands to the timer service task. */
 PRIVILEGED_DATA static xQueueHandle xTimerQueue = NULL;
 
+#if ( INCLUDE_xTimerGetTimerTaskHandle == 1 )
+	
+	PRIVILEGED_DATA static xTaskHandle xTimerTaskHandle = NULL;
+	
+#endif
+
 /*-----------------------------------------------------------*/
 
 /*
@@ -183,7 +189,18 @@ portBASE_TYPE xReturn = pdFAIL;
 
 	if( xTimerQueue != NULL )
 	{
-		xReturn = xTaskCreate( prvTimerTask, ( const signed char * ) "Tmr Svc", ( unsigned short ) configTIMER_TASK_STACK_DEPTH, NULL, ( unsigned portBASE_TYPE ) configTIMER_TASK_PRIORITY, NULL);
+		#if ( INCLUDE_xTimerGetTimerTaskHandle == 1 )
+		{
+			/* Create the timer task, storing its handle in xTimerTaskHandle so
+			it can be returned by the xTimerGetTimerTaskHandle() function. */
+			xReturn = xTaskCreate( prvTimerTask, ( const signed char * ) "Tmr Svc", ( unsigned short ) configTIMER_TASK_STACK_DEPTH, NULL, ( unsigned portBASE_TYPE ) configTIMER_TASK_PRIORITY, &xTimerTaskHandle );	
+		}
+		#else
+		{
+			/* Create the timer task without storing its handle. */
+			xReturn = xTaskCreate( prvTimerTask, ( const signed char * ) "Tmr Svc", ( unsigned short ) configTIMER_TASK_STACK_DEPTH, NULL, ( unsigned portBASE_TYPE ) configTIMER_TASK_PRIORITY, NULL);
+		}
+		#endif
 	}
 
 	configASSERT( xReturn );
@@ -267,6 +284,19 @@ xTIMER_MESSAGE xMessage;
 }
 /*-----------------------------------------------------------*/
 
+#if ( INCLUDE_xTimerGetTimerTaskHandle == 1 )
+
+	xTaskHandle xTimerGetTimerTaskHandle( void )
+	{
+		/* If xTimerGetTimerTaskHandle() is called before the scheduler has been
+		started, then xTimerTaskHandle will be NULL. */
+		configASSERT( ( xTimerTaskHandle != NULL ) );
+		return xTimerTaskHandle;
+	}
+	
+#endif
+/*-----------------------------------------------------------*/
+
 static void prvProcessExpiredTimer( portTickType xNextExpireTime, portTickType xTimeNow )
 {
 xTIMER *pxTimer;