Re-enable bootloader interrupts after a hard fault [Teensy 4.1]

Got now current CORES and the MyFaults into libraries.

First Bus_Fault.ino does a FAST reboot sequence.

Not seeing any 8 sec delay in : unused_interrupt_vector()

@Mike - is this what you were saying in p#162?


Note: the CRC compare as suggested p#160 wouldn't work I saw before update as the CRC includes Time and Temp.
 
Forgot to note: re Bus_Fault.ino

The sample should have:
Code:
if ( Serial )
  Serial.print(CrashReport);

Even using TyComm Serial OFF was doing fast reboot of p#176 because the Crash info was always being cleared - even when the data was never displayed.

Actually to DEMO the feature perhaps it should have:
Code:
  if ( CrashReport && Serial )  {
    Serial.print(CrashReport);
  }
 
Got now current CORES and the MyFaults into libraries.

First Bus_Fault.ino does a FAST reboot sequence.

Not seeing any 8 sec delay in : unused_interrupt_vector()

@Mike - is this what you were saying in p#162?


Note: the CRC compare as suggested p#160 wouldn't work I saw before update as the CRC includes Time and Temp.

No for the Bus Fault sketch I am seeing this along with a reboot
Code:
CrashReport:
  Fault occurred at: 18:25:39
  Temperature and System Clock at time of fault: 
    Temp = 40.700935 deg C,  Sys Clock = 600 Mhz
  length: 11
  IPSR: 5
  CFSR: 400
	(IMPRECISERR) Data bus error but address not related to instruction
  MMFAR: 0
  BFAR: 0
  return address: 1D22
  XPSR: 81000000
  crc: F5F0B0E2
Reboot was caused by 8 second auto-reboot after fault or bad interrupt detected
Bus Fault
and you don't need the SCB_SHCSR in the sketch as its in the core now.

The issue I was seeing was with turning off the FPU - no crash report just the constant immediate reboot.
 
No for the Bus Fault sketch I am seeing this along with a reboot
...
and you don't need the SCB_SHCSR in the sketch as its in the core now.

The issue I was seeing was with turning off the FPU - no crash report just the constant immediate reboot.

Just noticed building with IDE was still showing the now removed 'Hello World'??? So back to Sublime build and the 2 second Reset stopped. It is doing the 8 second wait before restart.

Removing the SCB_SHCSR seems right

And the change to add the p#177 is questionable value - given it just immediately does the same fault again. Though that would show expected use case in the example?
 
Bus_Fault :: (IMPRECISERR) Data bus error but address not related to instruction
: >> works as expected - 8 second restart with Crash text
--> Has extraneous SCB_SHCSR in code
Constructor_NULL_Pointer :: No Report
: >> works as with 8 second restart with no Crash text display
Division_By_Zero :: (DIVBYZERO) Divide by zero
: >> works as expected - 8 second restart with Crash text
FlexIO_Register :: No Report
: >> Teensy Hung Offline after running
FPU_Turned_Off :: No Report
: >> SPASTIC FAST repeated Restart
--> In "it's your fault" sample the other day it was working. - but that stopped too ????
Illegal_Instruction :: (IACCVIOL) Instruction Access Violation
: >> works as expected - 8 second restart with Crash text
Imprecise_Error :: (IMPRECISERR) Data bus error but address not related to instruction
: >> works as expected - 8 second restart with Crash text
--> Has extraneous function for Illegal Instruc at top
Instruction_Access_Violation :: (IACCVIOL) Instruction Access Violation
: >> works as expected - 8 second restart with Crash text
NULL_Pointer_Write :: (DACCVIOL) Data Access Violation
:: (MMARVALID) Accessed Address: 0x0 (nullptr)
: >> works as expected - 8 second restart with Crash text
Stack_overflow :: (DACCVIOL) Data Access Violation
:: (MMARVALID) Accessed Address: 0x200032D8 (Stack problem)
: >> works as expected - 8 second restart with Crash text

Made two PR's - items noted 'extraneous ' above
Remove other fault copied code
#9 opened 15 seconds ago by Defragster
Remove line now in CORES
#8 opened 3 minutes ago by Defragster
 
Last edited:
Running the repeat Fault code - and hitting the Button to stop the restarts ... it was odd to start the NEXT example and have it then show the prior CrashReport

Perhaps some wording change to first line :: CrashReport:
Something that points out this was from PRIOR code execution?

Something like : CrashReport for prior running sketch:

Also wording of:
Fault occurred at: 15:01:58
Temperature and System Clock at time of fault:
Temp = 47.666668 deg C, Sys Clock = 600 Mhz

Given the prior line shows system "Clock" time ...

Perhaps: Temperature and System Clock speed at time of fault:

Also I had ONE restart (running all those p#180 examples) with no recorded crash and saw :: No Crash Reported or Crash was Cleared
 
Does this seem like a worthy Example: TypicalUse.ino

Code:
// Typical Usage Example : when a sketch is leaving the Teensy non-responsive

void setup() {
  Serial.begin(9600); // With TeensyDuino 1.54 Serial.begin() may return connected
  if ( Serial && CrashReport ) { // Make sure Serial is alive and there is a CrashReport stored.
    Serial.print(CrashReport); // Once called any crash data is cleared
    // In this case USB Serial is used - but any Stream capable output will work : SD Card or other UART Serial
  }
  else {
    // Following code will cause a Fault of the processor from writing to a NULL pointer
    // Don't run it again until the next restart showing normal after a fault
    uint32_t *y = 0;
    y[0] = 5;
  }
  pinMode( LED_BUILTIN, OUTPUT );
}

elapsedMillis blinkTime;
void loop() {
  if ( blinkTime > 1000 ) {
    digitalToggle( LED_BUILTIN );
    blinkTime = 0;
  }
}
 
@Kurt (Good Morning):

I looked at the bus fault again.
Looks like that I used a read only Address. 0x4039C000 is LPSPI3_VERID which conatains version numbers.

The question remains why the other adresses don't fault anymore. Is it a 1062 feature?

Edit: Seems "yes". I tested more and tried different thing. A devices with disabled clock does not produce a fault anmory on register acess.
Your can write, and it returns zero.
Page 1083, RM says for disabled clock: "Clock is off during all modes. Stop enter hardware handshake is disabled."
So it just does not access the register.
 
Last edited:
@Kurt (Good Morning):

I looked at the bus fault again.
Looks like that I used a read only Address. 0x4039C000 is LPSPI3_VERID which conatains version numbers.

The question remains why the other adresses don't fault anymore. Is it a 1062 feature?

Edit: Seems "yes". I tested more and tried different thing. A devices with disabled clock does not produce a fault anmory on register acess.
Your can write, and it returns zero.
Page 1083, RM says for disabled clock: "Clock is off during all modes. Stop enter hardware handshake is disabled."
So it just does not access the register.

I liked the current bus fault with *(uint32_t *)0x4039C000 = 0;. I gave a

Code:
	(IMPRECISERR) Data bus error but address not related to instruction
If you change it to *(volatile uint32_t *)0x30000000 = 0; I now see
Code:
	(DACCVIOL) Data Access Violation
	(MMARVALID) Accessed Address: 0x30000000
Which I think we have an example for already.
 
yup.
But accessing a not enabled device does not result in an error. That's OK :)

:) and good morning.

@Paul - alcon

Sorted out the issue I had with the Temp fault example. Anyway, I undeleted it and added another simple sketch, while technically not a fault, it sets up high/temp alarm ISR and then uses that in the loop too give a warning and throttle back the clock to 24Mhz.
 
Good Morning all... Slept in... After 5 now...

@Frank - sounds good and very possible... Although I guess I hit one with one system that did not get fixed (FlexIO)...

So Thanks, wonder if it was different with 1052 as I know early on was hitting things like this a lot!...

May try a few more...

Thanks again for help clearing that up!
 
Does this seem like a worthy Example: TypicalUse.ino

Code:
// Typical Usage Example : when a sketch is leaving the Teensy non-responsive

void setup() {
  Serial.begin(9600); // With TeensyDuino 1.54 Serial.begin() may return connected
  if ( Serial && CrashReport ) { // Make sure Serial is alive and there is a CrashReport stored.
    Serial.print(CrashReport); // Once called any crash data is cleared
    // In this case USB Serial is used - but any Stream capable output will work : SD Card or other UART Serial
  }
  else {
    // Following code will cause a Fault of the processor from writing to a NULL pointer
    // Don't run it again until the next restart showing normal after a fault
    uint32_t *y = 0;
    y[0] = 5;
  }
  pinMode( LED_BUILTIN, OUTPUT );
}

elapsedMillis blinkTime;
void loop() {
  if ( blinkTime > 1000 ) {
    digitalToggle( LED_BUILTIN );
    blinkTime = 0;
  }
}

What happens if it is a remote device NOT connected to any I/O?
 
So error code NOT being written to EEPROM? I thought that was what was going to happen. That way any use condition would be covered.
 
You're imagining the fault handler and CrashReport to be more than the simple tools they are. You certainly can use these tools to log data to non-volatile memory. But the design is meant to be fairly lightweight building blocks, rather than a complete solution encompassing all usage scenarios.
 
Let's hope there are going to be instructions as to how to handle the various situations, online and offline!
 
Did a test pass on examples/MyFault on a TallDog SD equipped T_4.0!

Results Similar in general to p#180 where those things that won't work to trap - don't work.

A bit more complex with extra intro code shows the code works as expected - Crashes are Caught and Teensy works on restart as expected. Except for 'Stack_overflow' - because it Faults with: loop() { loop(); }

Added a code snippet replacing void setup() { in the examples with the following that Streams CrashReport to SD Once until the sketch name.txt exists { Opps - it does 2nd CrashReport>>SD } , if no Crash and no file it runs the Xsetup():
Code:
#include <SD.h>
#include <SPI.h>
const char Csketch[] = __FILE__;
char sketch[64];
int newF = 1;
void setup() {
  pinMode( LED_BUILTIN, OUTPUT );
  digitalWrite( LED_BUILTIN, 1 );
  uint ii = sizeof( Csketch );
  while ( Csketch[ii] != '\\') ii--;
  ii++;
  uint jj=0;
  while ( ii < sizeof( Csketch ) && Csketch[ii] != '.') {
    sketch[jj] = Csketch[ii];
    ii++;
    jj++;
  }
  strcpy( &sketch[jj], ".txt" );
  Serial.println(sketch);

  Serial.begin(115200);
  while (!Serial && millis() < 4000 );
  Serial.println("\n" __FILE__ " " __DATE__ " " __TIME__);
  Serial.printf(" millis() now %u\n", millis() );
  if ( CrashReport ) {
    if (SD.begin(BUILTIN_SDCARD)) {
      if ( SD.exists(sketch) ) {
        Serial.print( "FILE EXISTS");
        newF = 0;
      }
      File dataFile = SD.open(sketch, FILE_WRITE); // FILE_WRITE append if file already exists
      if (dataFile) {
        dataFile.print(CrashReport);
        dataFile.close();
      }
    } else if ( Serial ) {
      Serial.print(CrashReport);
    }
    Serial.print("\n\tRECOVERED from Crash !");
  }

  delay ( 100 );
  digitalWrite( LED_BUILTIN, 0 );
  delay ( 1000 );
  digitalWrite( LED_BUILTIN, 1 );
  Serial.println(sketch);
  if ( 1 == newF ) Xsetup();
  else Serial.print("\n\tDONE !");
}


void Xsetup() {

Run process after upload where no Fault exists - runs the Xsetup() { Fault test code } - on restarting with fault it logs to SD once and then DONE !:
Code:
[B]T:\arduino-1.8.15\hardware\teensy\avr\libraries\MyFault\examples\NULL_Pointer_Write\NULL_Pointer_Write.ino Jun 26 2021 09:56:46[/B]
 millis() now 658
NULL_Pointer_Write.txt
No Crash Reported or Crash was Cleared

[B]T:\arduino-1.8.15\hardware\teensy\avr\libraries\MyFault\examples\NULL_Pointer_Write\NULL_Pointer_Write.ino Jun 26 2021 09:56:46[/B]
 millis() now 432

	RECOVERED from Crash !NULL_Pointer_Write.txt
No Crash Reported or Crash was Cleared

[B]T:\arduino-1.8.15\hardware\teensy\avr\libraries\MyFault\examples\NULL_Pointer_Write\NULL_Pointer_Write.ino Jun 26 2021 09:56:46[/B]
 millis() now 433
FILE EXISTS
	RECOVERED from Crash !NULL_Pointer_Write.txt

	DONE !

Anyhow - that indicates Crash Report works well - even on T_4.0 - with process able to Stream to SD card and Teensy being Stable and usable on the Faults it can Handle.

Here are the SD output TXT files for fun:
 
Last edited:
We have a macro NVIC_IS_ACTIVE that can be used (I think priorities need to be considered - find the highest priority of active interrupts?) to determine which interrupt we are in.
There may also be a shortcut.

Edit: Ah yes, the IPSR can be used. Had used this in my old version.
 
Printf: Hm, do we use printf elsewhere (besides debugging?)
If not, we problably should return to normal prints... printf still needs a lot of memory. It it is used only in CrashReport, i'd change that..
 
IPSR is captured in startup.c on crash, like in hardFault.cpp.
Code:
	asm volatile("mrs %0, ipsr\n" : "=r" (ipsr) :: "memory");
	info = (struct arm_fault_info_struct *)0x2027FF80;
	info->ipsr = ipsr;

It was printed in CrashReport - now commented out - but it is available if it would tell something.
Code:
    //p.print("  IPSR: ");
    //p.println(info->ipsr, HEX);

From: keil.com/.../CMSIS/.../unionIPSR__Type.html
Code:
    //p.print("  IPSR: ");
    //p.println(info->ipsr, HEX);
 
Printf: Hm, do we use printf elsewhere (besides debugging?)
If not, we problably should return to normal prints... printf still needs a lot of memory. It it is used only in CrashReport, i'd change that..

I assumed that was the PJRC printf in :: T:\arduino-1.8.15\hardware\teensy\avr\cores\teensy4\debugprintf.c
THough maybe not ??/
 
To make it easy to run any of the MyFault\Examples - below is a DOS batch file.

In the FOLDER above "\Examples" Copy that to something like :: buildone.bat
Code:
 Directory of T:\arduino-1.8.15\hardware\teensy\avr\libraries\MyFault\examples

06/27/2021  02:33 AM    <DIR>          .
06/27/2021  02:33 AM    <DIR>          ..
06/27/2021  03:04 AM    <DIR>          all
06/27/2021  03:04 AM               625 buildone.bat

When done there will be an all\all.ino created where each example has a commented #define at the top to build setup() and loop() for that example.
Code:
//#define S1 // "T:\arduino-1.8.15\hardware\teensy\avr\libraries\MyFault\examples\Constructor_NULL_Pointer\Constructor_NULL_Pointer.ino" 
//#define S2 // "T:\arduino-1.8.15\hardware\teensy\avr\libraries\MyFault\examples\Data_Access_Violation\Data_Access_Violation.ino" 
//#define S3 // "T:\arduino-1.8.15\hardware\teensy\avr\libraries\MyFault\examples\Division_By_Zero\Division_By_Zero.ino" 
...

I just did a sync from github and it looks like this, just put this in a directory "all" and uncomment one #define and build, changing then builds about 4 times faster with simple comment swap:
Code:
[B][ATTACH]25141._xfImport[/ATTACH][/B]

The batch file contents - it wipes all\all.ino so it isn't included, so migrate out any changes before running this:
Code:
@echo off
cls 
md all
del all\all.txt
del all\all.ino
SET count=1
 FOR /F "tokens=*" %%G IN ('dir /b /s ^"*.ino^"') DO (
 call :subroutine1 "%%G" )
 GOTO :parttwo
 
 :parttwo
 SET count=1
 echo. >> all\all.txt
 FOR /F "tokens=*" %%G IN ('dir /b /s ^"*.ino^"') DO (
 call :subroutine2
 type %%G >> all\all.txt
 echo #endif >> all\all.txt
 echo. >> all\all.txt )
 pause
 ren all\all.txt all.ino
 GOTO :eof
 
:subroutine1
 echo //#define S%count% // %1 >> all\all.txt
 set /a count+=1
 GOTO :eof
 
:subroutine2
 echo #if defined S%count% >> all\all.txt
 echo %count%
 set /a count+=1
 GOTO :eof
 
Back
Top