Browse Source

Disable interrupts in MillisTimer critical sections

teensy4-core
PaulStoffregen 7 years ago
parent
commit
9b8892856f
2 changed files with 19 additions and 1 deletions
  1. +9
    -0
      teensy3/EventResponder.cpp
  2. +10
    -1
      teensy3/EventResponder.h

+ 9
- 0
teensy3/EventResponder.cpp View File



void MillisTimer::addToList() void MillisTimer::addToList()
{ {
bool irq = disableTimerInterrupt();
if (list == nullptr) { if (list == nullptr) {
// list is empty, easy case // list is empty, easy case
_next = nullptr; _next = nullptr;
timer->_prev = this; timer->_prev = this;
_prev->_next = this; _prev->_next = this;
isQueued = true; isQueued = true;
enableTimerInterrupt(irq);
return; return;
} }
} }
timer->_next = this; timer->_next = this;
} }
isQueued = true; isQueued = true;
enableTimerInterrupt(irq);
} }


void MillisTimer::end() void MillisTimer::end()
{ {
bool irq = disableTimerInterrupt();
if (isQueued) { if (isQueued) {
if (_next) { if (_next) {
_next->_prev = _prev; _next->_prev = _prev;
} }
isQueued = false; isQueued = false;
} }
enableTimerInterrupt(irq);
} }


void MillisTimer::runFromTimer() void MillisTimer::runFromTimer()
{ {
bool irq = disableTimerInterrupt();
MillisTimer *timer = list; MillisTimer *timer = list;
while (timer) { while (timer) {
if (timer->_ms > 0) { if (timer->_ms > 0) {
MillisTimer *next = timer->_next; MillisTimer *next = timer->_next;
if (next) next->_prev = nullptr; if (next) next->_prev = nullptr;
list = next; list = next;
enableTimerInterrupt(irq);
timer->isQueued = false; timer->isQueued = false;
EventResponderRef event = *(timer->_event); EventResponderRef event = *(timer->_event);
event.triggerEvent(0, timer); event.triggerEvent(0, timer);
timer->_ms = timer->_reload; timer->_ms = timer->_reload;
timer->addToList(); timer->addToList();
} }
irq = disableTimerInterrupt();
timer = list; timer = list;
} }
} }
enableTimerInterrupt(irq);
} }


extern "C" volatile uint32_t systick_millis_count; extern "C" volatile uint32_t systick_millis_count;

+ 10
- 1
teensy3/EventResponder.h View File

uint32_t primask; uint32_t primask;
__asm__ volatile("mrs %0, primask\n" : "=r" (primask)::); __asm__ volatile("mrs %0, primask\n" : "=r" (primask)::);
__disable_irq(); __disable_irq();
return (primask == 0) ? false : true;
return (primask == 0) ? true : false;
} }
static void enableInterrupts(bool doit) { static void enableInterrupts(bool doit) {
if (doit) __enable_irq(); if (doit) __enable_irq();
EventResponder *_event = nullptr; EventResponder *_event = nullptr;
bool isQueued = false; bool isQueued = false;
static MillisTimer *list; static MillisTimer *list;
static bool disableTimerInterrupt() {
uint32_t primask;
__asm__ volatile("mrs %0, primask\n" : "=r" (primask)::);
__disable_irq();
return (primask == 0) ? true : false;
}
static void enableTimerInterrupt(bool doit) {
if (doit) __enable_irq();
}
}; };


#endif #endif

Loading…
Cancel
Save