Update to allow nesting.

This commit is contained in:
Richard Barry 2008-05-06 11:51:13 +00:00
parent b7f66b9db6
commit bafcf8901e
4 changed files with 310 additions and 141 deletions

View file

@ -51,9 +51,6 @@
* Implementation of functions defined in portable.h for the PIC32MX port.
*----------------------------------------------------------*/
/* Library includes. */
#include <string.h>
/* Scheduler include files. */
#include "FreeRTOS.h"
#include "task.h"
@ -64,12 +61,13 @@
/* Bits within various registers. */
#define portIE_BIT ( 0x00000001 )
#define portEXL_BIT ( 0x00000002 )
#define portSW0_ENABLE ( 0x00000100 )
#define portIPL_SHIFT ( 10 )
#define portALL_IPL_BITS ( 0x1f << portIPL_SHIFT )
#define portALL_IPL_BITS ( 0x3f << portIPL_SHIFT )
/* The EXL bit is set to ensure interrupts do not occur while the context of
the first task is being restored. */
#define portINITIAL_SR ( portIE_BIT | portEXL_BIT )
#define portINITIAL_SR ( portIE_BIT | portEXL_BIT | portSW0_ENABLE )
/* Records the nesting depth of calls to portENTER_CRITICAL(). */
unsigned portBASE_TYPE uxCriticalNesting = 0x55555555;
@ -78,6 +76,13 @@ unsigned portBASE_TYPE uxCriticalNesting = 0x55555555;
decremented to 0 when the first task starts. */
volatile unsigned portBASE_TYPE uxInterruptNesting = 0x01;
/* Used to store the original interrupt mask when the mask level is temporarily
raised during an ISR. */
volatile unsigned portBASE_TYPE uxSavedStatusRegister = 0;
/* Stores the task stack pointer when a switch is made to use the system stack. */
unsigned portBASE_TYPE uxSavedTaskStackPointer = 0;
/* The stack used by interrupt service routines that cause a context switch. */
portSTACK_TYPE xISRStack[ configISR_STACK_SIZE ] = { 0 };
@ -88,11 +93,10 @@ const portBASE_TYPE * const xISRStackTop = &( xISRStack[ configISR_STACK_SIZE -
/* Place the prototype here to ensure the interrupt vector is correctly installed. */
extern void __attribute__( (interrupt(ipl1), vector(_TIMER_1_VECTOR))) vT1InterruptHandler( void );
/*
* General exception handler that will be called for all general exceptions
* other than SYS. This should be overridden by a user provided handler.
/*
* The software interrupt handler that performs the yield.
*/
void vApplicationGeneralExceptionHandler( unsigned portLONG ulCause, unsigned portLONG ulStatus ) __attribute__((weak));
void __attribute__( (interrupt(ipl1), vector(_CORE_SOFTWARE_0_VECTOR))) vPortYieldISR( void );
/*-----------------------------------------------------------*/
@ -156,7 +160,7 @@ unsigned portLONG ulStatus;
/* Mask interrupts at and below the kernel interrupt priority. */
ulStatus = _CP0_GET_STATUS();
ulStatus |= ( configKERNEL_INTERRUPT_PRIORITY << portIPL_SHIFT );
ulStatus |= ( configMAX_SYSCALL_INTERRUPT_PRIORITY << portIPL_SHIFT );
_CP0_SET_STATUS( ulStatus );
/* Once interrupts are disabled we can access the nesting count directly. */
@ -186,14 +190,18 @@ unsigned portLONG ulStatus;
portBASE_TYPE xPortStartScheduler( void )
{
extern void vPortStartFirstTask( void );
extern void *pxCurrentTCB;
memset( xISRStack, 0x5a, configISR_STACK_SIZE * sizeof( portSTACK_TYPE ) );
/* Setup the software interrupt. */
mConfigIntCoreSW0( CSW_INT_ON | CSW_INT_PRIOR_1 | CSW_INT_SUB_PRIOR_0 );
/* Setup the timer to generate the tick. Interrupts will have been
disabled by the time we get here. */
prvSetupTimerInterrupt();
/* Kick off the highest priority task that has been created so far. */
/* Kick off the highest priority task that has been created so far.
Its stack location is loaded into uxSavedTaskStackPointer. */
uxSavedTaskStackPointer = *( unsigned portBASE_TYPE * ) pxCurrentTCB;
vPortStartFirstTask();
/* Should never get here as the tasks will now be executing. */
@ -201,12 +209,49 @@ extern void vPortStartFirstTask( void );
}
/*-----------------------------------------------------------*/
void vApplicationGeneralExceptionHandler( unsigned portLONG ulCause, unsigned portLONG ulStatus )
void vPortYield( void )
{
/* This function is declared weak and should be overridden by the users
application. */
while( 1 );
unsigned portLONG ulStatus;
SetCoreSW0();
/* Unmask all interrupts. */
ulStatus = _CP0_GET_STATUS();
ulStatus &= ~portALL_IPL_BITS;
_CP0_SET_STATUS( ulStatus );
}
/*-----------------------------------------------------------*/
void vPortIncrementTick( void )
{
vPortSetInterruptMaskFromISR();
vTaskIncrementTick();
vPortClearInterruptMaskFromISR();
/* If we are using the preemptive scheduler then we might want to select
a different task to execute. */
#if configUSE_PREEMPTION == 1
SetCoreSW0();
#endif /* configUSE_PREEMPTION */
/* Clear timer 0 interrupt. */
mT1ClearIntFlag();
}
/*-----------------------------------------------------------*/
void vPortSetInterruptMaskFromISR( void )
{
asm volatile ( "di" );
uxSavedStatusRegister = _CP0_GET_STATUS() | 0x01;
_CP0_SET_STATUS( ( uxSavedStatusRegister | ( configMAX_SYSCALL_INTERRUPT_PRIORITY << portIPL_SHIFT ) ) );
}
/*-----------------------------------------------------------*/
void vPortClearInterruptMaskFromISR( void )
{
_CP0_SET_STATUS( uxSavedStatusRegister );
}
/*-----------------------------------------------------------*/