Tesla Model 3 Rear Drive Unit Hacking
- Jack Bauer
- Posts: 3831
- Joined: Wed Dec 12, 2018 5:24 pm
- Location: Ireland
- Has thanked: 75 times
- Been thanked: 696 times
- Contact:
Re: Tesla Model 3 Rear Drive Unit Hacking
Will do and test tomorrow. Thanks Dave.
I'm going to need a hacksaw
- johu
- Site Admin
- Posts: 6969
- Joined: Thu Nov 08, 2018 10:52 pm
- Location: Kassel/Germany
- Has thanked: 455 times
- Been thanked: 1771 times
- Contact:
Re: Tesla Model 3 Rear Drive Unit Hacking
Hmm, this should be handled in code, I had it in mind when coding. All code is unified to 1k pages. The only difference is the erase command. On 1k pages it is called once for canmap, once for params. On 2k pages it is only called once and then canmap and params are written in one go.
At least that's how it should be
Likewise in bootloader erase is only called when the next 1k to be written contains something else than 0xff
At least that's how it should be
Likewise in bootloader erase is only called when the next 1k to be written contains something else than 0xff
Support R/D and forum on Patreon: https://patreon.com/openinverter - Subscribe on odysee: https://odysee.com/@openinverter:9
-
davefiddes
- Posts: 375
- Joined: Mon Jan 18, 2021 12:39 pm
- Location: Edinburgh, Scotland, UK
- Has thanked: 149 times
- Been thanked: 195 times
Re: Tesla Model 3 Rear Drive Unit Hacking
I am remembering you explaining that now and why it had to be as complex as it is. Apologies. I think I need to go through the code again with a clear head tomorrow. I wonder if some more recent changes have broken the logic.
- Jack Bauer
- Posts: 3831
- Joined: Wed Dec 12, 2018 5:24 pm
- Location: Ireland
- Has thanked: 75 times
- Been thanked: 696 times
- Contact:
Re: Tesla Model 3 Rear Drive Unit Hacking
One thing that did seem to help yesterday was changing the page and can block sizes to 2k in hwdefs.h
Although it didnt fix the can mapping it did stop the processor hanging and rebooting. What seemd to take place then was akin to a memory leak where the can map kept growing until it reached the maximum number of allowed messages. All I can assume here is the code is looking for the canmap in the wrong place? Perhaps program space.
Although it didnt fix the can mapping it did stop the processor hanging and rebooting. What seemd to take place then was akin to a memory leak where the can map kept growing until it reached the maximum number of allowed messages. All I can assume here is the code is looking for the canmap in the wrong place? Perhaps program space.
I'm going to need a hacksaw
- Jack Bauer
- Posts: 3831
- Joined: Wed Dec 12, 2018 5:24 pm
- Location: Ireland
- Has thanked: 75 times
- Been thanked: 696 times
- Contact:
Re: Tesla Model 3 Rear Drive Unit Hacking
Little bit more diagnostics. Starting from a fresh firmware and no canmap I try adding opmode to be sent on id 400 (0x190). It displays as 477(0x1DD) and indeed sends on 0x1DD. If I now add a second parameter UDC to be sent on 400 (0x190) it displays as id 400 and indeed sends on id 400 (0x190). Now if I ht save canmap all hell breaks loose and the spamming starts. This seems to occur regardless of the version of libopeninv used. Be it the master head , the version Dave fixed or the version used by the ZombieVCU master.
I'm going to need a hacksaw
-
davefiddes
- Posts: 375
- Joined: Mon Jan 18, 2021 12:39 pm
- Location: Edinburgh, Scotland, UK
- Has thanked: 149 times
- Been thanked: 195 times
Re: Tesla Model 3 Rear Drive Unit Hacking
I've checked the code again this morning and I believe it should work as johu described and automatically do the right thing irrespective of whether it is running on 1KB or 2KB flash page hardware.
The corruption of the CAN ID when adding a mapping is odd. Are you able to compare behaviour with the ESP8266/serial interface (assuming you are using the esp32-web-interface for CAN config at the moment)? Also doing the same with OpenInverter CAN Tool might be helpful. Something like:
You need to turn off the esp32 CAN interface when using OIC as you can only have one CANopen controller operating on the same bus at the same time.
Just had a thought: I wonder if it is blowing through its stack. The parm_save() function needs a lot of stack (1KB) for a temporary buffer. You can increase the size of the stack by editing stm32_sine.ld to use all the RAM in your part:
Edit: Wait, that's not going to work. Uhi22 and johu found a bug last year with the stack initialisation that hasn't been picked up by stm32-sine yet. Try:
This will pull in the fix they found for Focci. There's a lot more going on with the Tesla M3 gate drivers and oil pump compared to the regular stm32-sine.
The corruption of the CAN ID when adding a mapping is odd. Are you able to compare behaviour with the ESP8266/serial interface (assuming you are using the esp32-web-interface for CAN config at the moment)? Also doing the same with OpenInverter CAN Tool might be helpful. Something like:
Code: Select all
oic can add tx 0x190 opmode 0 8 1
oic can add tx 0x190 udc 8 16 10
oic can list
oic cmd save
oic can list
Just had a thought: I wonder if it is blowing through its stack. The parm_save() function needs a lot of stack (1KB) for a temporary buffer. You can increase the size of the stack by editing stm32_sine.ld to use all the RAM in your part:
Code: Select all
MEMORY
{
rom (rx) : ORIGIN = 0x08001000, LENGTH = 120K
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 48K
}
Code: Select all
cd libopencm3
git switch master
make TARGETS=stm32/f1 clean all
- Jack Bauer
- Posts: 3831
- Joined: Wed Dec 12, 2018 5:24 pm
- Location: Ireland
- Has thanked: 75 times
- Been thanked: 696 times
- Contact:
Re: Tesla Model 3 Rear Drive Unit Hacking
Thanks Dave. I have been working via the esp8266 wifi driect to serial usart 3 as I have not as yet installed the inverter in the drive unit due to this problem. So I did the memory increase , reflashed and used oic to try to add mapping. Results attached.
I'm going to need a hacksaw
-
davefiddes
- Posts: 375
- Joined: Mon Jan 18, 2021 12:39 pm
- Location: Edinburgh, Scotland, UK
- Has thanked: 149 times
- Been thanked: 195 times
Re: Tesla Model 3 Rear Drive Unit Hacking
That's messed up. It works perfectly on my Bluepill when I do the exact same thing. Web interface (via serial) reflects the changes and works fine too.
I'm running out of ideas for how to debug without having hardware on my desk. Not having an STM32F103VCT6 makes it very difficult.
As a last ditch attempt I've taken your code and integrated it with the latest trunk of stm32-sine and libopeninv. I've focussed my testing here because johu did fix a bug related to CAN map saving. The code branch is here: https://github.com/davefiddes/stm32-sin ... perimental
Can you take the binary from https://github.com/davefiddes/stm32-sin ... 7189994309 and give it try? That'll rule out any toolchain or working directory problems at your end.
I'm running out of ideas for how to debug without having hardware on my desk. Not having an STM32F103VCT6 makes it very difficult.
As a last ditch attempt I've taken your code and integrated it with the latest trunk of stm32-sine and libopeninv. I've focussed my testing here because johu did fix a bug related to CAN map saving. The code branch is here: https://github.com/davefiddes/stm32-sin ... perimental
Can you take the binary from https://github.com/davefiddes/stm32-sin ... 7189994309 and give it try? That'll rule out any toolchain or working directory problems at your end.
- Jack Bauer
- Posts: 3831
- Joined: Wed Dec 12, 2018 5:24 pm
- Location: Ireland
- Has thanked: 75 times
- Been thanked: 696 times
- Contact:
Re: Tesla Model 3 Rear Drive Unit Hacking
Exact same. I even did a full chip erase via SWD just in case.
I'm going to need a hacksaw
-
davefiddes
- Posts: 375
- Joined: Mon Jan 18, 2021 12:39 pm
- Location: Edinburgh, Scotland, UK
- Has thanked: 149 times
- Been thanked: 195 times
Re: Tesla Model 3 Rear Drive Unit Hacking
Thought I had a brilliant idea: Convert a VCU to use 1KB flash page size.
No dice, apart from hosing the existing config it works fine and I can set up and save params and CAN map. Whatever is going on is stm32-sine specific.
No dice, apart from hosing the existing config it works fine and I can set up and save params and CAN map. Whatever is going on is stm32-sine specific.
- johu
- Site Admin
- Posts: 6969
- Joined: Thu Nov 08, 2018 10:52 pm
- Location: Kassel/Germany
- Has thanked: 455 times
- Been thanked: 1771 times
- Contact:
Re: Tesla Model 3 Rear Drive Unit Hacking
I also reckon this is somehow a side effect of something else.
Apart from that the flash layout is somewhat flexible, only flashend-3072 (blknum 3) is hard coded as the address for the PinInit structure for the boot loader. The configuration of stm32-sine puts params in flashend-1024 (blknum 1) and canmap in flashend-2048 (blknum 2)
If any of that is changed it mustn't overlap with PinInit. On 2k pages flashend-4096 (blknum 4) thus can't be used
Apart from that the flash layout is somewhat flexible, only flashend-3072 (blknum 3) is hard coded as the address for the PinInit structure for the boot loader. The configuration of stm32-sine puts params in flashend-1024 (blknum 1) and canmap in flashend-2048 (blknum 2)
If any of that is changed it mustn't overlap with PinInit. On 2k pages flashend-4096 (blknum 4) thus can't be used
Support R/D and forum on Patreon: https://patreon.com/openinverter - Subscribe on odysee: https://odysee.com/@openinverter:9
- Jack Bauer
- Posts: 3831
- Joined: Wed Dec 12, 2018 5:24 pm
- Location: Ireland
- Has thanked: 75 times
- Been thanked: 696 times
- Contact:
Re: Tesla Model 3 Rear Drive Unit Hacking
So what is CAN2 in this case? Is that on Block4?
I'm going to need a hacksaw
- Jack Bauer
- Posts: 3831
- Joined: Wed Dec 12, 2018 5:24 pm
- Location: Ireland
- Has thanked: 75 times
- Been thanked: 696 times
- Contact:
Re: Tesla Model 3 Rear Drive Unit Hacking
In order the changes I have made over standard STM32-FOC are
1)Change timings to have 8.8KHz pwm and resolver.
2)Activate DMA2 in order to use UART4 for LIN.
3)Change FLASH_PAGE_SIZE to 2048.
1)Change timings to have 8.8KHz pwm and resolver.
2)Activate DMA2 in order to use UART4 for LIN.
3)Change FLASH_PAGE_SIZE to 2048.
I'm going to need a hacksaw
-
davefiddes
- Posts: 375
- Joined: Mon Jan 18, 2021 12:39 pm
- Location: Edinburgh, Scotland, UK
- Has thanked: 149 times
- Been thanked: 195 times
Re: Tesla Model 3 Rear Drive Unit Hacking
That symbol is not currently used. I think it's a placeholder for functionality that nobody has yet implemented.
I backed that out on my branch and the binary you tested.
The changes you made are minimal and didn't look scary to me.
- johu
- Site Admin
- Posts: 6969
- Joined: Thu Nov 08, 2018 10:52 pm
- Location: Kassel/Germany
- Has thanked: 455 times
- Been thanked: 1771 times
- Contact:
Re: Tesla Model 3 Rear Drive Unit Hacking
So for CAN:
Code: Select all
uint32_t flashSize = desig_get_flash_size();
return FLASH_BASE + flashSize * 1024 - FLASH_PAGE_SIZE * CAN1_BLKNUM;
As Dave says neither CAN1_BLKSIZE not CAN2_BLKNUM play any role and if there's any mapping saved for CAN2 it would overwrite CAN1 (but only when saving to flash!).
Parameters:
Code: Select all
uint32_t flashSize = desig_get_flash_size();
//Always save parameters to last flash page
return FLASH_BASE + flashSize * 1024 - PARAM_BLKNUM * PARAM_BLKSIZE;
So far so good but now comes PinInit:
Code: Select all
#define PINDEF_BLKNUM 3 //3rd to last flash page
#define PINDEF_BLKSIZE 1024
Code: Select all
uint32_t flashSize = desig_get_flash_size();
uint32_t pindefAddr = FLASH_BASE + flashSize * 1024 - PINDEF_BLKNUM * PINDEF_BLKSIZE;
And it thereby sits in the same 2nd to last 2k page as CAN1 mappings. So if you insist on using 2k for params and CAN1 then CAN1_BLKNUM would have to be 3. Even if you observe that this "fixes" something. It rather covers something up.
I'd rather suggest to leave FLASH_PAGE_SIZE at 1k because CAN1 mapping and params on the same page is handled in code.
However, none of that would result in the processor faulting out so that must be caused by something else. Currently it would check the CRC of the page invalidated by write_bootloader_pininit() and thus not load anything from flash.
Support R/D and forum on Patreon: https://patreon.com/openinverter - Subscribe on odysee: https://odysee.com/@openinverter:9
- Jack Bauer
- Posts: 3831
- Joined: Wed Dec 12, 2018 5:24 pm
- Location: Ireland
- Has thanked: 75 times
- Been thanked: 696 times
- Contact:
Re: Tesla Model 3 Rear Drive Unit Hacking
Thanks guys. I'll setup an MG board here on the bench today (same MCU) and hunt this thing down.
I'm going to need a hacksaw
- Jack Bauer
- Posts: 3831
- Joined: Wed Dec 12, 2018 5:24 pm
- Location: Ireland
- Has thanked: 75 times
- Been thanked: 696 times
- Contact:
Re: Tesla Model 3 Rear Drive Unit Hacking
Starting off with a basic A-B test. Setup is an MG V2 board (same mcu as M3 board) , 12v from a drill battery , CAN and wifi. Loading the unmodified code from the MG-DU branch gives Normal operation of can and can mapping. Next up am going to do a clean build of the M3_DU branch and see what happens.
I'm going to need a hacksaw
-
davefiddes
- Posts: 375
- Joined: Mon Jan 18, 2021 12:39 pm
- Location: Edinburgh, Scotland, UK
- Has thanked: 149 times
- Been thanked: 195 times
Re: Tesla Model 3 Rear Drive Unit Hacking
Uh huh. What's to bet the MG board works fine with the latest code.
You using the latest CAN bootloader (https://github.com/jsphuebner/stm32-CAN ... s/tag/v1.3) on both boards?
You using the latest CAN bootloader (https://github.com/jsphuebner/stm32-CAN ... s/tag/v1.3) on both boards?
- Jack Bauer
- Posts: 3831
- Joined: Wed Dec 12, 2018 5:24 pm
- Location: Ireland
- Has thanked: 75 times
- Been thanked: 696 times
- Contact:
Re: Tesla Model 3 Rear Drive Unit Hacking
Nope. MG board with clean build of M3 software and we are back to crazy can. Ignores commands of mapping from oic as yesterday. So its unique to the M3 code. Next move I'll strip down the M3 branch. Bin lin first.
I'm going to need a hacksaw
- Jack Bauer
- Posts: 3831
- Joined: Wed Dec 12, 2018 5:24 pm
- Location: Ireland
- Has thanked: 75 times
- Been thanked: 696 times
- Contact:
Re: Tesla Model 3 Rear Drive Unit Hacking
If this line (272) in 10ms task in stm32_sine.cpp is commented out the canmapping behaves as normal.
Now to see why...
Now to see why...
- Attachments
-
- Screenshot from 2025-08-25 13-47-12.png (8.15 KiB) Viewed 1341 times
I'm going to need a hacksaw
- Jack Bauer
- Posts: 3831
- Joined: Wed Dec 12, 2018 5:24 pm
- Location: Ireland
- Has thanked: 75 times
- Been thanked: 696 times
- Contact:
Re: Tesla Model 3 Rear Drive Unit Hacking
Narrowing further. Any call to LinBus:: Request will mess up the can mapping.
I'm going to need a hacksaw
- Jack Bauer
- Posts: 3831
- Joined: Wed Dec 12, 2018 5:24 pm
- Location: Ireland
- Has thanked: 75 times
- Been thanked: 696 times
- Contact:
Re: Tesla Model 3 Rear Drive Unit Hacking
More narrowing. The junk can gets its id from lines 105 and 106 in LinBus::Request. So somehow, data being sent to and from the LIN peripheral is getting to the CAN peripheral via the map and/or DMA....
I'm going to need a hacksaw
- Jack Bauer
- Posts: 3831
- Joined: Wed Dec 12, 2018 5:24 pm
- Location: Ireland
- Has thanked: 75 times
- Been thanked: 696 times
- Contact:
Re: Tesla Model 3 Rear Drive Unit Hacking
DMA is innocent. Simply having the following in Lin request causes the problem.
I'm going to need a hacksaw
-
davefiddes
- Posts: 375
- Joined: Mon Jan 18, 2021 12:39 pm
- Location: Edinburgh, Scotland, UK
- Has thanked: 149 times
- Been thanked: 195 times
Re: Tesla Model 3 Rear Drive Unit Hacking
First reaction was "Wut!?" but I think I can see what's gone wrong...
There's a use-after-free on your LinBus instance in stm32_sine.cpp:
If you shuffle the code to initialise the LinBus outside of the HW_TESLAM3 block it'll start working. I was going to move it anyway into the TeslaModel3 class (I think, implications need further thought) but no need to do that now.
Edit: The reason you see the data in CAN is because the memory that the LinBus pointer points to ends up being used by the Stm32Scheduler, Stm32Can, CanMap and maybe CanSdo class instances. When the 10ms handler runs is scribbles all over the internals of the CanMap class in an unpleasant way.
There's a use-after-free on your LinBus instance in stm32_sine.cpp:
Code: Select all
if (hwRev == HW_TESLAM3)
{
DigIo::gate_ps_en.Set();
uDelay(200000);
TeslaModel3::Initialize();
LinBus l(UART4, 19200);
lin=&l;
linM3.SetLinInterface(lin);
} // <------ the instance "l" is freed when this point is reached
Stm32Scheduler s(hwRev == HW_BLUEPILL ? TIM4 : TIM2); //We never exit main so it's ok to put it on stack
Edit: The reason you see the data in CAN is because the memory that the LinBus pointer points to ends up being used by the Stm32Scheduler, Stm32Can, CanMap and maybe CanSdo class instances. When the 10ms handler runs is scribbles all over the internals of the CanMap class in an unpleasant way.
- Jack Bauer
- Posts: 3831
- Joined: Wed Dec 12, 2018 5:24 pm
- Location: Ireland
- Has thanked: 75 times
- Been thanked: 696 times
- Contact:
Re: Tesla Model 3 Rear Drive Unit Hacking
I reckon someone (probably Johannes) Has injected a buffer overrun exploit.
I'm going to need a hacksaw