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

@@ -206,6 +206,7 @@ void MillisTimer::beginRepeat(unsigned long milliseconds, EventResponderRef even

void MillisTimer::addToList()
{
bool irq = disableTimerInterrupt();
if (list == nullptr) {
// list is empty, easy case
_next = nullptr;
@@ -230,6 +231,7 @@ void MillisTimer::addToList()
timer->_prev = this;
_prev->_next = this;
isQueued = true;
enableTimerInterrupt(irq);
return;
}
}
@@ -240,10 +242,12 @@ void MillisTimer::addToList()
timer->_next = this;
}
isQueued = true;
enableTimerInterrupt(irq);
}

void MillisTimer::end()
{
bool irq = disableTimerInterrupt();
if (isQueued) {
if (_next) {
_next->_prev = _prev;
@@ -255,10 +259,12 @@ void MillisTimer::end()
}
isQueued = false;
}
enableTimerInterrupt(irq);
}

void MillisTimer::runFromTimer()
{
bool irq = disableTimerInterrupt();
MillisTimer *timer = list;
while (timer) {
if (timer->_ms > 0) {
@@ -268,6 +274,7 @@ void MillisTimer::runFromTimer()
MillisTimer *next = timer->_next;
if (next) next->_prev = nullptr;
list = next;
enableTimerInterrupt(irq);
timer->isQueued = false;
EventResponderRef event = *(timer->_event);
event.triggerEvent(0, timer);
@@ -275,9 +282,11 @@ void MillisTimer::runFromTimer()
timer->_ms = timer->_reload;
timer->addToList();
}
irq = disableTimerInterrupt();
timer = list;
}
}
enableTimerInterrupt(irq);
}

extern "C" volatile uint32_t systick_millis_count;

+ 10
- 1
teensy3/EventResponder.h View File

@@ -214,7 +214,7 @@ private:
uint32_t primask;
__asm__ volatile("mrs %0, primask\n" : "=r" (primask)::);
__disable_irq();
return (primask == 0) ? false : true;
return (primask == 0) ? true : false;
}
static void enableInterrupts(bool doit) {
if (doit) __enable_irq();
@@ -242,6 +242,15 @@ private:
EventResponder *_event = nullptr;
bool isQueued = false;
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

Loading…
Cancel
Save