Electronics > Microcontrollers

Globally enabling/disabling CH32V003 interrupts with the mstatus CSR

<< < (4/4)

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

There was an error while thanking
Thanking...
Go to full version
Powered by SMFPacks Advanced Attachments Uploader Mod