This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Bare Metal Criical Section Code for Cortex MO

On a bare metal system you often need to protect code with a critical section.

Here is an article describing what I need.

mcuoneclipse.com/.../

At the end, the author provides an example. Try as I might, I cannot get this or variants to compile with KEIL. Can anyone help? I am looking for the solution to work with C++.

Thanks

Rich

Here are the specifics on the KEIL tool that I am using.
IDE-Version:
µVision V5.22.0.0

Tool Version Numbers:
Toolchain: MDK-Lite Version: 5.22
Toolchain Path: C:\Keil_v5\ARM\ARMCC\Bin
C Compiler: Armcc.exe V5.06 update 4 (build 422)
Assembler: Armasm.exe V5.06 update 4 (build 422)
Linker/Locator: ArmLink.exe V5.06 update 4 (build 422)
Library Manager: ArmAr.exe V5.06 update 4 (build 422)
Hex Converter: FromElf.exe V5.06 update 4 (build 422)
CPU DLL: SARMCM3.DLL V5.22
Dialog DLL: DARMCM1.DLL V1.15.0.0
Target DLL: UL2CM3.DLL V1.159.0.0
Dialog DLL: TARMCM1.DLL V1.11.0.0

Code:


#define CpuCriticalVar()  uint8_t cpuSR

#define CpuEnterCritical()              \ 
  do {                                  \ 
    asm (                               \ 
    "MRS   R0, PRIMASK\n\t"             \ 
    "CPSID I\n\t"                       \ 
    "STRB R0, %[output]"                \ 
    : [output] "=m" (cpuSR) :: "r0");   \ 
  } while(0)

#define CpuExitCritical()               \ 
  do{                                   \ 
    asm (                               \ 
    "ldrb r0, %[input]\n\t"             \ 
    "msr PRIMASK,r0;\n\t"               \ 
    ::[input] "m" (cpuSR) : "r0");      \ 
  } while(0)


Test code

#if 0 /* original, buggy version */
  #define DEFINE_CRITICAL() /* nothing */
  #define ENTER_CRITICAL()  EnterCritical()
  #define EXIT_CRITICAL()   ExitCritical()
#else /* fixed version using local variable */
  #define DEFINE_CRITICAL() CpuCriticalVar()
  #define ENTER_CRITICAL()  CpuEnterCritical()
  #define EXIT_CRITICAL()   CpuExitCritical()
#endif

static volatile uint8_t shared=0;

static void Error(void) {
 for(;;);
}

void T1(void) { /* called by timer interrupt every 0.1 ms, max prio (0) */
 DEFINE_CRITICAL();

 ENTER_CRITICAL();
 shared += 1;
 if (shared!=1) {
 Error();
 }
 shared -= 1;
 EXIT_CRITICAL();
}

void T2(void) { /* called by timer interrupt every 1 ms, minimal prio (3) */
 DEFINE_CRITICAL();

 ENTER_CRITICAL();
 shared += 1;
 if (shared!=1) {
 Error();
 }
 shared -= 1;
 EXIT_CRITICAL();
}

static void test(void) {
 DEFINE_CRITICAL();

 for(;;) {
 ENTER_CRITICAL();
 shared += 1;
 if (shared!=1) {
 Error();
 }
 shared -= 1;
 EXIT_CRITICAL();
 }
}

Parents Reply Children
No data