Electronics > Microcontrollers
Globally enabling/disabling CH32V003 interrupts with the mstatus CSR
HwAoRrDk:
I had the idea to take the technique for an atomic block macro I talked about in my first post in this thread, and to adapt it to have a macro that can make an atomic block that disables/restores only a specific individual interrupt, using the PFIC control registers.
What I came up with is this:
--- Code: ---#define interrupt_individual_atomic_block(irq) \
for( \
uint32_t \
__interrupt_atomic_block_irq_saved = (PFIC->ISR[(irq) / 32] & (1 << ((uint32_t)(irq) % 32))), \
__interrupt_atomic_block_loop = (PFIC->IRER[(irq) / 32] = (1 << ((uint32_t)(irq) % 32))); \
__interrupt_atomic_block_loop; \
(PFIC->IENR[(irq) / 32] = __interrupt_atomic_block_irq_saved), __interrupt_atomic_block_loop = 0 \
)
--- End code ---
What it does is:
1. Saves the current enabled status value of the appropriate PFIC_ISRn register, masked to the given interrupt number.
2. Disables the given interrupt using the relevant PFIC_IRERn register by writing 1 in the appropriate bit. This non-zero expression value is also assigned to the loop flag so the loop body will proceed.
3. Re-enables (if previously enabled) the given interrupt by writing the previously-saved value to the appropriate PFIC_IENRn register.
4. Exits the for-loop by setting the loop flag to false.
However... there's one thing that this relies upon, which I have some uncertainty about: the order in which the local variable declarations are processed.
It's obviously critical here that the interrupt's current enabled status is saved before it's disabled - i.e. __interrupt_atomic_block_irq_saved is assigned its value before __interrupt_atomic_block_loop is assigned its value. Does the C standard guarantee that? I think so, but I'm not 100% sure. :-\
I imagine it does because when declaring multiple variables in a single statement you might want to initialise the value of one with the value of a prior one, and that wouldn't work if the compiler didn't strictly order the initialisations left-to-right. But I can't find anything explicitly saying so. Nearest I found was on cppreference.com where it says about declarators that "The end of every declarator that is not part of another declarator is a sequence point". IIRC, a 'sequence point' essentially means everything must be resolved before proceeding to the next thing, but reading the page linked for "sequence point" is giving me a headache. :scared: Is that sentence confirming the ordering behaviour is as I think it is?
brucehoult:
--- Quote from: HwAoRrDk on April 01, 2023, 08:56:04 am ---IIRC, a 'sequence point' essentially means everything must be resolved before proceeding to the next thing
--- End quote ---
Correct.
At least for everything that has or can observe side-effects. For other things the order doesn't matter.
Navigation
[0] Message Index
[*] Previous page
Go to full version