Author Topic: Flash an MCU from another MCU (over SWD)  (Read 4061 times)

0 Members and 1 Guest are viewing this topic.

Offline peter-h

  • Super Contributor
  • ***
  • Posts: 3494
  • Country: gb
  • Doing electronics since the 1960s...
Re: Flash an MCU from another MCU (over SWD)
« Reply #25 on: December 20, 2022, 09:49:52 am »
FWIW, somebody pointed out to me that the only way to do a remotely upgradeable system (OTA) which is 100% brick-proof is to have a second CPU which is SWD capable and can write the FLASH of the primary CPU.
Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 

Online Siwastaja

  • Super Contributor
  • ***
  • Posts: 7676
  • Country: fi
Re: Flash an MCU from another MCU (over SWD)
« Reply #26 on: December 20, 2022, 10:06:39 am »
FWIW, somebody pointed out to me that the only way to do a remotely upgradeable system (OTA) which is 100% brick-proof is to have a second CPU which is SWD capable and can write the FLASH of the primary CPU.

Nothing is 100% brick-proof. You can still make a bug which sets undesired pins as outputs short-circuiting them, possibly causing damage.

With the usual multi-page/sector flash, it's fairly trivial to verify your code in such way you never accidentally clear the working firmware. 99.9% of upgradeable devices in existence work like this, and 99.9% of them never get bricked.

I consider such massive added extra complication (of secondary CPU) orders of magnitude more risky.
 

Offline peter-h

  • Super Contributor
  • ***
  • Posts: 3494
  • Country: gb
  • Doing electronics since the 1960s...
Re: Flash an MCU from another MCU (over SWD)
« Reply #27 on: December 20, 2022, 05:08:38 pm »
Sure; I've never done this, and on my current system the OTA bricking window is just 300ms out of a total programming time of ~10 secs, but I know somebody whose customer demanded this architecture.

Otherwise, it would be fairly unusual to want to build your own SWD debugger :) Still, it does amaze me how many people reverse engineer these dirt-cheap dongles... Maybe they are looking for something more reliable? None of the STLINK units (I've used them all, I think) are all that reliable, and they lose contact with the target easily. And their interface to Cube is crap.
Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 

Offline wek

  • Frequent Contributor
  • **
  • Posts: 462
  • Country: sk
Re: Flash an MCU from another MCU (over SWD)
« Reply #28 on: December 20, 2022, 05:35:20 pm »
Reminded me of the original AVRPROG, where an AT90S1200 served as the bootloader to an AT90S8535... In my specimen, the latter failed in an overvoltage event, replaced with an ATMega8535 and it works to this day in production of some rather old products...

JW
 

Online Siwastaja

  • Super Contributor
  • ***
  • Posts: 7676
  • Country: fi
Re: Flash an MCU from another MCU (over SWD)
« Reply #29 on: December 20, 2022, 06:19:25 pm »
Sure; I've never done this, and on my current system the OTA bricking window is just 300ms out of a total programming time of ~10 secs, but I know somebody whose customer demanded this architecture.

You really don't have multi-page flash available, or you just messed things up for no reason? I mean, normally a "time window" like this does not exist.

I mean, I have done that "window of death" thing too, but it was a conscious decision to use a single flash page budget MCU (designed to be used with external flash, but in my project, used without).
 

Offline Nominal Animal

  • Super Contributor
  • ***
  • Posts: 5792
  • Country: fi
    • My home page and email address
Re: Flash an MCU from another MCU (over SWD)
« Reply #30 on: December 20, 2022, 06:38:45 pm »
FWIW, somebody pointed out to me that the only way to do a remotely upgradeable system (OTA) which is 100% brick-proof is to have a second CPU which is SWD capable and can write the FLASH of the primary CPU.
Nothing is 100% brick-proof. You can still make a bug which sets undesired pins as outputs short-circuiting them, possibly causing damage.
Also, as observed with Teensy MicroMods (manufactured by Sparkfun), the processor-processor connection itself is a possible failure point.
(It looks like the MicroMods' PCB is a bit too flexible, causing connection issues with the i.MX RT1062 BGA IC.)

I don't have an opinion on what is the most robust approach here, but I like the fact that in the Teensy case, the secondary MKL02 processor has direct access to a LED it can use for flashing a specific pattern indicating type of communication error with the main chip: when a problem does appear, it doesn't just become a silent brick, and you get at least a detectable pattern of LED flashes to investigate the problem.  (There is also a very-long-button-press option, that reflashes the RT1062 with the default Blinky program without any host computer involvement.)
« Last Edit: December 20, 2022, 06:40:21 pm by Nominal Animal »
 

Offline peter-h

  • Super Contributor
  • ***
  • Posts: 3494
  • Country: gb
  • Doing electronics since the 1960s...
Re: Flash an MCU from another MCU (over SWD)
« Reply #31 on: December 20, 2022, 10:12:20 pm »
Quote
You really don't have multi-page flash available, or you just messed things up for no reason? I mean, normally a "time window" like this does not exist.

Normally I do like to make a mess for no reason :)

Your scheme seems to imply that one has two copies of the loader, in different flash blocks, and switches from one to the other. I didn't bother; I just loaded the loader into RAM and it does everything from there. Nice and simple. I posted various threads on RAM based loaders a year or two ago...
Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 

Online Siwastaja

  • Super Contributor
  • ***
  • Posts: 7676
  • Country: fi
Re: Flash an MCU from another MCU (over SWD)
« Reply #32 on: December 21, 2022, 08:22:52 am »
Your scheme seems to imply that one has two copies of the loader, in different flash blocks, and switches from one to the other. I didn't bother; I just loaded the loader into RAM and it does everything from there. Nice and simple. I posted various threads on RAM based loaders a year or two ago...

Remember the "do not turn power off or your motherboard bricks!!" BIOS updates from early 2000's? Those you applied by booting into DOS, then running the updater tool, fearing you will destroy your computer.

The rest of the world went on, for the last 15 or so years every firmware update has been brick-proof. Yes, two copies of the application is all you need. Erase and write one; after verification, mark that one bootable. If that fails, the other app is not touched. Flash is cheap. When was the last time you used more than 50% of the flash for the firmware itself? For me, it was over a decade ago, in a small cost-optimized application on ATTiny25, which used 80-90% of the flash (2K). After that, every project has been way below 50%, so could easily afford split into two apps. All you need is multi-page flash controller, which is also available in almost every MCU, weird budget models like STM32H750 aside.

And yes, you are not the only lazy one. I have went with super simple "flasher" code as well in a few projects in past. Just place the functions in RAM, erase and write. Very simple, but comes with window of death. I have minimized this risk by receiving the full firmware in RAM, so there is no communication to fail during flashing. But flash erase is still slow, someone can cut power during that. So we should really stop doing lazy bullshit solutions like this.

I remember seeing you having significant trouble with bootloaders. It's true this is more work, of course, but still ain't rocket science. My current project still uses the app itself to write the flash, but it writes the other app. Bootloader checks which one has higher counter and valid CRC, and boots that. Still very simple.
« Last Edit: December 21, 2022, 08:24:29 am by Siwastaja »
 
The following users thanked this post: Nominal Animal, tellurium

Offline peter-h

  • Super Contributor
  • ***
  • Posts: 3494
  • Country: gb
  • Doing electronics since the 1960s...
Re: Flash an MCU from another MCU (over SWD)
« Reply #33 on: December 21, 2022, 11:52:32 am »
Quote
When was the last time you used more than 50% of the flash for the firmware itself?

This morning.

Quote
I remember seeing you having significant trouble with bootloaders

That was because I was learning.
Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 

Offline eutectique

  • Frequent Contributor
  • **
  • Posts: 297
  • Country: be
Re: Flash an MCU from another MCU (over SWD)
« Reply #34 on: December 21, 2022, 01:12:01 pm »
My current project still uses the app itself to write the flash, but it writes the other app. Bootloader checks which one has higher counter and valid CRC, and boots that.

Is your app position-independent? Or do you build two versions of the app for different VMAs?
 

Offline peter-h

  • Super Contributor
  • ***
  • Posts: 3494
  • Country: gb
  • Doing electronics since the 1960s...
Re: Flash an MCU from another MCU (over SWD)
« Reply #35 on: December 21, 2022, 02:45:11 pm »
Oh yes that old one :) I did various threads on that. IIRC, nobody had any experience of relocatable code, even though in theory the compiler has a command line option for it.

In the case of my loader I compiled it to run at the top 4k of RAM where it gets copied to and then the boot block jumps to it (using some asm code, one of the available hacks to prevent the compiler removing "unreachable" code - that was a whole other bit of fun). The loader itself is 2-3k and that is all that's needed to read data out of some device and program the CPU with it, a block at a time. I do various tests e.g. erase, program 0xaa 0x55 0xff and test the uppermost flash block (which is 128k on the 32f417). The whole device RAM is freely available for whatever purpose. And if that 128k block fails, there is obviously little point in bothering with anything else, but you won't have trashed the existing code (unless it extended into the top 128k). Then I program from top down, and the "boot block" (which is 32k) I program last.

If I was developing an SWD loader/debugger I would do the same thing, but I would pre-read each flash address (it is programmed in 32 bit words) and program it only if different. I have put in a pre-read into other parts of my code and it dramatically speeds up programming in any typical development scenario, because most of the time one is doing only small changes and often there is no "position shift" in the code (if e.g. you change int fred=0 to int fred=1, only 1 word changes). I actually don't think ST implemented that in their Cube - SWD - STLINK code.
Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 

Online mikeselectricstuff

  • Super Contributor
  • ***
  • Posts: 13539
  • Country: gb
    • Mike's Electric Stuff
Re: Flash an MCU from another MCU (over SWD)
« Reply #36 on: December 21, 2022, 03:32:15 pm »
Quote
When was the last time you used more than 50% of the flash for the firmware itself?

This morning.

Quote
I remember seeing you having significant trouble with bootloaders

That was because I was learning.
External SPI flash is extremely cheap nowadays - that can provide an easy way to download & verify firmware bfore programming. This can be made brick-proof ( and secure if needed)  with sufficient though & effort.
Youtube channel:Taking wierd stuff apart. Very apart.
Mike's Electric Stuff: High voltage, vintage electronics etc.
Day Job: Mostly LEDs
 

Offline peter-h

  • Super Contributor
  • ***
  • Posts: 3494
  • Country: gb
  • Doing electronics since the 1960s...
Re: Flash an MCU from another MCU (over SWD)
« Reply #37 on: December 21, 2022, 04:57:04 pm »
Indeed, but you are paying money for that privilege. Especially if you have no need for that extra chip.

Yet another chip to get shafted on when times are tight, too.
Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 

Online mikeselectricstuff

  • Super Contributor
  • ***
  • Posts: 13539
  • Country: gb
    • Mike's Electric Stuff
Re: Flash an MCU from another MCU (over SWD)
« Reply #38 on: December 21, 2022, 05:06:49 pm »
Indeed, but you are paying money for that privilege. Especially if you have no need for that extra chip.

Yet another chip to get shafted on when times are tight, too.
It's probably cheaper than doubling the size of your onboard flash ( if you even can) for a second image, and there are many manufacturers with pin-compatoble parts
Youtube channel:Taking wierd stuff apart. Very apart.
Mike's Electric Stuff: High voltage, vintage electronics etc.
Day Job: Mostly LEDs
 

Online Siwastaja

  • Super Contributor
  • ***
  • Posts: 7676
  • Country: fi
Re: Flash an MCU from another MCU (over SWD)
« Reply #39 on: December 21, 2022, 07:54:34 pm »
My current project still uses the app itself to write the flash, but it writes the other app. Bootloader checks which one has higher counter and valid CRC, and boots that.

Is your app position-independent? Or do you build two versions of the app for different VMAs?

Link two different versions, all I need is two different linker scripts. Compilation (before linking stage) is the same. Two binaries are produced, of course, so one could consider this a small minus. Doesn't matter to me. One could combine them in one file if that matters.

There is a flag in status data stream which tells the updater tool(s) which binary to send (a single bit that indicates "I'm running app_a, please send app_b" or vice versa). The flasher code does one final safety check by looking at the second DWORD in the supplied binary, namely reset vector address, that it indeed is in the address space of the correct binary, before going on with the update. (One could also always send the combined blob to the firmware and it would choose whichever to write. I guess this is the most usual solution.)

There also is a CRC added in the binary.
« Last Edit: December 21, 2022, 08:03:28 pm by Siwastaja »
 
The following users thanked this post: eutectique

Offline ataradov

  • Super Contributor
  • ***
  • Posts: 10913
  • Country: us
    • Personal site
Re: Flash an MCU from another MCU (over SWD)
« Reply #40 on: December 21, 2022, 08:01:55 pm »
Yes, this two images linked at different addresses is the most universal way. Position independent code is next to impossible to achieve. And you really don't need it.
Alex
 

Online Siwastaja

  • Super Contributor
  • ***
  • Posts: 7676
  • Country: fi
Re: Flash an MCU from another MCU (over SWD)
« Reply #41 on: December 21, 2022, 08:02:31 pm »
External SPI flash is extremely cheap nowadays - that can provide an easy way to download & verify firmware bfore programming. This can be made brick-proof ( and secure if needed)  with sufficient though & effort.

I don't like external SPI flash. Even if "cheap", it's still a BOM item, and completely unnecessary if the target MCU is available with multiple flash pages (and enough flash). This is usually the case.

Of course, sometimes it just happens the otherwise good MCU candidate does not have enough flash or multiple pages, and the next better model in the family is way more expensive (or different otherwise) so external flash chip ends up cheaper or better. But it's not that often.

Some people offer external flash solution even when internal multipage flash is available and flash consumption is way below 50%. I don't get this at all, there is absolutely no point. Using external versus internal is always more complicated and more prone to error, IMHO. One has to understand how the MCU flash is used anyway to program it, there's no way around it.
 

Online SiliconWizard

  • Super Contributor
  • ***
  • Posts: 13495
  • Country: fr
Re: Flash an MCU from another MCU (over SWD)
« Reply #42 on: December 21, 2022, 08:08:48 pm »
Yep. Now a good reason otherwise is just about size. Internal flash is always relatively limited, and it's uncommon to get more than 1MB or 2MB of internal Flash, while you can get cheap external Flash chips with tens of MB.

People seem to be wary of wearing out internal Flash by writing to it too often, which could render the code itself compromised. It should not happen if as you say you are careful not to share the same pages for code and data, as internal Flash of MCUs is pretty basic and there is absolutely no internal reordering of data as with SSDs or such, so if you don't touch the "code" area, it shouldn't wear out if you write elsewhere.

Now to be fair though, a relatively common point is that the internal Flash of MCUs often has a lower specified max number of write cycles than external Flash chips. That's at least something to look at.
« Last Edit: December 21, 2022, 08:10:30 pm by SiliconWizard »
 

Offline SaimounTopic starter

  • Frequent Contributor
  • **
  • Posts: 538
  • Country: dk
Re: Flash an MCU from another MCU (over SWD)
« Reply #43 on: December 21, 2022, 10:23:19 pm »
Wow - apparently I started quite a topic ha ha!!

I started to look at your code @alex - thank you so much for that, it really is a life saver :)

What I want to program is a GD32 from another GD32 (probably the same one).

As I understood all I have to change is the hal_gpio.h to have the correct GPIO set/clr/out/in/etc, and the target setup in dap_target.c, right?
(in https://github.com/ataradov/embedded-swd)

And for the target I can get inspired of this file, right? https://github.com/ataradov/edbg/blob/master/target_gd_gd32f4xx.c

Some of you mentioned halting the CPU of the target MCU (the one that is being programmed). I did not actually think about that but it's a very good point! I can see this is done in the target_select() of target_gd_gd32f4xx.c :)
 

Offline ataradov

  • Super Contributor
  • ***
  • Posts: 10913
  • Country: us
    • Personal site
Re: Flash an MCU from another MCU (over SWD)
« Reply #44 on: December 21, 2022, 10:38:06 pm »
You can either change hal_gpio.h or just implement your own functions in the dap_config.h using any GPIO manipulation functions you like.

Yes, for the target target_gd_gd32f4xx.c would be the closest to what you need. You can look at the edbg target for Atmel Cortex-M0+ devices and see how that translated into the dap_target.c and do similar things to translate stuff in the target_gd_gd32f4xx.c. It shouold not  be to hard and you can take it one step at time starting with erase. Once you get that working, the rest is easy.
Alex
 
The following users thanked this post: Saimoun


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf