Hi all,
in the following code i think that the Serial1 "serial_write" handler function is still not handling "Priority Inversion" correctly. It's my understanding that Teensyduino 1.17 Release Candidate #1 should of fixed this but i'm not sure. The code below sets up the Interval Timer CH0 with a priority that is equal to Serial1 and then prints using Serial1 in the interrupt handler routine for the Interval Timer. It runs for a few cycles then quits printing as far as I can tell. It also makes it so you have to push the upload code button on the teensy to reprogram it.
This might be a issue with the Interval Timer class not handling the inversion also, but if i leave the priority of Interval Timer at 64 and remove the Serial1.print code it works normally. The code below shows this.
The weird thing is it seems as if the interval timer works still even if the teensy is "sudo" locked up using example 1. The work around i found is to change PIT CH0 priority to 128 before calling Serial1.print and then change it back after shown below.
The reason i think i have to change the priority to 128 in the above example is that the USB is at priority 112 so that where the inversion i think is happening. Anyway i just wanted to share this case someone in counters the same problem. This probably won't be a issue with 99% of project but it is a problem for those setting priorities in thier code.
duff
in the following code i think that the Serial1 "serial_write" handler function is still not handling "Priority Inversion" correctly. It's my understanding that Teensyduino 1.17 Release Candidate #1 should of fixed this but i'm not sure. The code below sets up the Interval Timer CH0 with a priority that is equal to Serial1 and then prints using Serial1 in the interrupt handler routine for the Interval Timer. It runs for a few cycles then quits printing as far as I can tell. It also makes it so you have to push the upload code button on the teensy to reprogram it.
Code:
//example 1
#define NVIC_IABR1 *(volatile uint32_t *)0xE000E300
#define NVIC_IABR2 *(volatile uint32_t *)0xE000E304
IntervalTimer timer;
void PriorityInversionISR(void) {
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
[COLOR="#FF0000"][B]Serial1.println("Hello, World!!!");[/B][/COLOR]
int priority = nvic_execution_priority();
Serial.printf("current priority: %i | NVIC_IABR1: %#X | NVIC_IABR2: %#X\n", priority, NVIC_IABR1, NVIC_IABR2);
}
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
Serial.begin(0);
Serial1.begin(1200);
while(!Serial);
delay(100);
[COLOR="#FF0000"][B]NVIC_SET_PRIORITY(IRQ_PIT_CH0, 64);//<-- same priority as serial1[/B][/COLOR]
timer.begin(PriorityInversionISR, 100000);
}
void loop() {}
This might be a issue with the Interval Timer class not handling the inversion also, but if i leave the priority of Interval Timer at 64 and remove the Serial1.print code it works normally. The code below shows this.
Code:
example 2
#define NVIC_IABR1 *(volatile uint32_t *)0xE000E300
#define NVIC_IABR2 *(volatile uint32_t *)0xE000E304
IntervalTimer timer;
void PriorityInversionISR(void) {
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
[COLOR="#FF0000"][B]//Serial1.println("Hello, World!!!");<--- commented out, now works![/B][/COLOR]
int priority = nvic_execution_priority();
Serial.printf("current priority: %i | NVIC_IABR1: %#X | NVIC_IABR2: %#X\n", priority, NVIC_IABR1, NVIC_IABR2);
}
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
Serial.begin(0);
Serial1.begin(1200);
while(!Serial);
delay(100);
[COLOR="#FF0000"][B]NVIC_SET_PRIORITY(IRQ_PIT_CH0, 64); //<-- same priority as serial1[/B][/COLOR]
timer.begin(PriorityInversionISR, 100000);
}
void loop() {}
The weird thing is it seems as if the interval timer works still even if the teensy is "sudo" locked up using example 1. The work around i found is to change PIT CH0 priority to 128 before calling Serial1.print and then change it back after shown below.
Code:
//example 3
#define NVIC_IABR1 *(volatile uint32_t *)0xE000E300
#define NVIC_IABR2 *(volatile uint32_t *)0xE000E304
IntervalTimer timer;
void PriorityInversionISR(void) {
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
[COLOR="#FF0000"]
[B]
NVIC_SET_PRIORITY(IRQ_PIT_CH0, 128);//<--- Lower priority
Serial1.println("Hello, World!!!");
NVIC_SET_PRIORITY(IRQ_PIT_CH0, 64);//<--- increase priority
[/B]
[/COLOR]
int priority = nvic_execution_priority();
Serial.printf("current priority: %i | NVIC_IABR1: %#X | NVIC_IABR2: %#X\n", priority, NVIC_IABR1, NVIC_IABR2);
}
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
Serial.begin(0);
Serial1.begin(1200);
while(!Serial);
delay(100);
[COLOR="#FF0000"][B]NVIC_SET_PRIORITY(IRQ_PIT_CH0, 64); //<-- same priority as serial1[/B][/COLOR]
timer.begin(PriorityInversionISR, 100000);
}
void loop() {}
The reason i think i have to change the priority to 128 in the above example is that the USB is at priority 112 so that where the inversion i think is happening. Anyway i just wanted to share this case someone in counters the same problem. This probably won't be a issue with 99% of project but it is a problem for those setting priorities in thier code.
duff