Teensy 4.1 freezes if USB stick removed when reading/writing to it

Richard H

Member
Hi I am using Teensy 4.1 with Arduino IDE 2.3.4.
Consider the following standard setup for transferring data using an external USB stick attached to the Teensy.

#include <USBHost_t36.h> // import the Teensy USB library
int mscError=0; // USB error flag
USBHost myusb; // USB Host
USBHub hub1(myusb); // USB Hub
USBDrive myDrive(myusb); // Instance for one drive
USBDrive *drive_list[]={&myDrive}; // USB device array

byte blocks; // no of blocks to read or write
unsigned long startAddr; // start address (sector no)
uint32_t TotBytes=0; // no of bytes to read or write (blocks x 512)
byte USBData_writeBytes[16384]; // 16k write buffer
byte USBData_readBytes[16384]; // 16k read buffer

void setup() {
myusb.begin(); // initiate USB
delay(3000); // and wait a bit
}

void loop () {
myusb.Task();
USBDrive *pdrive=drive_list[0]; // initialise first (and only in this case) USB device

if (pdrive->msDriveInfo.connected==0) { // problem with USB device
Serial.println(" Problem with USB device \n");
}
else { // USB OK

if (writeFlag==1) { // write flag is true
mscError = myDrive.msWriteBlocks(startAddr, blocks, (uint16_t)512, USBData_writeBytes);
if (mscError==0) { // successful write
Serial.println("Successful write to USB device \n");
}
else { // failed write
Serial.println("Failed write to USB device \n");
}
}

if (readFlag==1) { // read flag is true
mscError = myDrive.msReadBlocks(startAddr, blocks, (uint16_t)512, USBData_readBytes);
if (mscError==0) { // successful read
Serial.println("Successful read from USB device \n");
}
else { // failed read
Serial.println("Failed to read from USB device \n");
}
}

} // usb ok

} // loop

The problem seems to be that if the USB media is removed during either the myDrive.msReadBlocks or myDrive.msWriteBlocks operations then the Teesny freezes and has to be physically reset.

Is the best method to catch this with a software driven reset from an timed interrupt method or via a threaded timer watching the state of the USB and initiating a software reset?

I was wondering if anybody else has encountered this problem?

Cheers
 
First of all the USB stick should NEVER be removed while a read or write operation is in progress. Any reads or writes should be finished before removing the USB drive. This also applies to an open file if using file operations. The file should be closed before hot plugging. Removing the USB drive during direct sector reads and writes will most likely cause a lockup needing a reset. It makes no sense to interrupt a read or write like that. Also I noticed that the "startAddress" variable is not initialized anywhere in the sketch.

Please use the "</>" in the upper left corner. It will bring up a window you can copy and paste your sketch into that will preserve the sketch formatting making it easier for others to read ;)
 
First of all the USB stick should NEVER be removed while a read or write operation is in progress. Any reads or writes should be finished before removing the USB drive. This also applies to an open file if using file operations. The file should be closed before hot plugging. Removing the USB drive during direct sector reads and writes will most likely cause a lockup needing a reset. It makes no sense to interrupt a read or write like that. Also I noticed that the "startAddress" variable is not initialized anywhere in the sketch.

Please use the "</>" in the upper left corner. It will bring up a window you can copy and paste your sketch into that will preserve the sketch formatting making it easier for others to read ;)
Many thanks for replying!

I think I noticed you were the creator of a USB library that has been amalgamated with USBHost_t36 but forgive me if I am incorrect.

1. Of course you are correct in that the device should not be removed but I am catering for all worst case scenario as the product is supposed to be very robust and we don't want to ask our customers to power cycle the end product.

2. The code above was a 'pseudo extract' from the original (much larger) source and in reality the startAddr variable would have associated values in the real code. I pruned the code above just to represent the read/write blocks scenario as including the whole source would not given anymore than the response you have given - so many thanks.

3. I am a newbie so thank you for pointing out the </> tip!

I will pursue a thread and interrupt to continually test to see if the device is there and hopefully implement a software reset to prevent lockup. I will post the result here.

Best regards
Richard
 
The USBHost_T36 code has quite a few race conditions, particularly when it comes to handling failed transactions. These have the potential to trigger a crash or infinite loop.

This was one of the reasons I wrote my own USB Host library. However if you want to use it, be aware that a) it is GPL licensed and b) there's not really any documentation besides the examples, and you need decent knowledge of USB and multithread programming to successfully use it.
 
It's supposed to reboot. Details from ARM's documentation:

1737079364176.png
 
I use this method in FlasherX to do a reset after writing new firmware, and as far as I know it has always had the intended effect, with the 1062 rebooting and running the new firmware.
 
ok Paul and Joe many thanks for the replies. So for example if I put it in void doReset() {SCB_AIRCR = 0x05FA0004;} and call that on a certain condition (e.g. an input pin goes high) from within void loop() then it should reboot, go through void setup() and start void loop() again.
I should not have to init all my code variables in doReset() as it will clear them anyway on the reboot?
It almost as if you are pulling the power on the board and it restarts the sketch.
 
Back
Top