-
-
Notifications
You must be signed in to change notification settings - Fork 405
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Unable to flash SAM chip with bootloader #507
Comments
Ohhh I think I know what's the issue! Could you try and pass |
|
I cloned probe-rs and cargo-embed, and edited the New error message:
|
I was reviewing @henrikssn 's updates via #542, and testing them against
I took a look, and I think this may be caused by invalid probe-rs/probe-rs/targets/SAMD21.yaml Lines 589 to 610 in 08d9fa2
|
so, strangely enough, even though I'm fairly sure my chip is a I am currently testing on a seeeduino xiao, which the manufacturer states is a "ARM Cortex-M0+ CPU(SAMD21G18)" (seeeduino xiao specs. The actual chip on the xiao board is shielded, so I cant verify the chip without destroying the board, but I have some new boards coming in a few days that supposedly also have the atsamd21g18au (and not shielded), and I'll re-run some of these tests with those boards as well to see what results I can replicate. If things go strangely at that point, I'll rip the shielding off one of these seeeduino's to verify the chip. |
btw, my mistake earlier, the flash aglo is 2556 not 128, at least according to the CMSIS pack. (this matches what is currently in the targets spec of probe-rs for the chip.) |
I'm running into the same issue while trying to flash an ATSAMD21G18AU (Adafruit Feather M0 Express); probe-run tries to erase flash at address 0x0000, even though
This is trying to flash the unmodified blinky_basic example from here |
Was also playing with Feather-M0 just now and passing |
So to clarify: You intentinally passed the wrong chip to make it work? Could you specify what Chip you have? We should diff the config files against eachother and see what the differences are :) |
@Yatekii this is only happening when the board uses the I did some digging a little over a year ago, and determined that it came down to the flash region size being incorrect for the CMSIS pack for the 21G18au. I compared the flash algo's for that chip and the 21e17a, and the only differences were the flash region size. The region size for the 21e17a seems to be right size for 21d18au, so that why I flashed it using the "wrong chip" so long ago. Since then I've seen a few dozen people with the same problem for these 2 chips, and this fix always works for them. I think there's another issue thread in one of the probe-rs repos where I had an even more detailed description and analysis, but can't remember where that is. |
Hmm then we should fix the target description file :/ Or see if there is an updated CMSIS-Pack :/ |
If I get a chance, I'll look into whether or not the CMSIS-Pack has been updated this weekend. If not, I can submit a PR to update the target description file for the g18au. |
I went ahead and ran target-gen on the current SAMD21 dev pack - here- it looks like the tool now generates decimal rather than hex values, so the diff isn't particularly enlightening, but the spot checking I did doesn't indicate any changes including to the ATSAMD21G18AU flash algorithm. The ATSAMD HAL has made a PR or two to the dev packs before, but I'm not actually sure what exactly the error is. Per the SAMD21 datasheet 22.6.3 "Region Lock Bits", the region size is determined by the total flash size - ATSAMD21G18AU has 256kB flash so should have 16kB region size, ATSAMD21E17A is 128kB/8kB. Those look to be the same as the "sector" values in the generated yaml. I do notice the page size for all these parts is 64B per the datasheet table 10-3, and the flash algos differ between these two parts: ATSAMD21G18AU uses flash algo atsamd21_256 and that uses 64B page size, The ATSAMD21E17A uses algo atsamd21_128, 1024B page size. However, I don't understand how that would relate to the bootloader specifically... |
yeah, i was stumped as well. what's more interesting, when I flash this chip with platformio, which uses the same derived algos from the cmsis packs, it works fine. |
After some time away from SAMD and Rust firmware, this has tripped me up again so I've dug in to the cause: probe-rs has a concept of flash "sectors", and before programming it erases any sectors that will later be programmed. The sector boundaries are calculated based on the flash algorithm, in this case from SAMD21.yaml which is generated from the Microchip dev pack. ATSAMD21G18AU sectors start at 0x0 with size 0x4000 (16kB), while ATSAMD21E17A sectors start at 0x0 and have size 0x2000 (8kB). When probe-rs attempts to program a SAMD21G18AU that has an 8kB bootloader (as is typical for Adafruit boards, at least), it decides to erase the sector that goes from 0x0 to 0x4000-1 because the program starts halfway through that sector. But, the chip has the bootloader protection enabled for the lower 8kB (this setting can be queried). The naive fix of turning down the sector size in SAMD21.yaml fails, I presume because the loader can't handle the finer grained sector addresses. @Yatekii do you have any thoughts on the best approach to resolve this? |
The erase always happens per sector. The only way is to erase the bootloader and write it again (there is a flag for it). Maybe the chip has a weird finer grained sector set that can be enabled with some commands; in that case we can fix it with a new flashloader. But thats a rather rare thing afaik. Bootloaders are typically the size of N sectors for this reason. Are you sure the program is linked correctly and the program should not actually be placed at the sector boundary? |
From a look at the datasheet tonight, I believe the SAMD21 flash can be erased in units called "rows" which are 256 bytes, each row is four 64 byte "pages". SAMD21 has two flash protection schemes which relate to this issue, one via BOOTPROT and another via "Region Lock Bits": BOOTPROT is meant to protect a bootloader at the beginning of flash, it's a 3-bit value which maps on to the same set of sizes for all flash size parts, either 0B, 512B, 1024B, 2048B, ... 32768B. The Region Lock Bits provide a more general-purpose protection scheme, which divides the flash in to 16 equally-sized regions and allows disabling writes per-region. I believe these regions are what we're treating as "sectors", but they are substantially larger (16kB, in the chip discussed here) than the 256B rows that the flash can be erased in. |
What if you try to make the sector size 256 bytes? I mean best would be if there was a dynamic sector erase size in our flashing code, but for now we can do it with a smaller sector maybe. It will take much longer to erase like this tho. |
Changing the sector size to 0x10 in SAMD21.yaml fails (that's what I did in this comment). My guess is that the loader program doesn't handle finer grained erases, but that is just a guess - is that program provided by the pack? I also tried setting the sector size to 0x800, which is the same used for ATSAMD21E15A - that fails similarly to 0x10, but setting the device to ATSAMD21E15A succeeds.
Understood; I'm happy to look at concatenating adjacent sectors if that would help. |
I've decompiled the It seems like there are a couple options to proceed: A) Take the bootloader protection in to account in probe-rs, which would look something like
B) Create a new erase function, that can work per-row. If we went this route, I presume that target-gen would need to have some exception for SAMD21 parts - is there prior art for this sort of exception? Ideally, the new erase function would take both start address and size parameters, so we don't need to make separate transactions for each row erase - but that might require more extensive changes to probe-rs. |
After a bit more thought about this - there's an option in-between those two: C) Modify the flash algorithm to backup, disable, and re-enable the bootloader protection. I tend to think that A) is the best option, because it would give the user more visibility and control over the state of the chip. Automatically turning off a protection feature seems a bit surprising too. |
I replicated this using platformio and a J-Link - from the logs it appears that pio uses Segger's software to drive the flashing process, and it doesn't seem to suffer the same problem as here. With the chip's bootloader protection set to 8kB, the Segger tool flashes the application, and if I set the bootloader protection to 16kB, it fails with an error @LongLiveCHIEF - what probe are you using? |
I believe I tried with a a rust probe, and an st-link V3... and I recall
doing the same tests with a jlink and pio that you did. I think I even
documented some of it in another related issue here somewhere.
…On Thu, Oct 26, 2023, 3:38 AM Ian ***@***.***> wrote:
what's more interesting, when I flash this chip with platformio, which
uses the same derived algos from the cmsis packs, it works fine.
I replicated this using platformio and a J-Link - from the logs it appears
that pio uses Segger's software to drive the flashing process, and it
doesn't seem to suffer the same problem as here. With the chip's bootloader
protection set to 8kB, the Segger tool flashes the application, and if I
set the bootloader protection to 16kB, it fails with an error ((sector is
locked)). So, it's not fiddling with the bootloader protection, and I
guess it isn't using the loader from Microchip's dev_packs.
@LongLiveCHIEF <https://github.com/LongLiveCHIEF> - what probe are you
using?
—
Reply to this email directly, view it on GitHub
<#507 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAZBLALEK2OMQIIBYVC2KRDYBIOP7AVCNFSM4VGZQU32U5DIOJSWCZC7NNSXTN2JONZXKZKDN5WW2ZLOOQ5TCNZYGA3DMNJVGAZQ>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
@ianrrees Did we want to still come up with a fix for this or do we require a chip erase? Maybe we can at least fix the diagnostics on this so it tells us what's wrong. |
Yes, I think this is still a significant issue. With #1855, probe-rs now does have a chip erase for ATSAM, however that doesn't really help here since the chip erase functionality leaves the "user row" intact, and that includes the bootloader protection setting... With a wider view, I think we need a generic reading/writing functionality for field like the BOOTPROT, where there's more to it than simply reading/writing a register, and there are also good reasons for developers to want to access just that specific field. For another instance, in a recent project with i.MX8 (not-Rust and proprietary), I've encountered similar need for programming crypto keys. I totally agree that better diagnostics messages would be great - in this case it would be difficult to make the diagnostic very helpful without the ability to read the BOOTPROT setting. The logs in the attached bugs do start with the same failure to erase sector 0x0000, however in other combinations of flash size and BOOTPROT setting, those erasing errors will manifest at different addresses. |
@Yatekii - apologies for digging this up after so long away! I've got some time for OSS again, and am curious whether there have been developments on this? |
Describe the bug
When trying to flash a Feather M0 (SAMD21G18AU) with 8K bootloader, the command fails (see log output below).
To Reproduce
Steps to reproduce the behavior:
cargo generate --git https://github.com/rust-embedded/cortex-m-quickstart
memory.x
to make space for bootloader:.cargo/config
:cargo flash --chip atsamd21g18au
Expected behavior
The program is flashed to the MCU.
Stacktrace
Desktop (please complete the following information):
Additional context
0x2000
works fine, so doesbossac
.probe-rs
instead of the bootloader due to the RTT integration, but would like to keep the option of later flashing with bootloader.The text was updated successfully, but these errors were encountered: