Przeglądaj źródła

Use PendSV for EventResponder attachInterrupt

main
PaulStoffregen 7 lat temu
rodzic
commit
e77b120f7b
3 zmienionych plików z 28 dodań i 11 usunięć
  1. +18
    -10
      teensy3/EventResponder.cpp
  2. +3
    -1
      teensy3/EventResponder.h
  3. +7
    -0
      teensy3/kinetis.h

+ 18
- 10
teensy3/EventResponder.cpp Wyświetl plik

@@ -60,6 +60,7 @@ void EventResponder::triggerEventNotImmediate()
_prev->_next = this;
lastYield = this;
}
_pending = true;
} else if (_type == EventTypeInterrupt) {
// interrupt, called from software interrupt
if (firstInterrupt == nullptr) {
@@ -73,11 +74,12 @@ void EventResponder::triggerEventNotImmediate()
_prev->_next = this;
lastInterrupt = this;
}
// TODO set interrupt pending
_pending = true;
SCB_ICSR = SCB_ICSR_PENDSVSET; // set PendSV interrupt
} else {
// detached, easy :-)
_pending = true;
}
_pending = true;
}

void pendablesrvreq_isr(void)
@@ -87,15 +89,21 @@ void pendablesrvreq_isr(void)

void EventResponder::runFromInterrupt()
{
// FIXME: this will fail if the handler function triggers
// its own or other EventResponder instances. The list will
// change while we're holding a pointers to it.
for (EventResponder *first=firstInterrupt; first; first = first->_next) {
first->_pending = false;
(*(first->_function))(*first);
while (1) {
EventResponder *first = firstInterrupt;
if (first) {
firstInterrupt = first->_next;
if (firstInterrupt) {
firstInterrupt->_prev = nullptr;
} else {
lastInterrupt = nullptr;
}
first->_pending = false;
(*(first->_function))(*first);
} else {
break;
}
}
firstInterrupt = nullptr;
lastInterrupt = nullptr;
}

bool EventResponder::clearEvent()

+ 3
- 1
teensy3/EventResponder.h Wyświetl plik

@@ -106,7 +106,7 @@ public:
detach();
_function = function;
_type = EventTypeInterrupt;
// TODO: configure PendSV
SCB_SHPR3 |= 0x00FF0000; // configure PendSV, lowest priority
}

// Attach a function to be called as its own thread. Boards not running
@@ -161,6 +161,8 @@ public:

static void runFromYield() {
EventResponder *first = firstYield;
// FIXME: also check if yield() called from an interrupt
// never run these functions from any interrupt context
if (first && !runningFromYield) {
runningFromYield = true;
firstYield = first->_next;

+ 7
- 0
teensy3/kinetis.h Wyświetl plik

@@ -5664,7 +5664,14 @@ typedef struct __attribute__((packed)) {
// System Control Space (SCS), ARMv7 ref manual, B3.2, page 708
#define SCB_CPUID (*(const uint32_t *)0xE000ED00) // CPUID Base Register
#define SCB_ICSR (*(volatile uint32_t *)0xE000ED04) // Interrupt Control and State
#define SCB_ICSR_NMIPENDSET ((uint32_t)0x80000000)
#define SCB_ICSR_PENDSVSET ((uint32_t)0x10000000)
#define SCB_ICSR_PENDSVCLR ((uint32_t)0x08000000)
#define SCB_ICSR_PENDSTSET ((uint32_t)0x04000000)
#define SCB_ICSR_PENDSTCLR ((uint32_t)0x02000000)
#define SCB_ICSR_ISRPREEMPT ((uint32_t)0x00800000)
#define SCB_ICSR_ISRPENDING ((uint32_t)0x00400000)
#define SCB_ICSR_RETTOBASE ((uint32_t)0x00000800)
#define SCB_VTOR (*(volatile uint32_t *)0xE000ED08) // Vector Table Offset
#define SCB_AIRCR (*(volatile uint32_t *)0xE000ED0C) // Application Interrupt and Reset Control
#define SCB_SCR (*(volatile uint32_t *)0xE000ED10) // System Control Register

Ładowanie…
Anuluj
Zapisz