mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-08-11 13:54:16 -04:00
Changed the way the ARM7/9 GCC ports enter interrupts that can cause a context switch.
This commit is contained in:
parent
c54ec1c639
commit
ada7fa862d
24 changed files with 322 additions and 275 deletions
|
@ -163,9 +163,9 @@ const unsigned char ucIPAddress[ 4 ] = { emacIPADDR0, emacIPADDR1, emacIPADDR2,
|
|||
/* See the header file for descriptions of public functions. */
|
||||
|
||||
/*
|
||||
* Prototype for the EMAC interrupt function - called by the asm wrapper.
|
||||
* Prototype for the EMAC interrupt function.
|
||||
*/
|
||||
void vEMACISR( void ) __attribute__ ((naked));
|
||||
void vEMACISR_Wrapper( void ) __attribute__ ((naked));
|
||||
|
||||
/*
|
||||
* Initialise both the Tx and Rx descriptors used by the EMAC.
|
||||
|
@ -666,7 +666,7 @@ static void prvSetupEMACInterrupt( void )
|
|||
AT91C_BASE_EMAC->EMAC_IER = AT91C_EMAC_RCOMP | AT91C_EMAC_TCOMP;
|
||||
|
||||
/* Enable the interrupts in the AIC. */
|
||||
AT91F_AIC_ConfigureIt( AT91C_ID_EMAC, emacINTERRUPT_LEVEL, AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL, ( void (*)( void ) ) vEMACISR );
|
||||
AT91F_AIC_ConfigureIt( AT91C_ID_EMAC, emacINTERRUPT_LEVEL, AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL, ( void (*)( void ) ) vEMACISR_Wrapper );
|
||||
AT91C_BASE_AIC->AIC_IECR = 0x1 << AT91C_ID_EMAC;
|
||||
}
|
||||
portEXIT_CRITICAL();
|
||||
|
|
|
@ -33,18 +33,6 @@
|
|||
***************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
Changes from V3.2.4
|
||||
|
||||
+ Also read the EMAC_RSR register in the EMAC ISR as a work around the
|
||||
the EMAC bug that can reset the RX bit in EMAC_ISR register before the
|
||||
bit has been read.
|
||||
|
||||
Changes from V4.0.1
|
||||
|
||||
+ Only check the interrupt status register to see if an EMAC Tx interrupt
|
||||
has occurred. Previously the TSR register was also inspected.
|
||||
*/
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
@ -58,26 +46,22 @@ Changes from V4.0.1
|
|||
task. */
|
||||
static xSemaphoreHandle xSemaphore = NULL;
|
||||
|
||||
void vEMACISR( void ) __attribute__((naked));
|
||||
/* The interrupt entry point is naked so we can control the context saving. */
|
||||
void vEMACISR_Wrapper( void ) __attribute__((naked));
|
||||
|
||||
/* The interrupt handler function must be separate from the entry function
|
||||
to ensure the correct stack frame is set up. */
|
||||
void vEMACISR_Handler( void );
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
/*
|
||||
* The EMAC ISR. Handles both Tx and Rx complete interrupts.
|
||||
*/
|
||||
void vEMACISR( void )
|
||||
void vEMACISR_Handler( void )
|
||||
{
|
||||
/* This ISR can cause a context switch, so the first statement must be a
|
||||
call to the portENTER_SWITCHING_ISR() macro. This must be BEFORE any
|
||||
variable declarations. */
|
||||
portENTER_SWITCHING_ISR();
|
||||
|
||||
/* Variable definitions can be made now. These must be static. */
|
||||
static volatile unsigned portLONG ulIntStatus, ulEventStatus;
|
||||
static portBASE_TYPE xSwitchRequired;
|
||||
extern void vClearEMACTxBuffer( void );
|
||||
|
||||
/* As the variable is static it must be initialised manually here. */
|
||||
xSwitchRequired = pdFALSE;
|
||||
volatile unsigned portLONG ulIntStatus, ulEventStatus;
|
||||
portBASE_TYPE xSwitchRequired = pdFALSE;
|
||||
extern void vClearEMACTxBuffer( void );
|
||||
|
||||
/* Find the cause of the interrupt. */
|
||||
ulIntStatus = AT91C_BASE_EMAC->EMAC_ISR;
|
||||
|
@ -103,8 +87,27 @@ void vEMACISR( void )
|
|||
AT91C_BASE_AIC->AIC_EOICR = 0;
|
||||
|
||||
/* If a task was woken by either a frame being received then we may need to
|
||||
switch to another task. */
|
||||
portEXIT_SWITCHING_ISR( xSwitchRequired );
|
||||
switch to another task. If the unblocked task was of higher priority then
|
||||
the interrupted task it will then execute immediately that the ISR
|
||||
completes. */
|
||||
if( xSwitchRequired )
|
||||
{
|
||||
portYIELD_FROM_ISR();
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vEMACISR_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. */
|
||||
vEMACISR_Handler();
|
||||
|
||||
/* Restore the context of whichever task will execute next. */
|
||||
portRESTORE_CONTEXT();
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue