Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Critical sections in ARM

I am experienced in implementing critical sections on the AVR family of processors, where all you do is disable interrupts (with a memory barrier of course), do the critical operation, and then reenable interrupts:

void my_critical_function()
{
   cli();  //Disable interrupts
   // Mission critical code here
   sei();  //Enable interrupts
}

Now my question is this:

Does this simple method apply to the ARM architecture of processor as well? I have heard things about the processor doing lookahead on the instructions, and other black magic, and was wondering primarily if these types of things could be problematic to this implementation of critical sections.

like image 989
DarthRubik Avatar asked Aug 11 '18 00:08

DarthRubik


2 Answers

Assuming you're on a Cortex-M processor, take a look at the LDREX and STREX instructions, which are available in C via the __LDREXW() and __STREXW() macros provided by CMSIS (the Cortex Microcontroller Software Interface Standard). They can be used to build extremely lightweight mutual exclusion mechanisms.

Basically,

data = __LDREXW(address)

works like data = *address except that it sets an 'exclusive access flag' in the CPU. When you've finished manipulating your data, write it back using

success = __STREXW(address, data)

which is like *address = data but will only succeed in writing if the exclusive access flag is still set. If it does succeed in writing then it also clears the flag. It returns 0 on success and 1 on failure. If the STREX fails, you have to go back to the LDREX and try again.

For simple exclusive access to a shared variable, nothing else is required. For example:

do {
  data = LDREX(address);
  data++;
} while (STREXW(address, data));

The interesting thing about this mechanism is that it's effectively 'last come, first served'; if this code is interrupted and the interrupt uses LDREX and STREX, the STREX interrupt will succeed and the (lower-priority) user code will have to retry.

If you're using an operating system, the same primitives can be used to build 'proper' semaphores and mutexes (see this application note, for example); but then again if you're using an OS you probably already have access to mutexes through its API!

like image 176
cooperised Avatar answered Sep 20 '22 08:09

cooperised


ARM architecture is very wide and as I understand you probably mean ARM Cortex M micro controllers.

You can use this technique, but many ARM uCs offer much more. As I do know what is the actual hardware I can only give you some examples:

  1. bitband area. In this memory regions you can set and reset bits atomic way.
  2. Hardware semaphores (STM32H7)
  3. Hardware MUTEX-es (some NXP uCs)

etc etc.

like image 39
0___________ Avatar answered Sep 19 '22 08:09

0___________