Cortex M atomic operations – Critical section

In concurrent programming, concurrent accesses to shared resources can lead to unexpected or erroneous behavior, so parts of the program where the shared resource is accessed are protected. This protected section is the critical section or critical region. It cannot be executed by more than one process. Typically, the critical section accesses a shared resource, such as a data structure, a peripheral device, or a network connection, that would not operate correctly in the context of multiple concurrent accesses.

In other words, A ‘critical section’ is an area in the code where I need prevent two ‘threads’ accessing the same data in parallel. In ‘parallel’ might be code which is executed by the main program, but can be interrupt and accessed by another task or by an interrupt service routine. So we need to make sure that only only one program is executing that sequence. Or that this sequence is executed as such that it cannot be divided up (it needs to be executed in an atomic way).

https://en.wikipedia.org/wiki/Critical_section

https://mcuoneclipse.com/2014/01/26/entercritical-and-exitcritical-why-things-are-failing-badly/

The following header file presents 3 methods which can be used to ensure atomicity.

/******************************************************************************
* SOF - Header | By: Io.D
******************************************************************************/

#ifndef LIBRARIES_ICRITICAL_H_

/******************************************************************************
* Definitions
******************************************************************************/

#define LIBRARIES_ICRITICAL_H_

/******************************************************************************
* Includes
******************************************************************************/

#include <stdint.h>

/******************************************************************************
* Defines
******************************************************************************/

#define i_critical_section_init(arg)    \
  arg = 0
	
#define i_critical_section_start(arg)   \
  do {                                  \
    asm (                               \
    "MRS   R0, PRIMASK\n\t"             \
    "CPSID I\n\t"                       \
    "STRB R0, %[output]"                \
    : [output] "=m" (arg) :: "r0");     \
  } while(0)
 
#define i_critical_section_stop(arg)    \
  do{                                   \
    asm (                               \
    "ldrb r0, %[input]\n\t"             \
    "msr PRIMASK,r0;\n\t"               \
    ::[input] "m" (arg) : "r0");        \
  } while(0)

/******************************************************************************
* Enumerations, structures & External Variables
******************************************************************************/

typedef volatile uint8_t i_critical_t;

/******************************************************************************
* Public Functions (API)
******************************************************************************/

/******************************************************************************
* EOF - Header
******************************************************************************/

#endif

 

Add comment

Categories

Tags