SD.open()?

If you're completely stuck, here are a couple alternate ideas.

First the easy one that's unlikely to yield results, but it's so simple you might as well give it a try. Instead of calling SD.open(), you can call SD.sdfs.open() to directly access the SdFat open function. This gives you the ability to configure the filesystem driver. Click File > Examples > SD > SDFat_Usage for examples of the syntax you can use. Who knows, maybe you'll get lucky and find one of the alternate ways "solves" the problem, or makes it behave differently enough to give you more info. It's a long shot, but so easy to try you might as well.

If that doesn't work out, my other suggestion which involves a lot more work, but is almost certain to eventually lead to a solution, is to whittle your program down and keep retesting whether the problem happens. Maybe you'll find removing something magically makes the problem vanish, and then of course you can focus on that thing.

But if you do end up with a fairly small program that still has the problem, then the final step is to share it here. If there really is something wrong inside SD / SdFat, sharing the exact code and files needed on the SD card so anyone can reproduce the issue is the first step to involve me and anyone else to actually dig into the issue. We do have a pretty good history of truely getting to the bottom of difficult problems on this forum, when full code and details allow anyone to reproduce the issue. And sometimes we even figure things out by blind guesswork, but that's not a solidly reliable path to success.
 
Using BBEdit & Cmd-shift-. I was able to track it down to SpSPICard.cpp - SharedSpiCard::cardCommand(uint8_t cmd, uint32_t arg) and it fails in the waitReady(SD_CMD_TIMEOUT). I'm guessing I must break the SPI in some way.

I"m trying to pair down the stuff now, but I'm kinda' zonked. So.. Time for a break.
 
Hey Jim, I'm trying to understand what is happening with the code your trying to troubleshoot, is this an intermittent problem? are you using CrashReport in your code? does the teensy lock up/reboot when this happens? or the code just won't work the way you expect.
 
This is for Frank, he was trying to understand what's happening. So I'm writing a bit of a description of what's going on over here. This is not a "Hey come fix this." post.

Crashing? Not working right? It's an inevitable problem. Runs for a while, when it fails, it seems to stay failed.
Typically the Teensy will keep running. I'll get white rectangles on the screen where it can't open a .bmp file to draw. Then at some point it'll reboot the processor. Probably when a piece of code doesn't check that it has no .bmp file to read from.

I have..
Teensly 4.0 and a MSP3526_T.h display with a SD card on it.

I have a sketch switching framework running. This is code that I've been using since before covid. But, there's always updates and changes. It's bascially a way of swapping sketch objects in and out of RAM. Here's an example so you can see what I'm talking about : Wokwi version (Using a mega)

I have a couple different paths for reading .bmp files. Icons & pictures. I get a random amount of .bmp files fine then at some point when looking for a .bmp file to draw. The SD drive usually fails with my trace message of "##### SharedSpiCard::waitReady() is timing out!!! #####". And then everything falls apart. Sometime it fails elsewhere but they always show up in "******** SharedSpiCard::readStart()->cardCommand() FAIL! ********" Just sometimes I don't see the timeout one. Oh and it's always on sector : 16384.

The screen is still fine. It can no longer open .bmp files, so it draws white rectangles as their defaults. I'm surprised that, if the SPI bus is timing out, that the screen still is fine.

The major changes from my last reliable system were..
The Swap from Teensy 3.2 to the Teensy 4.0.
This new higher resolution screen. LC_MSP3526_T
And, new hardware for mounting the processor.

I was a fool and changed all three at once.

I've checked the hardware as much as I can. I was worried about power, so I put in a bigger capacity battery and now run the screen directly from that. This was designed into the hardware as a" just in case" kinda' thing. I can read the battery voltage with the Teensy and it always looks fine. If there's a problem with the hardware, I'm pretty much stuck. My EE is sailing around somewhere between here and Alaska 'till fall.

As for crashing or rebooting. Sometimes it will reboot. If, after the SD card fails, and the next screen is just drawing & icons? It may not crash. You'll see square white boxes where the icon's belong. If there's .bmp image that's not an icon? I -think- that causes it to crash. This is all kinda' muddy and I don't know enough here is say what's going on at all.

Don't know anything about CrashReport.

What else have I found out..

Just opening .bmp files alone as images, doesn't seem to trigger this.
Doing my path searches alone, don't seem to fail. IE : Opening folders of a path one by one to make sure the path sf valid before use.

So I'm currently combing through my .bmp image/icon code to see if I can find something I missed in my last update. Writing to a NULL pointer and not catching it? Using un-initialzed variable? Standard stuff..

NOTE : Sometimes I get no Serial printing at all. I'll do a tiny change somewhere and *poof* I got blank serial monitor. Nothing. Like Serial.begin() dosn't work or something. This is also disturbing.

So, this is where I am today.
 
FYI: https://www.pjrc.com/teensy/td_crashreport.html

There will be an 8 second pause and restart when a crash is handled. Then on restart, if it was a handled Crash, the 'report' can be sent to Serial/stream.

USB is very robust and will be there as requested during the BUILD, even if there is no Serial.begin(). If that doesn't work then something stomped it.
 
HA! Got something!

>>>>> GOT REPORT <<<<<<<
CrashReport:
A problem occurred at (system time) 15:17:30
Code was executing from address 0x2C864
CFSR: 82
(DACCVIOL) Data Access Violation
(MMARVALID) Accessed Address: 0x0 (nullptr)
Check code at 0x2C864 - very likely a bug!
Run "addr2line -e mysketch.ino.elf 0x2C864" for filename & line number. <<< What's this? How do I do this?
Temperature inside the chip was 43.87 °C
Startup CPU clock speed is 528MHz
Reboot was caused by auto reboot after fault or bad interrupt detected
>>>>> GOT REPORT <<<<<<<
 
HA! Got something!

>>>>> GOT REPORT <<<<<<<
CrashReport:
A problem occurred at (system time) 15:17:30
Code was executing from address 0x2C864
CFSR: 82
(DACCVIOL) Data Access Violation
(MMARVALID) Accessed Address: 0x0 (nullptr)
Check code at 0x2C864 - very likely a bug!
Run "addr2line -e mysketch.ino.elf 0x2C864" for filename & line number. <<< What's this? How do I do this?
Temperature inside the chip was 43.87 °C
Startup CPU clock speed is 528MHz
Reboot was caused by auto reboot after fault or bad interrupt detected
>>>>> GOT REPORT <<<<<<<

@jim lee: Paul has created a CrashReport() <webpage> with useful details. You can also check the entry in the unofficial Teensy wiki <here> for links to descriptions of where to find the addr2line utility for both the old (1.8.x) & new (2.3.x) Arduino IDE, as well as detailed descriptions of how to use it.

Good luck . . .

Mark J Culross
KD5RXT
 
Jim, I ask because the issues you describe have happened to me. not exactly but similar. Crashreport helped me track down a very intermittent bug and it was indeed a null pointer problem (related to the SD access). I've also seen where the serial monitor would not respond, I had thought maybe it was a computer issue and I would need to reinstall things. Still not sure about that as the serial monitor seems to work most times.
My solution was to work through my code (6000+ lines, lots of coffee for sure) and make sure everywhere that a pointer might be used I put guards in place to catch the nasty NULL pointer issue before it gets used.
I just started using pointers so still got a lot to learn, using addr2line it led me to the sd library. So I figured my code was calling the sd with a null pointer somewhere. The problem was not in the sd library itself but in me calling a function in it with a null pointer.
In my case I added this in code before I try to access/use the pointer,

char *token; // declare the pointer
if (token == nullptr) return; //is null, so do nothing

I not saying this will solve all problems, but it helped me sort this bug out.
 
Last edited:
@jim lee: Paul has created a CrashReport() <webpage> with useful details. You can also check the entry in the unofficial Teensy wiki <here> for links to descriptions of where to find the addr2line utility for both the old (1.8.x) & new (2.3.x) Arduino IDE, as well as detailed descriptions of how to use it.

Good luck . . .

Mark J Culross
KD5RXT
Yeah! I read that www page about it. But the bit that talks about “address to function”? It says “TODO..”. So my question still stands. What takes this info. I’ve been given?
 
Jim, I ask because the issues you describe have happened to me. not exactly but similar. Crashreport helped me track down a very intermittent bug and it was indeed a null pointer problem (related to the SD access). I've also seen where the serial monitor would not respond, I had thought maybe it was a computer issue and I would need to reinstall things. Still not sure about that as the serial monitor seems to work most times.
My solution was to work through my code (6000+ lines, lots of coffee for sure) and make sure everywhere that a pointer might be used I put guards in place to catch the nasty NULL pointer issue before it gets used.
I just started using pointers so still got a lot to learn, using addr2line it led me to the sd library. So I figured my code was calling the sd with a null pointer somewhere. The problem was not in the sd library itself but in me calling a function in it with a null pointer.
In my case I added this in code before I try to access/use the pointer,

char *token; // declare the pointer
if (token == nullptr) return; //is null, so do nothing

I not saying this will solve all problems, but it helped me sort this bug out.
I suspect what’s going on here is very similar. In fact, that crash locator stuff from above was telling me that exact thing. Somewhere I’m letting a NULL pointer out unchecked.

I’m paying for my sloppy coding practices.
 
So my question still stands. What takes this info. I’ve been given?

The gcc toolchain has a program called addr2line. You give it the .elf file and the address, and it tries to tell you the corresponding line in the source code.

Successfully doing this isn't so simple. You have the find the program and your .elf file, and then run it by command line with the right syntax. Easy if you're familiar with unix command line and you know the locations of everything. Plenty of opportunity for things to do wrong if you don't have that knowledge and experience.
 
Yeah, I saw the command line. Thought about my Mac. Read the www. Then figured, there must be a bunch of stuff “Missing in the box”.

I’m assuming the gcc that comes in the Arduino IDE has no accessible command line to run this?
 
I’m assuming the gcc that comes in the Arduino IDE has no accessible command line to run this?
It will be in the ../bin directory with the rest of the GCC programs. Runable in xterm or whatever terminal window your OS provides.

But that is of limited use. What would be really helpful is to have gdb runing when this happens. Then you could examine the stack frame (who called) to see where that bogus pointer came from. But the Arduino/Teensy system doesn't provide for a JTAG connection. Making debugging a PITA.
 
It will be in the ../bin directory with the rest of the GCC programs. Runable in xterm or whatever terminal window your OS provides.

But that is of limited use. What would be really helpful is to have gdb runing when this happens. Then you could examine the stack frame (who called) to see where that bogus pointer came from. But the Arduino/Teensy system doesn't provide for a JTAG connection. Making debugging a PITA.
I'm curious how you think CrashReport squirrels away the information if you think catching a fault requires JTAG.
 
Well.. If anyone has an Idea where this .elf file can be..

I go to my Arduino15 folder in the terminal and tried find "handheld.ino.elf" and I get nothing. Searching from my user folder I get a LOT of access denied..
 
Yeah! I read that www page about it. But the bit that talks about “address to function”? It says “TODO..”. So my question still stands. What takes this info. I’ve been given?
Did you also look at the wiki page ?? Has many of the details that you are asking/looking for . . . & no TODOs there :) . . .

Mark J Culross
KD5RXT
 
From the Sketch menu in the IDE there is an "Export compiled binary" option that will build the .elf in a subdirectory of the sketch folder. Otherwise by default it will be in a temp directory somewhere, decided by the OS.
 
MacOS version is installed on your machine deep inside the ~/Library/Arduino15 directory, together with all the other compiler utilities.

1779922669612.png


If you use version 1.62 (currently in beta testing) the path will have version 15.2.1 rather than 11.3.1. And if you use 1.57 or older, it will be an older compiler version.
 
objdump -S says:

Code:
0002c580 <strlen>:
   2c580:       f890 f000       pld     [r0]
   2c584:       e96d 4502       strd    r4, r5, [sp, #-8]!
   2c588:       f020 0107       bic.w   r1, r0, #7
   2c58c:       f06f 0c00       mvn.w   ip, #0
   2c590:       f010 0407       ands.w  r4, r0, #7
   2c594:       f891 f020       pld     [r1, #32]
   2c598:       f040 8049       bne.w   2c62e <strlen+0xae>
   2c59c:       f04f 0400       mov.w   r4, #0
   2c5a0:       f06f 0007       mvn.w   r0, #7
   2c5a4:       e9d1 2300       ldrd    r2, r3, [r1]
   2c5a8:       f891 f040       pld     [r1, #64]       @ 0x40
   2c5ac:       f100 0008       add.w   r0, r0, #8
 
Wait, is this saying that passing a NULL to strlen() is causing a crash? Or something else bashed memory and broke strlen()?

Thank you! BTW. I guess all search out all my calls to strlen().
 
Back
Top