Critical Sections, suggested implementation

Nicolas Horro nhorro at gmail.com
Fri Apr 3 14:05:33 UTC 2009


Hi,

anybody knows if is there a recommended/standard way of defining a
critical section in RTEMS from:

 i) inside a Task context ?
ii) an ISR ?

I'm particulary interested in RTEMS 4.8/ERC32, but i believe this
would be applicable to most architectures.

As far as I know, there are three ways:

------------------------------------------------------------------------------------------

/* --- Alternative 1. Changing Task Mode --- */

rtems_mode g_previous_task_mode;

inline void beginCriticalSection() {
  rtems_task_mode( RTEMS_NO_PREEMPT | RTEMS_INTERRUPT_LEVEL(15),
                   RTEMS_PREEMPT_MASK | RTEMS_INTERRUPT_MASK,
                   g_previous_task_mode);
}

inline void endCriticalSection() {
  rtems_mode tmp;
  rtems_task_mode( *g_previous_task_mode,
                   RTEMS_PREEMPT_MASK | RTEMS_INTERRUPT_MASK,
                   &tmp);
}


/* --- Alternative 2. Changing Interrupt Mask Register --- */

uint32_t g_previous_interrupt_mask_reg;

inline void beginCriticalSection() {
  g_previous_interrupt_mask_reg = *((uint32_t*)INTMSK);
}

inline void endCriticalSection() {
  *((uint32_t*)INTMSK) = g_previous_interrupt_mask_reg;
}


/* --- Alternative 3. Changing Interrupt Level --- */

uint32_t previous_interrupt_level;

inline void beginCriticalSection() {
  previous_interrupt_level = get_interrupt_level();
}

inline void endCriticalSection() {
  set_interrupt_level(previous_interrupt_level);
}

------------------------------------------------------------------------------------------

- Alternative 1 is only for tasks.
- Alternatives 2 and 3 alter hardware registers that might be
important for ISR_Handler (just a thought).

Thanks in advance,

Nicolás Eduardo Horro



More information about the users mailing list