I'm having to reflash the firmware (and python software) of my Trinket M0s almost every time they lose power or I press the reset button. I'm aware of the need to safely eject, and may have some udev rules configuration (or other Linux bug) which is causing the device to immediately remount after I eject it. I'm using something which is approximately Circuitpython 3.0.0 Alpha 6.
Is there any reason for this besides the eject issue? I'm wondering if there is maybe some file getting left open by Circuitpython firmware that would cause this kind of flash corruption when the device loses power.
Memory corrupted every power cycle or reset
Moderators: adafruit_support_bill, adafruit
Please be positive and constructive with your questions and comments.
- danhalbert
- Posts: 4655
- Joined: Tue Aug 08, 2017 12:37 pm
Re: Memory corrupted every power cycle or reset
What are the symptoms that lead to believe you have corruption that necessitates a reload?
Which distribution and version of Linux are you using?
What's in your /etc/udev/rules.d directory?
What editor are you using to edit the files on the Trinket M0?
Linux delays writes to the CIRCUITPY filesystem for a few 10's of seconds. To force a write, just do `sync` at a shell prompt. You don't need to eject. If you're using an editor that does an `fsync()` after write, this isn't necessary, but if you use `cp` or a file explorer window to copy files, then do a `sync`.
In recent versions of both 2.x and 3.0, you can do
to erase and reformat CIRCUITPY.
Which distribution and version of Linux are you using?
What's in your /etc/udev/rules.d directory?
What editor are you using to edit the files on the Trinket M0?
Linux delays writes to the CIRCUITPY filesystem for a few 10's of seconds. To force a write, just do `sync` at a shell prompt. You don't need to eject. If you're using an editor that does an `fsync()` after write, this isn't necessary, but if you use `cp` or a file explorer window to copy files, then do a `sync`.
In recent versions of both 2.x and 3.0, you can do
Code: Select all
>>> import storage
>>> storage.erase_filesystem()
- ps18
- Posts: 18
- Joined: Sat Oct 05, 2013 5:10 am
Re: Memory corrupted every power cycle or reset
Hi Dan,
The symptoms are the following (for example, after unplugging the USB cable and re-plugging it):
- My application doesn't boot up when I power it up again. The Trinket M0 is the main thing with nonvolatile memory (everything else should be stateless after a power cycle).
- CIRCUITPY doesn't remount when I plug the USB cable back in.
- When I eject the device from the files browser, it never really disappears from the navigation menu, and I can still click on the CIRCUITPY drive and view the files
- Using a custom version of Debian
- I have various udev rules; the relevant ones are the original TrinketM0 VID/PID, a customized one, and also a [perhaps overly permissive] one:
SUBSYSTEM=="usb", ATTRS{idVendor}=="239a", ATTRS{idProduct}=="801f", MODE="0664", GROUP="plugdev"
SUBSYSTEM=="usb", ATTRS{idVendor}=="<our VID>", ATTRS{idProduct}=="<our PID>", MODE="0664", GROUP="plugdev"
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTR{idVendor}=="*", ATTR{idProduct}=="*", MODE="0666"
I suspect this could be related the issue, but not sure why. Maybe I should revert to the original wildcard version and skip the whole customized VID/PID thing.
- I'm not editing the files directly on the drive. I'm copying them using a python-based builder, which ultimately uses shutil.copyfile() to copy the built files on the device then calls umount /media/<user>/CIRCUITPY. This works fine during the current session (ie, before I unplug the USB cable), but after I unplug it, it typically won't boot again.
- I have not tried 'sync'. Thanks for the tip; I'll try that out.
- If you use storage.erase_filesystem() it reverts to a factory image? Or it reverts to the image most recently flashed to TRINKETBOOT?
The symptoms are the following (for example, after unplugging the USB cable and re-plugging it):
- My application doesn't boot up when I power it up again. The Trinket M0 is the main thing with nonvolatile memory (everything else should be stateless after a power cycle).
- CIRCUITPY doesn't remount when I plug the USB cable back in.
- When I eject the device from the files browser, it never really disappears from the navigation menu, and I can still click on the CIRCUITPY drive and view the files
- Using a custom version of Debian
- I have various udev rules; the relevant ones are the original TrinketM0 VID/PID, a customized one, and also a [perhaps overly permissive] one:
SUBSYSTEM=="usb", ATTRS{idVendor}=="239a", ATTRS{idProduct}=="801f", MODE="0664", GROUP="plugdev"
SUBSYSTEM=="usb", ATTRS{idVendor}=="<our VID>", ATTRS{idProduct}=="<our PID>", MODE="0664", GROUP="plugdev"
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTR{idVendor}=="*", ATTR{idProduct}=="*", MODE="0666"
I suspect this could be related the issue, but not sure why. Maybe I should revert to the original wildcard version and skip the whole customized VID/PID thing.
- I'm not editing the files directly on the drive. I'm copying them using a python-based builder, which ultimately uses shutil.copyfile() to copy the built files on the device then calls umount /media/<user>/CIRCUITPY. This works fine during the current session (ie, before I unplug the USB cable), but after I unplug it, it typically won't boot again.
- I have not tried 'sync'. Thanks for the tip; I'll try that out.
- If you use storage.erase_filesystem() it reverts to a factory image? Or it reverts to the image most recently flashed to TRINKETBOOT?
- ps18
- Posts: 18
- Joined: Sat Oct 05, 2013 5:10 am
Re: Memory corrupted every power cycle or reset
Seems there were other related issues like this in 2.3.x ("Power-on CIRCUITPY corruption fix"). Maybe related? Is there an easy way to disable any unnecessary file I/O like writing *.txt at startup?
- ps18
- Posts: 18
- Joined: Sat Oct 05, 2013 5:10 am
Re: Memory corrupted every power cycle or reset
Actually, I'm looking at circuitpython/main.c and now suspecting I have a power glitch occurring at an unlucky time during those file I/O operations, when the board is plugged in. I have a lot of capacitance on this particular version, so inrush current could be large and it could be drooping the supply when power is applied.
- ps18
- Posts: 18
- Joined: Sat Oct 05, 2013 5:10 am
Re: Memory corrupted every power cycle or reset
Ok, I resolved my issue by adding this in mpconfigport.h (just undefining it after it is defined to "/boot_out.txt").
#undef CIRCUITPY_BOOT_OUTPUT_FILE
I can now unplug/replug reliably without corrupting the file system (tested successfully 5 times in a row; previously I was getting about 0-5% success rate). I realize you need to have those status files in there to help debug customer issues, but it seems a bit risky to be modifying the filesystem permissions right at startup.
#undef CIRCUITPY_BOOT_OUTPUT_FILE
I can now unplug/replug reliably without corrupting the file system (tested successfully 5 times in a row; previously I was getting about 0-5% success rate). I realize you need to have those status files in there to help debug customer issues, but it seems a bit risky to be modifying the filesystem permissions right at startup.
- danhalbert
- Posts: 4655
- Joined: Tue Aug 08, 2017 12:37 pm
Re: Memory corrupted every power cycle or reset
Several comments:
1. boot_out.txt is now rewritten only when it will change (either a change in version info or the presence of a boot.py). This is in 2.3.x and was added after 3.0.0-alpha.6, so it would be good for you to update your build. When it does need to change we wait 1.5 seconds before writing it to ensure the power is stable.
2. I don't see why you need those udev entries. As long as you are in the plugdev and dialout groups you should be fine, and that's just needed for REPL access.
3. Definitely do a sync after you do a copyfile() to the drive
4. storage.erase_filesystem() erases and reformats the CIRCUITPY filesystem, and then writes a few files and dirs to prevent MacOS from writing indexing files on the drive. It doesn't do anything to the firmware.
5. Ejecting is really the advice for Windows. Use `sync` instead.
1. boot_out.txt is now rewritten only when it will change (either a change in version info or the presence of a boot.py). This is in 2.3.x and was added after 3.0.0-alpha.6, so it would be good for you to update your build. When it does need to change we wait 1.5 seconds before writing it to ensure the power is stable.
2. I don't see why you need those udev entries. As long as you are in the plugdev and dialout groups you should be fine, and that's just needed for REPL access.
3. Definitely do a sync after you do a copyfile() to the drive
4. storage.erase_filesystem() erases and reformats the CIRCUITPY filesystem, and then writes a few files and dirs to prevent MacOS from writing indexing files on the drive. It doesn't do anything to the firmware.
5. Ejecting is really the advice for Windows. Use `sync` instead.
- ps18
- Posts: 18
- Joined: Sat Oct 05, 2013 5:10 am
Re: Memory corrupted every power cycle or reset
Ok, thanks a lot for the quick response!
Please be positive and constructive with your questions and comments.