adafruit / uf2-samdx1

MSC bootloader (based on UF2) for SAMD21
Other
214 stars 187 forks source link

Issues when implementing ATSAMD21E17D #141

Closed HpLightcorner closed 3 years ago

HpLightcorner commented 4 years ago

Hey,

Board A custom Board using ATSAMD21E17D.

Issue Copying to drive works perfectly, but BOSSA cannot flash device - aborting after flash is erased and while trying to execute write-buffer function. As far as I understood write-buffer puts code into SRAM and then into Flash? My bossac line: bossac -p COMxx --offset=0x2000 -e -i -d -v -w .\test.bin -R -U

What I have found out so far Bossac is able to detect the device, but when I try to flash my firmware, bossac hangs in the flash process terminating it after a few seconds. I deep-dived into bossac and found out that the issue seems to come from Write-Buffer Function (Extended Function Y) on the bootloader-side. When I override the capabilities and deactivate write-buffer functionality (change to [Arduino:XZ]) - everything seems to be perfect.

I am stuck on this a little bit - has there been any major update on the sam-ba bootloader or has BOSSA made some major changes? Are there further changes needed with the latest revision of Silicon (E17D?) Or have I simply overseen something else?

Would be nice if someone has experienced the same issues as I did. I now deactivated the Buffering form BOSSA to Bootloader which currently works.

HpLightcorner commented 4 years ago

Okay, I was able to get write-buffer working by decreasing the hard-coded buffer size in BOSSA (from 4096 to 1024) per buffered write to flash. So, BOSSA will send packages of 1024 bytes - seems that when sending with 4096 bytes boundaries of the memory are violated?

HpLightcorner commented 4 years ago

So, finally I was able to solve the problem. I have seen some Pull requests to both, uf2 and BOSSA which are both trying to add ATSAMD17, but I have not seen any changes to address the issue. Hence, I will try to explain my findings, hopefully someone can double check them.

First, let me start with a summary: BOSSA sends packages of data to the RAM and then executes a transfer from this buffered data to the FLASH. To do so, BOSSA has hard-coded start addresses for the RAM (in device.cpp). BOSSA sends packages up to 4096 bytes (also hard-coded). The SAMD21E17 has 16kB of RAM, so no problem here.

However, in the default linker script, the STACK Size is defined as 0x2000 Bytes, having a look into the map file:

 *fill*         0x20000318     0x2000 
                0x20002318                . = ALIGN (0x8)
                0x20002318                _estack = .
                0x20002318                . = ALIGN (0x4)
                0x20002318                _end = .

So, the BOSSA start address for buffering in RAM should be greather than 0x20002318 to avoid any issues here. Let's check the hard-coded BOSSA info:

        case 0x10010001: // J17A
        case 0x10010006: // G17A
        case 0x1001000b: // E17A
        case 0x10010094: // E17D
        case 0x10010095: // E17D WLCSP
        case 0x10010097: // E17L
        case 0x10010010: // G17A WLCSP
        case 0x10010093: // G17D
        case 0x10010096: // G17L
        case 0x10010092: // J17D
            _family = FAMILY_SAMD21;
            flashPtr = new D2xNvmFlash(_samba, "ATSAMD21x17", 2048, 64, 0x20002000, 0x20004000) ;
            break;

And here we have 0x20002000 as the starting address for the RAM buffers - which will definitly corrupt the Stack in some way if I have understood everything right. Why does this then work with devices having 32 kB?

        case 0x10010000: // J18A
        case 0x10010005: // G18A
        case 0x1001000a: // E18A
        case 0x1001000f: // G18A WLCSP
            _family = FAMILY_SAMD21;
            flashPtr = new D2xNvmFlash(_samba, "ATSAMD21x18", 4096, 64, 0x20004000, 0x20008000) ;
            break;

The Starting address is definitly beyond the STACK with 0x20004000.

My solution to this issue is either:

I would appreciate any further tips or comments, this was quite hard to find out. By decreasing stack the ATSAMD21E17 is fully compatible with the bootloader as far as I can tell (UF2 and SAM-BA/BOSSA).

HpLightcorner commented 4 years ago

I have seen that #132 is addressing similar issues.

Is UF2 taking limited ressources into account? As Setting FLASH_NUM_ROWS seems to work with UF2... It think it would be a good idea to improve BOSSA at this point by dynamically deciding how big the buffer should instead of hard-coding 4096 bytes? Or even deactivating Buffered-Writes in the bootloader settings for devices with less than 32 kB?

This would at least ensure that the 16 kB Versions are working with BOSSA and UF2, #132 is even using the 8kB Version which indeed seems to be very constrained...

Would by kind to know what the "Adafruit" way would be to overcome the limitations.

dhalbert commented 4 years ago

BOSSA and bossac have not had a release by the original maintainer in some time, despite some serious issues that could use fixing, most noticeably the new default --offset=0x0000 problem, which can easily cause bricked boards . Both arduino and adafruit have forks, but we have not been supplying alternate versions yet.

UF2 was designed with specific specific chips in mind, and we (and Microsoft) didn't consider trying to make it run on the lower-end chips. We would accept PR's for compile-time options for low-end chips, but we would not want to slow down loading on all chips to accommodate the low-end ones.

HpLightcorner commented 4 years ago

I understand your points and totally agree with you, slowing down the process is not an option. What do you think would be the way to prefer: Making a PR on Adafruits' BOSSA so the STACK can be left unchanged at 8kB or adjusting and testing the STACK Size of the Bootloader implementing a build-process for low-end chips? (at least 128 kB Flash, 16 kB ram)

dhalbert commented 4 years ago

Since we don't advertise that we have our own BOSSA, I'm not sure that's the most effective way. And this is for your boards, not ours, so I think it makes more sense for you to have your own fork of BOSSA/bossac that you ask your users to use. Or you can PR uf2-samdx1 to adjust the stack size for the smaller chips.

dhalbert commented 3 years ago

I am going to close this for now, but feel free to ask for it to be re-opened if someone figures out how to make it work on low-RAM processors.