CAN Bootloader

User avatar
EV_Builder
Posts: 1199
Joined: Tue Apr 28, 2020 3:50 pm
Location: The Netherlands
Has thanked: 16 times
Been thanked: 33 times
Contact:

CAN Bootloader

Post by EV_Builder »

As per title!
Couldn't find anything available so took the bootloader from Johannes and modified it towards a CAN version.

Build a GUI and the rest is history.

The CAN Interface used is a profi one from PEAK Systems.
https://www.peak-system.com/PCAN-USB-FD.365.0.html?&L=1

Didn't optimize yet for performance or size.

Currently 1 msg per mS (8bytes).
+/-8K/sec.
CanbootLoader.JPG
Update:
Currently the size needed is 0x2000 (8K) so we need to modify the LD files.
I'm thinking on a solution for that.
Converting an Porsche Panamera
see http://www.wdrautomatisering.nl for bespoke BMS modules.
User avatar
johu
Site Admin
Posts: 5681
Joined: Thu Nov 08, 2018 10:52 pm
Location: Kassel/Germany
Has thanked: 153 times
Been thanked: 959 times
Contact:

Re: CAN Bootloader

Post by johu »

That's cool. Puzzled by the size though... Is it on github for further inspection?
Support R/D and forum on Patreon: https://patreon.com/openinverter - Subscribe on odysee: https://odysee.com/@openinverter:9
User avatar
EV_Builder
Posts: 1199
Joined: Tue Apr 28, 2020 3:50 pm
Location: The Netherlands
Has thanked: 16 times
Been thanked: 33 times
Contact:

Re: CAN Bootloader

Post by EV_Builder »

johu wrote: Sun Nov 28, 2021 3:13 pm That's cool. Puzzled by the size though... Is it on github for further inspection?
No not yet i finished it last night.
Didn't optimize yet for size.
It uses both libraries cm3 and inv.
Converting an Porsche Panamera
see http://www.wdrautomatisering.nl for bespoke BMS modules.
User avatar
EV_Builder
Posts: 1199
Joined: Tue Apr 28, 2020 3:50 pm
Location: The Netherlands
Has thanked: 16 times
Been thanked: 33 times
Contact:

Re: CAN Bootloader

Post by EV_Builder »

Ok i optimized it a bit i now reserve 8K in the loader.

This is my contribution to the community of OpenInverter.org.
Enjoy!

https://github.com/EV-Builder/CANBootloader
Converting an Porsche Panamera
see http://www.wdrautomatisering.nl for bespoke BMS modules.
User avatar
johu
Site Admin
Posts: 5681
Joined: Thu Nov 08, 2018 10:52 pm
Location: Kassel/Germany
Has thanked: 153 times
Been thanked: 959 times
Contact:

Re: CAN Bootloader

Post by johu »

Superb, thanks!
So I did a build from the cloned repo and the binary was only 7k. Then I enabled -Os (optimize for size) and binary shrunk to 5.5k. While I much sympathize with using libopeninv, in this size critical application it could be worthwhile to carve it out even more than you did already. I can make a few quick experiments tomorrow to see if it's worthwhile
Support R/D and forum on Patreon: https://patreon.com/openinverter - Subscribe on odysee: https://odysee.com/@openinverter:9
User avatar
EV_Builder
Posts: 1199
Joined: Tue Apr 28, 2020 3:50 pm
Location: The Netherlands
Has thanked: 16 times
Been thanked: 33 times
Contact:

Re: CAN Bootloader

Post by EV_Builder »

Ok cool! I'm building the Bootloader GUI app right now.
Current speed is like +/-12 seconds to program 27K but i have some tricks on my sleeve remaining.
I think its the host pc limiting the speed not the uController.
(each msg invokes the GUI currently and that's expensive).

(how big are our inverter / charger programs anyway?)

Another option might be to program it on the end of the memory and jump back and forth...
You can then have: and the Wifi bootloader (serial) and then jump to the CAN bootloader and then back to start address.
(maybe by simply checking in the first bootloader if the CAN bootloader is programmed?).
Converting an Porsche Panamera
see http://www.wdrautomatisering.nl for bespoke BMS modules.
User avatar
EV_Builder
Posts: 1199
Joined: Tue Apr 28, 2020 3:50 pm
Location: The Netherlands
Has thanked: 16 times
Been thanked: 33 times
Contact:

Re: CAN Bootloader

Post by EV_Builder »

@johu; would you mind add to the bootloader (or paste it here) the code snippet to obtain the unique CPU id?
I need a 5 to 7byte ID.

I want to send it out on the first request for bootloader.
In the GUI we can then select which device we want to adress for the update and give normale names to the devices. (DHCP/DNS style).

This saves us from uploading to the wrong device in the network :)
Converting an Porsche Panamera
see http://www.wdrautomatisering.nl for bespoke BMS modules.
User avatar
johu
Site Admin
Posts: 5681
Joined: Thu Nov 08, 2018 10:52 pm
Location: Kassel/Germany
Has thanked: 153 times
Been thanked: 959 times
Contact:

Re: CAN Bootloader

Post by johu »

Yes, check here: https://github.com/jsphuebner/stm32-sin ... j.cpp#L177

Inverter firmware is currently about 45k
Support R/D and forum on Patreon: https://patreon.com/openinverter - Subscribe on odysee: https://odysee.com/@openinverter:9
User avatar
EV_Builder
Posts: 1199
Joined: Tue Apr 28, 2020 3:50 pm
Location: The Netherlands
Has thanked: 16 times
Been thanked: 33 times
Contact:

Re: CAN Bootloader

Post by EV_Builder »

txs!
Converting an Porsche Panamera
see http://www.wdrautomatisering.nl for bespoke BMS modules.
User avatar
EV_Builder
Posts: 1199
Joined: Tue Apr 28, 2020 3:50 pm
Location: The Netherlands
Has thanked: 16 times
Been thanked: 33 times
Contact:

Re: CAN Bootloader

Post by EV_Builder »

Ok made the tool stand-alone.
CanbootLoader2.JPG
Node selection works.
Converting an Porsche Panamera
see http://www.wdrautomatisering.nl for bespoke BMS modules.
User avatar
johu
Site Admin
Posts: 5681
Joined: Thu Nov 08, 2018 10:52 pm
Location: Kassel/Germany
Has thanked: 153 times
Been thanked: 959 times
Contact:

Re: CAN Bootloader

Post by johu »

That looks very nice! Would the GUI also run on Linux?
Support R/D and forum on Patreon: https://patreon.com/openinverter - Subscribe on odysee: https://odysee.com/@openinverter:9
davefiddes
Posts: 211
Joined: Mon Jan 18, 2021 12:39 pm
Location: Edinburgh, Scotland, UK
Has thanked: 14 times
Been thanked: 35 times

Re: CAN Bootloader

Post by davefiddes »

This thread seems to have stalled when it looked like it was heading towards a useful solution. Are there any updates?

I'm kicking the tyres around a solution for a Tesla Model 3 (i.e. TI C2000 MCU) CAN bootloader. It would seem to be best to try and combine efforts with a solution for STM32 systems.
User avatar
johu
Site Admin
Posts: 5681
Joined: Thu Nov 08, 2018 10:52 pm
Location: Kassel/Germany
Has thanked: 153 times
Been thanked: 959 times
Contact:

Re: CAN Bootloader

Post by johu »

Will revisit this now because my BMS only has CAN communication. @EV_Builder: can you make that GUI available? That said I will probably make a python script anyway.
Support R/D and forum on Patreon: https://patreon.com/openinverter - Subscribe on odysee: https://odysee.com/@openinverter:9
User avatar
EV_Builder
Posts: 1199
Joined: Tue Apr 28, 2020 3:50 pm
Location: The Netherlands
Has thanked: 16 times
Been thanked: 33 times
Contact:

Re: CAN Bootloader

Post by EV_Builder »

johu wrote: Fri Feb 03, 2023 7:08 pm Will revisit this now because my BMS only has CAN communication. @EV_Builder: can you make that GUI available? That said I will probably make a python script anyway.
Now that im commercially active I can't share that for the obvious reasons...

Better use a python script; or add-on on savvycan i only use Windows so it won't run on linux. My HW support is limited to peak adapters too.

Most importantly: use the full 8bytes during transfer; and bit bang so ack each message. Flash burn and CRC takes most of the time anyway.

If you run into issues I can help.
You already have my canbus bootloader firmware right?
Converting an Porsche Panamera
see http://www.wdrautomatisering.nl for bespoke BMS modules.
User avatar
johu
Site Admin
Posts: 5681
Joined: Thu Nov 08, 2018 10:52 pm
Location: Kassel/Germany
Has thanked: 153 times
Been thanked: 959 times
Contact:

Re: CAN Bootloader

Post by johu »

Ok, np.
EV_Builder wrote: Sat Feb 04, 2023 9:18 am You already have my canbus bootloader firmware right?
Yes, I will reuse the protocol and restructure the firmware a bit to hopefully fit into 4k. Did you implement a reset command in firmware? Otherwise I think I'll just add an SDO index for it.
Support R/D and forum on Patreon: https://patreon.com/openinverter - Subscribe on odysee: https://odysee.com/@openinverter:9
davefiddes
Posts: 211
Joined: Mon Jan 18, 2021 12:39 pm
Location: Edinburgh, Scotland, UK
Has thanked: 14 times
Been thanked: 35 times

Re: CAN Bootloader

Post by davefiddes »

When I didn't hear back I looked into the protocol some more. There looks to be a pretty serious problem with it when it comes to supporting more than one device on the same CAN bus. Think on turning on the ignition in a car with stm32-sine, stm32-vcu and your bms. Can I suggest you add a HW platform ID (stm32-sine, stm32-vcu, etc) and a unique node ID (say last 32-bits of the platform ID from DESIG_UNIQUE_ID0) to the initial "HELLO" packet? The reply to start the download would need to include the node ID to allow the competing nodes to determine if it was for them or not.
johu wrote: Sat Feb 04, 2023 9:45 am Did you implement a reset command in firmware? Otherwise I think I'll just add an SDO index for it.
Was considering doing something similar to replace other serial terminal commands (e.g. save, load, start, stop). Seems a hacky use of the protocol but easy to do. Would be good to share a common approach.
User avatar
EV_Builder
Posts: 1199
Joined: Tue Apr 28, 2020 3:50 pm
Location: The Netherlands
Has thanked: 16 times
Been thanked: 33 times
Contact:

Re: CAN Bootloader

Post by EV_Builder »

Yes; Later versions have that ID for exactly that purpose and the reset could be in the BMS firmware not in the bootloader.

The GUI can decide who to let go into user app and who not.
If you need todo multiple BMS boards i would do them one by one and keep others waiting. You can then release them all at once or one by one. I expect a small program so it won't take the world.
If you have Todo allot of boards i would broadcast the data and enable those devices who should write along. The ones who fail CRC could simply stop. This way I bet you don't over complicate and it will work. CRC never failed.
Converting an Porsche Panamera
see http://www.wdrautomatisering.nl for bespoke BMS modules.
User avatar
johu
Site Admin
Posts: 5681
Joined: Thu Nov 08, 2018 10:52 pm
Location: Kassel/Germany
Has thanked: 153 times
Been thanked: 959 times
Contact:

Re: CAN Bootloader

Post by johu »

I went over the code and removed the dependency for the libopeninv CAN module and some other unneeded stuff, see here
https://github.com/jsphuebner/stm32-CANBootloader/

The result:

Code: Select all

   text	   data	    bss	    dec	    hex	filename
   4056	     16	   2088	   6160	   1810	stm32_canloader
yay, back to 4k. Now of course I need to test if it still works. I left the program logic mostly untouched.
Support R/D and forum on Patreon: https://patreon.com/openinverter - Subscribe on odysee: https://odysee.com/@openinverter:9
User avatar
johu
Site Admin
Posts: 5681
Joined: Thu Nov 08, 2018 10:52 pm
Location: Kassel/Germany
Has thanked: 153 times
Been thanked: 959 times
Contact:

Re: CAN Bootloader

Post by johu »

I have now completely rewritten the loader while sticking pretty much to the original protocol. Tested and works. Also got the size down a bit more

Code: Select all

   text	   data	    bss	    dec	    hex	filename
   3796	     12	   2064	   5872	   16f0	stm32_canloader
Remaining issue: I initialize the clock to run off the internal oscillator (because I omitted the external one on the BMS). Now when I flash stm32_sine, it tries to switch to the external oscillator. This apparently fails and I get a very slow blinking LED. Is it not possible to change the oscillator after initial selection?
Wouldn't be a large problem, would just need to compile different boot loaders.

Protocol is now pretty much like the UART boot loader but I switched to 2k page size to be compatible with F105 and F107 without extra overhead.
  1. Send 0x7DE#1#'2' to indicate we entered version 2 boot loader
  2. Wait for reception of 0x7DD#1#0xAA magic
  3. Send 0x7DE#1#'S' to request number of pages, 2k per page
  4. Wait for reception of page size 0x7DD#1#S
  5. Send 0x7DE#1#'P' to request the first 8 bytes
  6. Repeat until full page has been received
  7. Send 0x7DE#1#'C' to request CRC over the 2k page
  8. Wait for CRC, check it
  9. If CRC correct program flash
    • If all pages received send 0x7DE#1#'D' and we're done
    • Otherwise go to 6
  10. If CRC incorrect send 0x7DE#1#'E' and go to 6
I have added an updater.py that implements this. Now need to implement a reset command via SDO.
EDIT: reset command should contain 32 bits of ID info in the data part to be able to precisely select which device to reset. Said ID should also be an SDO object. That said, the nodes should be set up in a way that they have different node ids anyway.
The BMS will achieve that with a daisy-chained address signal.
Support R/D and forum on Patreon: https://patreon.com/openinverter - Subscribe on odysee: https://odysee.com/@openinverter:9
davefiddes
Posts: 211
Joined: Mon Jan 18, 2021 12:39 pm
Location: Edinburgh, Scotland, UK
Has thanked: 14 times
Been thanked: 35 times

Re: CAN Bootloader

Post by davefiddes »

Looked at the code. Unfortunately it fails the "What if I have more than one?" test as explained above.

If you have clashing CANopen node ids then you are in for a world of hurt. Adding redundant information to a network protocol rarely ends well...
User avatar
johu
Site Admin
Posts: 5681
Joined: Thu Nov 08, 2018 10:52 pm
Location: Kassel/Germany
Has thanked: 153 times
Been thanked: 959 times
Contact:

Re: CAN Bootloader

Post by johu »

Yes, aware of that. Changing the magic to a word of the processor uid would fix it but requires obtaining said uid making the process more complicated.

When you've got your node ids sorted there wouldn't be an issue as you only ever reset one node and the other ones won't even see the updater packets down to filtering. The updater could obtain the firmware version via SDO. If it gets more than one reply, there's trouble.

Then there's the corner case of some devices not being flashed with running firmware. They'd be in the boot loader cycle asking for firmware. In that case you'd flash random firmware to one of them. Not good. You'd have to power down all OI devices except the one you want to flash.
Support R/D and forum on Patreon: https://patreon.com/openinverter - Subscribe on odysee: https://odysee.com/@openinverter:9
User avatar
EV_Builder
Posts: 1199
Joined: Tue Apr 28, 2020 3:50 pm
Location: The Netherlands
Has thanked: 16 times
Been thanked: 33 times
Contact:

Re: CAN Bootloader

Post by EV_Builder »

I help:

Include in step 1 6 bytes of chip unique Id.
Now on boot the GUI gives lots of chips. You can self compose list of who is what.
Insert wait loop for can msg if nothing boot user app.
If received 'W' with 6bytes equal Id rerun said loop.
If received 'AA' with 6bytea Id proceed.

Now on boot GUI can show all and if no choice is made it sends to all of them W with id.

Now user selects Id. That one receives AA. Now you have 2 choices keep others waiting..send W and their ID or don't do anything and they will boot user app.

Now Dave's case is solid and johu can control what to update and what not. In step 1 one byte is left. Could be used as device description. ...
Converting an Porsche Panamera
see http://www.wdrautomatisering.nl for bespoke BMS modules.
User avatar
crasbe
Posts: 234
Joined: Mon Jul 08, 2019 5:18 pm
Location: Germany
Has thanked: 43 times
Been thanked: 97 times

Re: CAN Bootloader

Post by crasbe »

johu wrote: Mon Feb 06, 2023 1:10 pm I have now completely rewritten the loader while sticking pretty much to the original protocol. Tested and works. Also got the size down a bit more

Code: Select all

   text	   data	    bss	    dec	    hex	filename
   3796	     12	   2064	   5872	   16f0	stm32_canloader
Remaining issue: I initialize the clock to run off the internal oscillator (because I omitted the external one on the BMS). Now when I flash stm32_sine, it tries to switch to the external oscillator. This apparently fails and I get a very slow blinking LED. Is it not possible to change the oscillator after initial selection?
Wouldn't be a large problem, would just need to compile different boot loaders.
I can't really say how libopencm3 does it, but I've done some PLL configuration on the register level of the STM32.
Generally speaking you have to be very careful about the correct order of operations. The reference manual is unfortunately not veeeery detailed about this, but you could check the PLL status flags as a start to see what's going on.

If the microcontroller doesn't like the PLL settings you're trying to do, it won't apply them. Maybe it thinks, that the clock is not ready yet?
7.2.6 System clock (SYSCLK) selection
After a system reset, the HSI oscillator is selected as system clock. When a clock source is
used directly or through the PLL as system clock, it is not possible to stop it.
A switch from one clock source to another occurs only if the target clock source is ready
(clock stable after startup delay or PLL locked). If a clock source which is not yet ready is
selected, the switch will occur when the clock source will be ready. Status bits in the Clock
control register (RCC_CR) indicate which clock(s) is (are) ready and which clock is currently
used as system clock.
https://www.st.com/resource/en/referenc ... ronics.pdf


I think you have to deactivate the peripheral clocks as well before switching over? But I really don't recall.
User avatar
johu
Site Admin
Posts: 5681
Joined: Thu Nov 08, 2018 10:52 pm
Location: Kassel/Germany
Has thanked: 153 times
Been thanked: 959 times
Contact:

Re: CAN Bootloader

Post by johu »

Intead of calling rcc_clock_setup_pll() which sets a whole host of prescalers I have now initialized only what I need:

Code: Select all

   rcc_set_pll_multiplication_factor(RCC_CFGR_PLLMUL_PLL_CLK_MUL6);
   rcc_set_pll_source(RCC_CFGR_PLLSRC_HSI_CLK_DIV2);
   rcc_osc_on(RCC_PLL);
   rcc_wait_for_osc_ready(RCC_PLL);
   rcc_set_sysclk_source(RCC_CFGR_SW_SYSCLKSEL_PLLCLK);
Then, most importantly the clock source must be reset to pure HSI (8 MHz) and the PLL must be disabled before leaving the boot loader

Code: Select all

   rcc_set_sysclk_source(RCC_CFGR_SW_SYSCLKSEL_HSICLK);
   rcc_osc_off(RCC_PLL);
The peripheral clocks can stay on. Would be more clean to turn them off but they will be used by most applications anyway (GPIO, CRC and CAN)

EDIT: this also saved a few 100 bytes of flash and we're down to 3.4k. I wonder if a unified boot loader supporting both CAN and UART is in reach.
Support R/D and forum on Patreon: https://patreon.com/openinverter - Subscribe on odysee: https://odysee.com/@openinverter:9
User avatar
johu
Site Admin
Posts: 5681
Joined: Thu Nov 08, 2018 10:52 pm
Location: Kassel/Germany
Has thanked: 153 times
Been thanked: 959 times
Contact:

Re: CAN Bootloader

Post by johu »

I have now handled the multiple device scenario by allowing an optional ID to be specified in the magic packet. So if you have just one device on the bus you can do as before and just send a 1-byte can message with 0xAA to enter update mode. If you have multiple devices you must know their DESIG_UNIQUE_ID2 value. ID2 seems the one that always changes between processors, should be unique enough.
It remains to the user to find this. I don't think having the boot loader send it out is useful as then you still don't know who sent what. If you have a wifi module you can find it out with the "serial" command (it needs to be pimped to place a ":" between the words). In a CAN setup you can only find out with a yet to introduce SDO which means you need your node ids sorted.

Once you know the updater is launched with

Code: Select all

python3 updater.py -d can2 -f stm32_yourname.bin -i 8721503A
It places the ID in the last word or byte 4-7 of the magic packet.
It will wait for an 'S' to be returned forever. If no one returns an S, no update happens.

EDIT: I think it might be useful to develop (if not exists) an ESP32-CAN dongle that runs the openinverter web frontend just transferring its data via CAN.
Support R/D and forum on Patreon: https://patreon.com/openinverter - Subscribe on odysee: https://odysee.com/@openinverter:9
Post Reply