mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-08-19 17:48:33 -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
|
@ -56,7 +56,7 @@
|
|||
#define configTICK_RATE_HZ ( ( portTickType ) 1000 )
|
||||
#define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 5 )
|
||||
#define configMINIMAL_STACK_SIZE ( ( unsigned portSHORT ) 128 )
|
||||
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 23 * 1024 ) )
|
||||
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 24 * 1024 ) )
|
||||
#define configMAX_TASK_NAME_LEN ( 16 )
|
||||
#define configUSE_TRACE_FACILITY 0
|
||||
#define configUSE_16_BIT_TICKS 0
|
||||
|
|
|
@ -130,9 +130,9 @@
|
|||
/* Priorities for the demo application tasks. */
|
||||
#define mainLED_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 )
|
||||
#define mainCOM_TEST_PRIORITY ( tskIDLE_PRIORITY + 2 )
|
||||
#define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 )
|
||||
#define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 0 )
|
||||
#define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 4 )
|
||||
#define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 )
|
||||
#define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 0 )
|
||||
#define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2 )
|
||||
|
||||
/* The rate at which the on board LED will toggle when there is/is not an
|
||||
|
@ -247,6 +247,7 @@ xTaskHandle xCreatedTask;
|
|||
parameter. */
|
||||
ulMemCheckTaskRunningCount = mainCOUNT_INITIAL_VALUE;
|
||||
xCreatedTask = mainNO_TASK;
|
||||
|
||||
if( xTaskCreate( vMemCheckTask, ( signed portCHAR * ) "MEM_CHECK", configMINIMAL_STACK_SIZE, ( void * ) &ulMemCheckTaskRunningCount, tskIDLE_PRIORITY, &xCreatedTask ) != pdPASS )
|
||||
{
|
||||
/* Could not create the task - we have probably run out of heap. */
|
||||
|
|
|
@ -118,7 +118,7 @@ xComPortHandle xSerialPortInitMinimal( unsigned portLONG ulWantedBaud, unsigned
|
|||
{
|
||||
unsigned portLONG ulDivisor, ulWantedClock;
|
||||
xComPortHandle xReturn = serHANDLE;
|
||||
extern void ( vUART_ISR )( void );
|
||||
extern void ( vUART_ISR_Wrapper )( void );
|
||||
|
||||
/* The queues are used in the serial ISR routine, so are created from
|
||||
serialISR.c (which is always compiled to ARM mode. */
|
||||
|
@ -153,7 +153,7 @@ extern void ( vUART_ISR )( void );
|
|||
/* Setup the VIC for the UART. */
|
||||
VICIntSelect &= ~( serUART0_VIC_CHANNEL_BIT );
|
||||
VICIntEnable |= serUART0_VIC_CHANNEL_BIT;
|
||||
VICVectAddr1 = ( portLONG ) vUART_ISR;
|
||||
VICVectAddr1 = ( portLONG ) vUART_ISR_Wrapper;
|
||||
VICVectCntl1 = serUART0_VIC_CHANNEL | serUART0_VIC_ENABLE;
|
||||
|
||||
/* Enable UART0 interrupts. */
|
||||
|
|
|
@ -80,9 +80,11 @@ static volatile portLONG lTHREEmpty;
|
|||
*/
|
||||
void vSerialISRCreateQueues( unsigned portBASE_TYPE uxQueueLength, xQueueHandle *pxRxedChars, xQueueHandle *pxCharsForTx, portLONG volatile **pplTHREEmptyFlag );
|
||||
|
||||
/* UART0 interrupt service routine. This can cause a context switch so MUST
|
||||
be declared "naked". */
|
||||
void vUART_ISR( void ) __attribute__ ((naked));
|
||||
/* UART0 interrupt service routine entry point. */
|
||||
void vUART_ISR_Wrapper( void ) __attribute__ ((naked));
|
||||
|
||||
/* UART0 interrupt service routine handler. */
|
||||
void vUART_ISR_Handler( void );
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
void vSerialISRCreateQueues( unsigned portBASE_TYPE uxQueueLength, xQueueHandle *pxRxedChars,
|
||||
|
@ -103,20 +105,24 @@ void vSerialISRCreateQueues( unsigned portBASE_TYPE uxQueueLength, xQueueHandle
|
|||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vUART_ISR( void )
|
||||
void vUART_ISR_Wrapper( 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();
|
||||
/* Save the context of the interrupted task. */
|
||||
portSAVE_CONTEXT();
|
||||
|
||||
/* Now we can declare the local variables. These must be static. */
|
||||
static signed portCHAR cChar;
|
||||
static portBASE_TYPE xTaskWokenByTx, xTaskWokenByRx;
|
||||
/* Call the handler. This must be a separate function from the wrapper
|
||||
to ensure the correct stack frame is set up. */
|
||||
vUART_ISR_Handler();
|
||||
|
||||
/* As these variables are static they must be initialised manually here. */
|
||||
xTaskWokenByTx = pdFALSE;
|
||||
xTaskWokenByRx = pdFALSE;
|
||||
/* Restore the context of whichever task is going to run next. */
|
||||
portRESTORE_CONTEXT();
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vUART_ISR_Handler( void )
|
||||
{
|
||||
signed portCHAR cChar;
|
||||
portBASE_TYPE xTaskWokenByTx = pdFALSE, xTaskWokenByRx = pdFALSE;
|
||||
|
||||
/* What caused the interrupt? */
|
||||
switch( UART0_IIR & serINTERRUPT_SOURCE_MASK )
|
||||
|
@ -154,14 +160,15 @@ void vUART_ISR( void )
|
|||
break;
|
||||
}
|
||||
|
||||
if( xTaskWokenByTx || xTaskWokenByRx )
|
||||
{
|
||||
portYIELD_FROM_ISR();
|
||||
}
|
||||
|
||||
/* Clear the ISR in the VIC. */
|
||||
VICVectAddr = serCLEAR_VIC_INTERRUPT;
|
||||
|
||||
/* Exit the ISR. If a task was woken by either a character being received
|
||||
or transmitted then a context switch will occur. */
|
||||
portEXIT_SWITCHING_ISR( ( xTaskWokenByTx || xTaskWokenByRx ) );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue