|
|
|
|
|
|
|
|
|
|
|
|
|
|
void EventResponder::triggerEventNotImmediate() |
|
|
void EventResponder::triggerEventNotImmediate() |
|
|
{ |
|
|
{ |
|
|
if (_triggered) { |
|
|
|
|
|
// already triggered |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
if (_type == EventTypeYield) { |
|
|
|
|
|
// normal type, called from yield() |
|
|
|
|
|
if (firstYield == nullptr) { |
|
|
|
|
|
_next = nullptr; |
|
|
|
|
|
_prev = nullptr; |
|
|
|
|
|
firstYield = this; |
|
|
|
|
|
lastYield = this; |
|
|
|
|
|
} else { |
|
|
|
|
|
_next = nullptr; |
|
|
|
|
|
_prev = lastYield; |
|
|
|
|
|
_prev->_next = this; |
|
|
|
|
|
lastYield = this; |
|
|
|
|
|
} |
|
|
|
|
|
_triggered = true; |
|
|
|
|
|
} else if (_type == EventTypeInterrupt) { |
|
|
|
|
|
// interrupt, called from software interrupt |
|
|
|
|
|
if (firstInterrupt == nullptr) { |
|
|
|
|
|
_next = nullptr; |
|
|
|
|
|
_prev = nullptr; |
|
|
|
|
|
firstInterrupt = this; |
|
|
|
|
|
lastInterrupt = this; |
|
|
|
|
|
|
|
|
bool irq = disableInterrupts(); |
|
|
|
|
|
if (_triggered == false) { |
|
|
|
|
|
// not already triggered |
|
|
|
|
|
if (_type == EventTypeYield) { |
|
|
|
|
|
// normal type, called from yield() |
|
|
|
|
|
if (firstYield == nullptr) { |
|
|
|
|
|
_next = nullptr; |
|
|
|
|
|
_prev = nullptr; |
|
|
|
|
|
firstYield = this; |
|
|
|
|
|
lastYield = this; |
|
|
|
|
|
} else { |
|
|
|
|
|
_next = nullptr; |
|
|
|
|
|
_prev = lastYield; |
|
|
|
|
|
_prev->_next = this; |
|
|
|
|
|
lastYield = this; |
|
|
|
|
|
} |
|
|
|
|
|
} else if (_type == EventTypeInterrupt) { |
|
|
|
|
|
// interrupt, called from software interrupt |
|
|
|
|
|
if (firstInterrupt == nullptr) { |
|
|
|
|
|
_next = nullptr; |
|
|
|
|
|
_prev = nullptr; |
|
|
|
|
|
firstInterrupt = this; |
|
|
|
|
|
lastInterrupt = this; |
|
|
|
|
|
} else { |
|
|
|
|
|
_next = nullptr; |
|
|
|
|
|
_prev = lastInterrupt; |
|
|
|
|
|
_prev->_next = this; |
|
|
|
|
|
lastInterrupt = this; |
|
|
|
|
|
} |
|
|
|
|
|
SCB_ICSR = SCB_ICSR_PENDSVSET; // set PendSV interrupt |
|
|
} else { |
|
|
} else { |
|
|
_next = nullptr; |
|
|
|
|
|
_prev = lastInterrupt; |
|
|
|
|
|
_prev->_next = this; |
|
|
|
|
|
lastInterrupt = this; |
|
|
|
|
|
|
|
|
// detached, easy :-) |
|
|
} |
|
|
} |
|
|
_triggered = true; |
|
|
_triggered = true; |
|
|
SCB_ICSR = SCB_ICSR_PENDSVSET; // set PendSV interrupt |
|
|
|
|
|
} else { |
|
|
|
|
|
// detached, easy :-) |
|
|
|
|
|
_triggered = true; |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
enableInterrupts(irq); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void pendablesrvreq_isr(void) |
|
|
void pendablesrvreq_isr(void) |
|
|
|
|
|
|
|
|
void EventResponder::runFromInterrupt() |
|
|
void EventResponder::runFromInterrupt() |
|
|
{ |
|
|
{ |
|
|
while (1) { |
|
|
while (1) { |
|
|
|
|
|
bool irq = disableInterrupts(); |
|
|
EventResponder *first = firstInterrupt; |
|
|
EventResponder *first = firstInterrupt; |
|
|
if (first) { |
|
|
if (first) { |
|
|
firstInterrupt = first->_next; |
|
|
firstInterrupt = first->_next; |
|
|
|
|
|
|
|
|
} else { |
|
|
} else { |
|
|
lastInterrupt = nullptr; |
|
|
lastInterrupt = nullptr; |
|
|
} |
|
|
} |
|
|
|
|
|
enableInterrupts(irq); |
|
|
first->_triggered = false; |
|
|
first->_triggered = false; |
|
|
(*(first->_function))(*first); |
|
|
(*(first->_function))(*first); |
|
|
} else { |
|
|
} else { |
|
|
|
|
|
enableInterrupts(irq); |
|
|
break; |
|
|
break; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool EventResponder::clearEvent() |
|
|
bool EventResponder::clearEvent() |
|
|
{ |
|
|
{ |
|
|
|
|
|
bool ret = false; |
|
|
|
|
|
bool irq = disableInterrupts(); |
|
|
if (_triggered) { |
|
|
if (_triggered) { |
|
|
if (_type == EventTypeYield) { |
|
|
if (_type == EventTypeYield) { |
|
|
if (_prev) { |
|
|
if (_prev) { |
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
_triggered = false; |
|
|
_triggered = false; |
|
|
return true; |
|
|
|
|
|
|
|
|
ret = true; |
|
|
} |
|
|
} |
|
|
return false; |
|
|
|
|
|
|
|
|
enableInterrupts(irq); |
|
|
|
|
|
return ret; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void EventResponder::detach() |
|
|
void EventResponder::detach() |
|
|
{ |
|
|
{ |
|
|
|
|
|
bool irq = disableInterrupts(); |
|
|
if (_type == EventTypeYield) { |
|
|
if (_type == EventTypeYield) { |
|
|
if (_triggered) { |
|
|
if (_triggered) { |
|
|
if (_prev) { |
|
|
if (_prev) { |
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
_type = EventTypeDetached; |
|
|
_type = EventTypeDetached; |
|
|
} |
|
|
} |
|
|
|
|
|
enableInterrupts(irq); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|