When to enable interrupts - before or after vTaskStartScheduler()?

Good day

As far as I know, FreeRTOS only enables interrupts after vTaskStartScheduler() is called.
Is this correct?
I’m asking because I don’t know when I should call NVIC_EnableIRQ(__) for the interrupts that I use?

For example, I use interrupts for inter-core communication (my processor is dual-core).
I enable these interrupts before vTaskStartScheduler() is called.
What happens if an interrupt were to occur before vTaskStartScheduler() is called?
Would this interrupt be ignored?

My system works for the most part, but I have intermittent problems with ISRs (see my other post here).
I want to be sure that when I enable my interrupts isn’t causing the instability I’m experiencing.

Thanks in advance!

Do the corresponding ISR uses FreeRTOS APIs? If yes, you should enable it after starting the scheduler. If no, you can enable it anytime.


Many MCUs allow enabling device interrupts independent of globally enabling interrupts. Thus, many ports come out of reset with all interrupts disabled. If you enable interrups on the device level, no interrupt will fire until interrups are globally enabled which happens AT scheduler start time, not before or after (in order for scheduling to work, at least the sys tick timer must be enabled, on many ports also the service interrupt timer).

I have a question that the code after vtaskstartscheduler will not be executed.
My startup process is as follows:
(1) prvSetupHardware(enable many interrupts, and ISR uses FreeRTOS APIs)
(2) semphr, mutex, queue initialize
(3) create tasks
(4) vtaskstartscheduler
If an interrupt is triggered before (2), it will not work properly.
What kind of initialization process is correct, please?
Best regards!

you may want to re-read this thread, it’s all in there. BEFORE the scheduler start, you may enable interrupts on the device level and (if the processor supports that) interrupt controller level, but not on the processor level (ie cpsie on a Cortex M). That’s the last thing vTaskStartScheduler does before dispatching the first task. Doing that before is a fairly safe recipe for crashes. Iow, interrupts (at least those affecting RTOS compliant handlers) must not fire before the scheduler is up and running.

1 Like

Thanks for the clarification @RAc

Just to be sure, NVIC_EnableIRQ() enables interrupts on a device-level, so it’s okay to call that before vTaskStartScheduler(), because the processor’s interrupts are not yet enabled (with cpsie)?

If so, then does @aggarg’s comment (below) only apply if you enable interrupts at the processor level (cpsie) before calling vTaskStartScheduler?

Yes, that is correct. Do you see any problem when you do that?


1 Like

Thanks for the clarification @aggarg!

I have been doing it like this all along, so it can’t be the reason for the problems I’m having (described in my other post).


did you make sure that interrupts re DISabled out of reset (eg the first instruction in the Reset handler ISR is a cpsid)? Some PODs come out of reset with interrupts not disabled. If you wanted to be absolutely sure, you could add some assert code to your ISRs that hit a hard break point (__asm(" bkpt ")) if invoked with the scheduler not started.

However, from what you describe, that doesn’t look like your problem. The only way for us to help you with your issue would be for you to disclose some code…

1 Like

Thanks @RAc

My ResetISR() calls cpsid first:

I understand that you would need more information to go further.
Unfortunately I cannot disclose much code, so I need to ask these rather theoretical questions so that I can understand the system better and then debug it myself.

I really appreciate your effort, thank you @RAc & @aggarg !