Specific timing of thread start causes hard fault (invalid EXC_RETURN) in Teensy core

Merlin04

New member
There's a very weird bug I've encountered - I'm not sure if it's an issue with TeensyThreads or with the Teensyduino core, so I'm reporting the issue to both places. There's more details at https://github.com/ftrias/TeensyThreads/issues/42 - but to summarize, some specific timing between the end of a thread and the creation of a new one causes a hard fault (invalid EXC_RETURN) inside the `cores/teensy4/yield.cpp` file in the teensy core library. There are many more details + a full reproducible example over in the GitHub repo (I'd put it here but I'm not as familiar with forum markup), if you think it's an issue with teensyduino I can move the github issue over to the PaulStoffregen/cores repo.
 
It is not safe to use TeensyThread's primitives (thread functions, mutexes) within ISR callbacks such as IntervalTimer.
Creating a thread (done in the function a() used by the IntervalTimer) may cause a new thread to be scheduled, which switches the current stack and removes the exception information required to return from the ISR.
 
Oh ok, that makes sense - I didn't realize that I couldn't create threads from ISRs (would be awesome if that could be added to documentation somewhere to save others from this issue!). In this case, how could I create a thread when an interrupt is triggered? Is it possible to tell TeensyThreads to not schedule the thread until the ISR is over? I tried using EventResponder to trigger a callback added as a low priority interrupt but that didn't work for what I now know to be the same reason.

(also, feel free to move this thread to troubleshooting if possible - wasn't my intention to clutter up the bug reports section, super sorry about that!)
 
As p#1 indicates - it is a weird process - but thought to see if breadcrumbs might show where the oddity came up.

First step seemed counting entry and exits - they were all balanced.

And wiping out factory weak yield() - just changed where the fault was reported.

Not related but got tired of hearing the USB chimes on repeat restarts so came up with this to limited restarts after each build:
Code:
#include <TeensyThreads.h>
#include <CrashReport.h>

#include <EEPROM.h>

volatile unsigned int d = 1;
uint32_t bc1 = 0;
uint32_t bc2 = 0;
uint32_t bc3 = 0;
uint32_t bc4 = 0;
uint32_t bc5 = 0;
[U]void yield() {}[/U]

void threadFn() {
  CrashReport.breadcrumb(1, bc1++);
  next();
  CrashReport.breadcrumb(1, bc1++);
}

IntervalTimer t;

void a() {
  CrashReport.breadcrumb(2, bc2++);
  threads.addThread(threadFn);
  t.end();
  CrashReport.breadcrumb(2, bc2++);
}

void next() {
  CrashReport.breadcrumb(3, bc3++);
  d += 1;
  threads.addThread(threadFn);
  t.begin(a, d);
  CrashReport.breadcrumb(3, bc3++);
}

void setup() {
  // put your setup code here, to run once:
  delay(5000);
[B]  if (CrashReport) {
    static char szTime[] = __TIME__;
    int ii, jj;
    Serial.println(CrashReport);
    ii = atoi(&szTime[3]) * 100;
    ii += atoi(&szTime[6]);
    Serial.println(__TIME__);
    Serial.println(ii);
    EEPROM.get(0, jj);
    if (ii == jj) {
      Serial.println("Stopping");
      EEPROM.put(0, ii - 1);
      while (1)
        ;
    }
    EEPROM.put(0, ii);
  }
[/B]  delay(5000);
[U]  threads.setSliceMicros(4000);[/U]
  threads.addThread(threadFn);
  // we're going to scan through a list of possible delays to figure out what triggers the fault
  next();
}

void loop() {}

Output looks like this - each of the three marked functions enter and exit the proper number of times ... and moving the timeslice up from 400 to 4000 changed nothing:
Code:
CrashReport:
  A problem occurred at (system time) 23:12:0
  Code was executing from address 0x13AE
  CFSR: 40000
	(INVPC) Usage fault: invalid EXC_RETURN
  Temperature inside the chip was 50.51 °C
  Startup CPU clock speed is 600MHz
  Reboot was caused by auto reboot after fault or bad interrupt detected
  Breadcrumb #1 was 1 (0x1)
  Breadcrumb #2 was 3 (0x3)
  Breadcrumb #3 was 3 (0x3)

22:44:48
4448
CrashReport:
  A problem occurred at (system time) 23:12:18
  Code was executing from address 0x22C
  CFSR: 40000
	(INVPC) Usage fault: invalid EXC_RETURN
  Temperature inside the chip was 50.51 °C
  Startup CPU clock speed is 600MHz
  Reboot was caused by auto reboot after fault or bad interrupt detected
  Breadcrumb #1 was 1 (0x1)
  Breadcrumb #2 was 3 (0x3)
  Breadcrumb #3 was 3 (0x3)

22:44:48
4448
Stopping
 
Back
Top