Can you explain this planned lib in more detail ? What is it supposed to do ?I'll write a dynamic IRQ library for testing this weekend. What I want at this point is just a list of IRQs that will be considered reserved for the SWIs.
.
Yes, if nested means one interrupt cause interrupting a lower priority interrupt cause - in hardware. I was referring to where any one ISR reads some I/O status to clear the interrupt request for that level, then reenables interrupts at that same level. This can lead to reentry risks.I'm confident ARM has implemented nested interrupts correctly with the NVIC. It's entirely in hardware.
Paul, did you notice my post #32 ?
... where any one ISR reads some I/O status to clear the interrupt request for that level, then reenables interrupts at that same level. This can lead to reentry risks.
#define NVIC_STIR (*(volatile uint32_t *)0xE000EF00)
#define NVIC_TRIGGER_INTERRUPT(x) NVIC_STIR=(x);
volatile int chk;
void softISR() {
chk = 1;
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
Serial.println("...OK.");
}
const unsigned char swInterrupts[] = {
#if defined(__MK20DX128__)
5,
#elif defined(__MK20DX256__)
17,23,28,37,38,39,40,41,42,43,51,52,53,54,55,56,75,76,77,78,79,80,82,86,92,93,
#endif
IRQ_UART0_LON,
IRQ_SOFTWARE,
0};
void setup() {
while(!Serial);
pinMode(LED_BUILTIN, OUTPUT);
Serial.begin(115200);
}
void loop() {
Serial.println("Reserved Interrupt tester");
unsigned char n = 0;
while (swInterrupts[n] > 0) {
int interrupt = swInterrupts[n];
Serial.printf("%d (%d)",interrupt + 16, interrupt);
_VectorsRam[interrupt+16] = softISR;
NVIC_ENABLE_IRQ(interrupt);
chk = 0;
//Trigger swi this way :
//NVIC_SET_PENDING(interrupt);
//Or this way (faster):
NVIC_TRIGGER_INTERRUPT(interrupt);
delay(50);
if (!chk) Serial.println("...NOT OK.");
n++;
}
Serial.println("Done.");
while(1){;}
}
Reserved Interrupt tester
21 (5)...OK.
31 (15)...OK.
61 (45)...OK.
Done.
Reserved Interrupt tester
33 (17)...OK.
39 (23)...OK.
44 (28)...OK.
53 (37)...OK.
54 (38)...OK.
55 (39)...OK.
56 (40)...OK.
57 (41)...OK.
58 (42)...OK.
59 (43)...OK.
67 (51)...OK.
68 (52)...OK.
69 (53)...OK.
70 (54)...OK.
71 (55)...OK.
72 (56)...OK.
91 (75)...OK.
92 (76)...OK.
93 (77)...OK.
94 (78)...OK.
95 (79)...OK.
96 (80)...OK.
98 (82)...OK.
102 (86)...OK.
108 (92)...OK.
109 (93)...OK.
60 (44)...OK.
110 (94)...OK.
Done.
Teensy 3.0 Teensy 3.1
---------- ----------
Audio 45 94
MP3 56
UHS 5 17
#include "SoftwareInterrupt.h"
SoftwareInterrupt myIntr;
void setup() {
// required:
myIntr.attach(function); // clear, attach function, and enable, so ready to trigger
myIntr.trigger();
// optional:
myIntr.priority(number); // defaults to TBD if this is not used
myIntr.clear(); // clear pending, if triggered but not yet run
myIntr.disable(); // disable this interrupt
myIntr.enable(); // reenable it
}
/**
* Use this class to extend your class, in order to provide
* a C++ context callable SWI.
*/
class dyn_SWI {
/**
* Override this method with your code.
*/
virtual void dyn_SWISR(void) {};
};
Ok, here's a simple fixed allocation, to serve as a temporary measure until a nice dynamic system is made.
Code:Teensy 3.0 Teensy 3.1 ---------- ---------- Audio 45 94 MP3 56 UHS 5 17
I would leave 94 to the user, since it is documentated in the Datasheets. This leads to less questions..
I'm thinking on passing a class instance.
That way it does not have to be static!
I would leave 94 to the user, since it is documentated in the Datasheets. This leads to less questions..
I'll use 5/17 for the library. I should only need one now.
I don't quite follow what you're trying to do with that.
The simple API can be either static or dynamic. Each call to trigger() could do stuff like you proposed in msg #9. The function to give to attach() doesn't have to know whether it was called directly by the NVIC or if some other intermediate handler called it.
Paul mentioned that IRQ_UART0_LON is unused too.
Just to remind: We can use ANY interrupt, if it is not used by a device.
I would say, we could add flash_error_isr or flash_cmd_isr to our list too, for teensy 3.0.
#define NVIC_GET_ACTIVE(n) (*((volatile uint32_t *)0xE000E300 + ((n) >> 5)) & (1 << ((n) & 31)))
Given the fact that we are talking about software interrupts , I would like to propose the following macro :
(similar to the other NVIC_ macros)Code:#define NVIC_GET_ACTIVE(n) (*((volatile uint32_t *)0xE000E300 + ((n) >> 5)) & (1 << ((n) & 31)))
Thus, it can be determined from an interrupt with a higher priority , whether a certain other was interrupted.
For my codecs. e.g. that makes sense.