Interrupt happening during CriticalSection

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
D_Sd_3235936
Level 4
Level 4
25 sign-ins 50 questions asked 25 replies posted

Using this code:

uint8_t InterruptState = 0 ;

    InterruptState = CyEnterCriticalSection();

     // I do something here, couple of msec.

    CyExitCriticalSection(InterruptState);

Are interrupts happening during CriticalSection are saved and activated on exit?

If the same interrupt occurred several times during CriticalSection how many times will it get executed on exit?

Is there a better way to protect code from ISR?

0 Likes
1 Solution
Pava_1191361
Level 3
Level 3
First like received First like given Welcome!

According to the documentation of Cy_SysLib_EnterCriticalSection:

     Cy_SysLib_EnterCriticalSection disables interrupts and returns a value  indicating whether the interrupts were previously enabled.

Which means that the interrupts are disabled. You can't prevent them from happening, so they will occur, and will set the appropriate interrupt  flag. Although the flag is set, because the interrupts are disabled, the interrupt will not be serviced: Only after the critical section is cleared and the interrupts are enabled again, the pending interrupt with the highest priority will be serviced first.

If you have a timerISR that would fire every ms, and you stay 10 ms in the Critical Section, it will only be served once, as the ISR can only raise a flag, not a counter.

Critical Sections should  therefore be as short as possible. A couple of ms is already pretty long. Depending on what you try to achieve there are different solutions available. You could for example create a simple state machine in a high priority timerISR that fires every ms. As you know that there are no higher priorities in the system, you know you can't be interrupted by another ISR and you don't even need to use the CyEnterCriticalSection(), but you do need to ensure that the execution will be done within one ms (that's why you need a state machine if the actual action spans several ms).

View solution in original post

1 Reply
Pava_1191361
Level 3
Level 3
First like received First like given Welcome!

According to the documentation of Cy_SysLib_EnterCriticalSection:

     Cy_SysLib_EnterCriticalSection disables interrupts and returns a value  indicating whether the interrupts were previously enabled.

Which means that the interrupts are disabled. You can't prevent them from happening, so they will occur, and will set the appropriate interrupt  flag. Although the flag is set, because the interrupts are disabled, the interrupt will not be serviced: Only after the critical section is cleared and the interrupts are enabled again, the pending interrupt with the highest priority will be serviced first.

If you have a timerISR that would fire every ms, and you stay 10 ms in the Critical Section, it will only be served once, as the ISR can only raise a flag, not a counter.

Critical Sections should  therefore be as short as possible. A couple of ms is already pretty long. Depending on what you try to achieve there are different solutions available. You could for example create a simple state machine in a high priority timerISR that fires every ms. As you know that there are no higher priorities in the system, you know you can't be interrupted by another ISR and you don't even need to use the CyEnterCriticalSection(), but you do need to ensure that the execution will be done within one ms (that's why you need a state machine if the actual action spans several ms).