Changed the way the ARM7/9 GCC ports enter interrupts that can cause a context switch.

This commit is contained in:
Richard Barry 2007-10-28 13:55:35 +00:00
parent c54ec1c639
commit ada7fa862d
24 changed files with 322 additions and 275 deletions

View file

@ -699,7 +699,7 @@ static void vDetachUSBInterface( void)
static void vInitUSBInterface( void )
{
extern void ( vUSB_ISR )( void );
extern void ( vUSB_ISR_Wrapper )( void );
/* Create the queue used to communicate between the USB ISR and task. */
xUSBInterruptQueue = xQueueCreate( usbQUEUE_LENGTH + 1, sizeof( xISRStatus * ) );
@ -759,7 +759,7 @@ extern void ( vUSB_ISR )( void );
/* Enable the USB interrupts - other interrupts get enabled as the
enumeration process progresses. */
AT91F_AIC_ConfigureIt( AT91C_ID_UDP, usbINTERRUPT_PRIORITY, AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL, ( void (*)( void ) ) vUSB_ISR );
AT91F_AIC_ConfigureIt( AT91C_ID_UDP, usbINTERRUPT_PRIORITY, AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL, ( void (*)( void ) ) vUSB_ISR_Wrapper );
AT91C_BASE_AIC->AIC_IECR = 0x1 << AT91C_ID_UDP;

View file

@ -59,27 +59,20 @@ extern xQueueHandle xUSBInterruptQueue;
/*-----------------------------------------------------------*/
/* The ISR can cause a context switch so is declared naked. */
void vUSB_ISR( void ) __attribute__ ((naked));
void vUSB_ISR_Wrapper( void ) __attribute__ ((naked));
/* The function that actually performs the ISR work. This must be separate
from the wrapper function to ensure the correct stack frame gets set up. */
void vUSB_ISR_Handler( void );
/*-----------------------------------------------------------*/
void vUSB_ISR( void )
void vUSB_ISR_Handler( void )
{
/* This ISR can cause a context switch. Therefore a call to the
portENTER_SWITCHING_ISR() macro is made. This must come BEFORE any
stack variable declarations. */
portENTER_SWITCHING_ISR();
/* Now variables can be declared. These must be static. */
static portCHAR cTaskWokenByPost;
static volatile unsigned portLONG ulNextMessage = 0;
static xISRStatus *pxMessage;
static unsigned portLONG ulRxBytes;
static unsigned portCHAR ucFifoIndex;
/* As the variables are static they must be initialised manually here. */
cTaskWokenByPost = pdFALSE;
portCHAR cTaskWokenByPost = pdFALSE;
static volatile unsigned portLONG ulNextMessage = 0;
xISRStatus *pxMessage;
unsigned portLONG ulRxBytes;
unsigned portCHAR ucFifoIndex;
/* Use the next message from the array. */
pxMessage = &( xISRMessages[ ( ulNextMessage & usbQUEUE_LENGTH ) ] );
@ -158,6 +151,27 @@ void vUSB_ISR( void )
AT91C_BASE_AIC->AIC_EOICR = 0;
/* Do a task switch if needed */
portEXIT_SWITCHING_ISR( cTaskWokenByPost )
if( cTaskWokenByPost )
{
/* This call will ensure that the unblocked task will be executed
immediately upon completion of the ISR if it has a priority higher
than the interrupted task. */
portYIELD_FROM_ISR();
}
}
/*-----------------------------------------------------------*/
void vUSB_ISR_Wrapper( void )
{
/* Save the context of the interrupted task. */
portSAVE_CONTEXT();
/* Call the handler to do the work. This must be a separate
function to ensure the stack frame is set up correctly. */
vUSB_ISR_Handler();
/* Restore the context of whichever task will execute next. */
portRESTORE_CONTEXT();
}