- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Is there a faster way to make a critical block of instructions atomic (not interruptible) than using the alt_irq_disable_all and alt_irq_enable_all HAL functions?
ChrisLink Copied
3 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I don't know exactly how the hal implements it, but in the legacy SDK, I use some macro's with a direct assembler instruction.
Normaly, disbling and enabling interrupts take only one instruction. And if you want to store the status from before disabling (if you want to nest enables, disables) on the stack, you need some more. The macros look like this (DWORD is an unsigned long = 32 bit): /** Local stack space for processor status word. * Must be placed in the same scope where CRITICAL() and END_CRITICAL() is used * \hideinitializer */# define CONTAINS_CRITICAL DWORD stored_status; /** Begin critical section. * Interrupts will be disabled after this macro. \n * CRITICAL() must always be used in pair with END_CRITICAL(). * \hideinitializer */# define CRITICAL { __asm__ volatile ("rdctl %0, status" : "=r" (stored_status)); __asm__ volatile ("wrctl status, r0"); } /** End critical section. * Interrupts will be enabled after this macro if they were enabled before CRITICAL(). \n * END_CRITICAL() must always be used in pair with CRITICAL(). * \hideinitializer */# define END_CRITICAL { __asm__ volatile ("wrctl status, %0" :: "r" (stored_status)); } If you want to use, do this : void foo() { CONTAINS_CRITICAL // normal section CRITICAL //interrupts disabled here END_CRITICAL //normal section CRITICAL //interrupts disabled here END_CRITICAL }- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
If you find a more efficient way then I'd be interested to hear it.
At optimisation level -O2 these functions compile up into exactly the same code as described above:rdctl rx, status
wrctl status, zero
at the start and wrctl status, rx
at the end (where rx is a register between r2 and r23 chosen by the compiler). Please check your objdump file to see what the compiler has generated for you.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page