In xPortStartScheduler():
|
/* Make PendSV and SysTick the lowest priority interrupts. */ |
|
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; |
|
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; |
|
|
|
/* Start the timer that generates the tick ISR. Interrupts are disabled |
|
* here already. */ |
|
vPortSetupTimerInterrupt(); |
|
|
|
/* Initialise the critical nesting count ready for the first task. */ |
|
uxCriticalNesting = 0; |
|
|
|
/* Ensure the VFP is enabled - it should be anyway. */ |
|
vPortEnableVFP(); |
|
|
|
/* Lazy save always. */ |
|
*( portFPCCR ) |= portASPEN_AND_LSPEN_BITS; |
|
|
|
/* Start the first task. */ |
|
prvPortStartFirstTask(); |
|
|
|
/* Should never get here as the tasks will now be executing! Call the task |
|
* exit error function to prevent compiler warnings about a static function |
|
* not being called in the case that the application writer overrides this |
|
* functionality by defining configTASK_RETURN_ADDRESS. Call |
|
* vTaskSwitchContext() so link time optimisation does not remove the |
|
* symbol. */ |
|
vTaskSwitchContext(); |
|
prvTaskExitError(); |
|
|
|
/* Should not get here! */ |
|
return 0; |
|
} |
vPortSetupTimerInterrupt() is called which calls setupApplicationsIsr():
|
void setupApplicationsIsr(void) |
|
{ |
|
// interrupts |
|
SYS_SetPriority(CAN0_ORed_0_15_MB_IRQn, 8); // can0 buffer 0 - 15 |
|
SYS_SetPriority(CAN0_ORed_16_31_MB_IRQn, 8); // can0 buffer 16 - 32 |
|
|
|
SYS_EnableIRQ(CAN0_ORed_0_15_MB_IRQn); |
|
SYS_EnableIRQ(CAN0_ORed_16_31_MB_IRQn); |
|
|
|
// Data transfer done, Transmit Buffer Done for Ring/Queue 0, Transmit Frame Done for Ring/Queue |
|
// 0 |
|
SYS_SetPriority(ENET_TX_Buffer_IRQn, 9); |
|
// Receive Buffer Done for Ring/Queue 0, Receive Frame Done for Ring/Queue 0 |
|
SYS_SetPriority(ENET_RX_Buffer_IRQn, 9); |
|
// Payload receive error, Collision retry limit reached, Late collision detected, AXI Bus Error |
|
// detected, Babbling transmit error, Babbling receive error, Transmit FIFO underrun |
|
// SYS_SetPriority(ENET_PRE_IRQn, 9); |
|
SYS_EnableIRQ(ENET_TX_Buffer_IRQn); |
|
SYS_EnableIRQ(ENET_RX_Buffer_IRQn); |
|
// SYS_EnableIRQ(ENET_PRE_IRQn); |
|
ENABLE_INTERRUPTS(); |
|
} |
which enables interrupts in the last line.
However, FreeRTOS enables interrupts later in:
|
static void prvPortStartFirstTask( void ) |
|
{ |
|
/* Start the first task. This also clears the bit that indicates the FPU is |
|
* in use in case the FPU was used before the scheduler was started - which |
|
* would otherwise result in the unnecessary leaving of space in the SVC stack |
|
* for lazy saving of FPU registers. */ |
|
__asm volatile ( |
|
" ldr r0, =0xE000ED08 \n" /* Use the NVIC offset register to locate the stack. */ |
|
" ldr r0, [r0] \n" |
|
" ldr r0, [r0] \n" |
|
" msr msp, r0 \n" /* Set the msp back to the start of the stack. */ |
|
" mov r0, #0 \n" /* Clear the bit that indicates the FPU is in use, see comment above. */ |
|
" msr control, r0 \n" |
|
" cpsie i \n" /* Globally enable interrupts. */ |
|
" cpsie f \n" |
|
" dsb \n" |
|
" isb \n" |
|
" svc 0 \n" /* System call to start first task. */ |
|
" nop \n" |
|
" .ltorg \n" |
|
); |
|
} |
Is there a reason why we enable interrupts ourselves earlier?
In
xPortStartScheduler():openbsw/platforms/s32k1xx/3rdparty/freertos_cm4_sysTick/src/port.c
Lines 389 to 420 in 73fb9cd
vPortSetupTimerInterrupt()is called which callssetupApplicationsIsr():openbsw/executables/referenceApp/platforms/s32k148evb/main/src/main.cpp
Lines 53 to 74 in 73fb9cd
which enables interrupts in the last line.
However, FreeRTOS enables interrupts later in:
openbsw/platforms/s32k1xx/3rdparty/freertos_cm4_sysTick/src/port.c
Lines 270 to 291 in 73fb9cd
Is there a reason why we enable interrupts ourselves earlier?