temporary disabling interrupts and serving occured interrupts afterwards / critical s

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

cross mob
User21268
Level 1
Level 1
Hi I want to introduce to my code:
something like "enter_critical_section" and "exit_crtical_section".

This function shall disable all interrupt handling and sahll enable interrupt handling afterwards.
The must have is, that the interrupts that occured while disabled, shall be held pending and shall be handled after the call of "exit_critical_section".

I am not quite sure wheter __disable_irq and __enable_irq fullfill this requirement.

In xmc_math.c ther are the functions crtical_section_enter and crtical_section_exit. Do these functions do the job?
I am a bit confused because i expected to find a __enable_irq() in the function critical_section_exit ?

Maybe there is some kind of expert out there who can help me out on this, as the documentation is a bit confusing how to safely catch pending intterupts after re-enabling.

Best regards Sven



__attribute__((always_inline)) __STATIC_INLINE uint32_t critical_section_enter(void)
{
uint32_t status;
status = __get_PRIMASK();
__disable_irq ();
return status;
}

__attribute__((always_inline)) __STATIC_INLINE void critical_section_exit(uint32_t status)
{
__set_PRIMASK(status);
}
0 Likes
1 Solution
Vasanth
Moderator
Moderator
Moderator
250 sign-ins 500 solutions authored First question asked
Hi Sven,


__disable_irq () - Globally disables interrupts and configurable fault handlers.The function disables interrupts and all configurable fault handlers by setting PRIMASK.

Set the Priority Mask bit.

__set_PRIMASK - The function sets the Priority Mask register (PRIMASK) value using the instruction MSR.PRIMASK is a 1-bit-wide interrupt mask register.
When set, it blocks all interrupts apart from the non-maskable interrupt (NMI) and the hard fault exception. The PRIMASK prevents activation of all exceptions with configurable priority.

As both are manipulating one register, __set_PRIMASK call is sufficient. It sets the register to the previous 'status' value( a series critical section will not accidentally turn on the interrupt, but move it to last known state).
The pending interrupts is activated once the the register is unmasked.

Best Regards,
Vasanth

View solution in original post

0 Likes
3 Replies
Vasanth
Moderator
Moderator
Moderator
250 sign-ins 500 solutions authored First question asked
Hi Sven,


__disable_irq () - Globally disables interrupts and configurable fault handlers.The function disables interrupts and all configurable fault handlers by setting PRIMASK.

Set the Priority Mask bit.

__set_PRIMASK - The function sets the Priority Mask register (PRIMASK) value using the instruction MSR.PRIMASK is a 1-bit-wide interrupt mask register.
When set, it blocks all interrupts apart from the non-maskable interrupt (NMI) and the hard fault exception. The PRIMASK prevents activation of all exceptions with configurable priority.

As both are manipulating one register, __set_PRIMASK call is sufficient. It sets the register to the previous 'status' value( a series critical section will not accidentally turn on the interrupt, but move it to last known state).
The pending interrupts is activated once the the register is unmasked.

Best Regards,
Vasanth
0 Likes
rst
Level 3
Level 3
First solution authored Welcome!
crit_sect.h:
//Critical sections
#define CPU_SR_ALLOCATE() u32 cpu_sr //Allocate storage for CPU status register
#define ENTR_CRT_SECTION() do { cpu_sr = __get_PRIMASK(); __disable_interrupt(); } while (0)
#define EXIT_CRT_SECTION() __set_PRIMASK(cpu_sr)

*.cpp:
void Func()
{
CPU_SR_ALLOCATE();
ENTR_CRT_SECTION();
...
EXIT_CRT_SECTION();
}
0 Likes
Vasanth
Moderator
Moderator
Moderator
250 sign-ins 500 solutions authored First question asked
Hi,

I think your questions were answered. Let me know if anything was not answered.

Best Regards,
Vasanth
0 Likes