Announcement

Collapse
No announcement yet.

CSL '0401' Program Binary Disassembly Notes

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    I'm probably going to do a bad job of explaining this as it has a bunch of components to it, but I've figured out the operating system (by the way the name of the OS is OSKAR) task scheduling system. When I have a high enough level of enthusiasm I'll document this properly in the wiki, but for now here's the quick run-down.

    Each processor in the DME receives an external timer interrupt from the programmable interrupt timer 1024 times per second (e.g. approximately every millisecond).

    The interrupt is handled here:

    Click image for larger version

Name:	Screenshot 2025-06-19 at 10.55.31 AM.png
Views:	53
Size:	192.8 KB
ID:	309158

    So this function fires every 1ms, and in it it does some important high frequency things like update the system timertics variables, sync the values in the dual-ported RAM to local copies of the variables, etc.

    Every 2ms it calls sys_process_scheduled_tasks() which checks all scheduled tasks, updates the delay timers on each task and reschedules periodic tasks.

    Every time the function runs, and provided there are no other active interrupts, the tasks are actually dispatched via sys_dispatch_tasks which in turn calls sys_task_dispatcher.

    Both of these functions are below:

    Click image for larger version

Name:	Screenshot 2025-06-19 at 11.01.40 AM.png
Views:	52
Size:	217.1 KB
ID:	309159

    Click image for larger version

Name:	Screenshot 2025-06-19 at 11.02.35 AM.png
Views:	53
Size:	274.7 KB
ID:	309160

    There is also a function to schedule a task in the first place:

    Click image for larger version

Name:	Screenshot 2025-06-19 at 11.04.05 AM.png
Views:	54
Size:	202.7 KB
ID:	309161
    Click image for larger version

Name:	Screenshot 2025-06-19 at 11.04.16 AM.png
Views:	51
Size:	66.4 KB
ID:	309162

    And to cancel tasks:
    Click image for larger version

Name:	Screenshot 2025-06-19 at 11.05.13 AM.png
Views:	51
Size:	197.2 KB
ID:	309163

    The details of the tasks are stored in a pointer array in the program ROM (0x0003d810 in Master) which in turn points to a table of structs

    Click image for larger version

Name:	Screenshot 2025-06-19 at 11.06.57 AM.png
Views:	53
Size:	220.8 KB
ID:	309164

    The array of structs starts at 0x0003d798 (in Master program ROM)

    Click image for larger version

Name:	Screenshot 2025-06-19 at 11.08.19 AM.png
Views:	53
Size:	85.1 KB
ID:	309165

    And this is what I've figured out of the structure so far:

    Click image for larger version

Name:	Screenshot 2025-06-19 at 11.08.56 AM.png
Views:	53
Size:	111.6 KB
ID:	309166

    It's important to note that sys_process_scheduled_tasks runs every 2ms (every other time the timer interrupt fires) so the period and the initial delay of each task is specified in units of 2ms. e.g. task_10ms has period_2s set to 0x0005:

    Click image for larger version

Name:	Screenshot 2025-06-19 at 11.10.27 AM.png
Views:	51
Size:	31.6 KB
ID:	309167

    The task manager can manage up to 32 different tasks and can schedule up to 8 of them at once for execution.
    2005 ///M3 SMG Coupe Silbergrau Metallic/CSL bucket seats/CSL airbox/CSL console/6 point RACP brace
    Build Thread:
    https://nam3forum.com/forums/forum/m...e46-m3-journal

    Comment


      Another good discovery today. I've got a whole bunch more work to do before I write up a summary of it but I've figured out a bunch of the Inter-Processor Communication (IPK) mechanism which is used by the Safety Concept to provide a guaranteed communication mechanism between the processors for critical safety variables.

      Anyone who has looked into MSS54HP code will be familiar with the memory map table below and the fact that two sectors (0x4000 - 0x5fff and 0x6000 - 0x7fff) are unknown.

      Click image for larger version

Name:	Screenshot 2025-06-19 at 2.22.29 PM.png
Views:	50
Size:	417.2 KB
ID:	309177

      0x6000 - 0x7fff (and 0x86000 - 0x87fff for the Slave) is a memory-buffer zone which is used to store IPK frames to be sent over the IPK.
      2005 ///M3 SMG Coupe Silbergrau Metallic/CSL bucket seats/CSL airbox/CSL console/6 point RACP brace
      Build Thread:
      https://nam3forum.com/forums/forum/m...e46-m3-journal

      Comment


        Also started making some progress on the extra CAN message today:

        New CAN_Send_DME_ARBIDs_karter16() function which replaces the original CAN_Send_DME_ARBIDs() '

        Click image for larger version

Name:	Screenshot 2025-06-19 at 8.10.29 PM.png
Views:	44
Size:	193.5 KB
ID:	309194

        And screenshot of the disassembler's C interpretation below to show that I got the machine code right. our new CAN message is decimal 16 in the table.

        Click image for larger version  Name:	Screenshot 2025-06-19 at 8.03.43 PM.png Views:	0 Size:	39.6 KB ID:	309191

        And here's our new function being called in the 10ms task:

        Click image for larger version  Name:	Screenshot 2025-06-19 at 8.05.40 PM.png Views:	0 Size:	146.3 KB ID:	309192

        And here's the new entry in the table:

        Click image for larger version  Name:	Screenshot 2025-06-19 at 8.07.14 PM.png Views:	0 Size:	55.1 KB ID:	309193

        I've decided on ARBID 7D0 as it is higher (lower priority) than any other message in the table, used or not, and is still within the standard 0x000 to 0x7FF CAN ARBID range.
        The pointer to 0x0003f900 leads to empty program rom currently. The next step will be to build the new function to send the CAN message.
        2005 ///M3 SMG Coupe Silbergrau Metallic/CSL bucket seats/CSL airbox/CSL console/6 point RACP brace
        Build Thread:
        https://nam3forum.com/forums/forum/m...e46-m3-journal

        Comment


          And here's the function to send the new CAN message:

          Click image for larger version

Name:	Screenshot 2025-06-19 at 9.59.50 PM.png
Views:	43
Size:	185.2 KB
ID:	309198
          Click image for larger version

Name:	Screenshot 2025-06-19 at 9.59.58 PM.png
Views:	42
Size:	46.8 KB
ID:	309199

          And the C interpretation:

          Click image for larger version

Name:	Screenshot 2025-06-19 at 10.00.10 PM.png
Views:	42
Size:	69.5 KB
ID:	309200

          Who wants to check my work lol?

          Seriously though - I need to go through this with a fine-toothed comb.
          2005 ///M3 SMG Coupe Silbergrau Metallic/CSL bucket seats/CSL airbox/CSL console/6 point RACP brace
          Build Thread:
          https://nam3forum.com/forums/forum/m...e46-m3-journal

          Comment


            Counting the instruction clock cycles shows that this additional CAN message takes approximately 20us (micro-seconds) to run (that's for both the function that constructs the message and to actually push it onto the CAN bus).

            I've spent some time going through my work and am probably about as happy as I can be with most of it, I'm still working out a couple of the config bytes in the CAN message table - They don't seem to be relevant for sent CAN messages but I need to be certain on those before I go any further.

            After that will be to copy the changes into the flashable 0401 program binary and flash that to my DME as a guinea pig test. Amusingly I'm not setup for CAN logging so all I will be able to do is validate that the new program runs without error.

            I'm a bit concerned that I wrote the machine code for the new functions and haven't found any issues whatsoever with that work since. Usually that just means that you haven't found the bug yet 😏
            2005 ///M3 SMG Coupe Silbergrau Metallic/CSL bucket seats/CSL airbox/CSL console/6 point RACP brace
            Build Thread:
            https://nam3forum.com/forums/forum/m...e46-m3-journal

            Comment


              This is awesome!

              Question, what is FUN_0003aa20() doing?
              2002 Topasblau M3 - Coupe - 6MT - Karbonius CSL Airbox - MSS54HP Conversion - Kassel MAP - SSV1 - HJS - PCS Tune - Beisan - MK60 Swap - ZCP Rack - Nogaros - AutoSolutions - 996 Brembos - Slon - CMP - VinceBar - Koni - Eibach - BlueBus - Journal

              2012 Alpinweiss 128i - Coupe - 6AT - Slicktop - Manual Seats - Daily - Journal

              Comment


                Originally posted by heinzboehmer View Post
                This is awesome!

                Question, what is FUN_0003aa20() doing?
                Ah it's the function that actually pushes the frame to the bus. I must have taken that screenshot before I labeled the function.


                Sent from my iPhone using Tapatalk
                2005 ///M3 SMG Coupe Silbergrau Metallic/CSL bucket seats/CSL airbox/CSL console/6 point RACP brace
                Build Thread:
                https://nam3forum.com/forums/forum/m...e46-m3-journal

                Comment


                  Originally posted by karter16 View Post

                  Ah it's the function that actually pushes the frame to the bus. I must have taken that screenshot before I labeled the function.


                  Sent from my iPhone using Tapatalk
                  I figured, but just double checking . Maybe throw a screenshot of that function up for code review completeness?

                  C code LGTM. I looked through the assembly and it also seems fine, but my assembly skills are rusty, so take that with a grain of salt.
                  2002 Topasblau M3 - Coupe - 6MT - Karbonius CSL Airbox - MSS54HP Conversion - Kassel MAP - SSV1 - HJS - PCS Tune - Beisan - MK60 Swap - ZCP Rack - Nogaros - AutoSolutions - 996 Brembos - Slon - CMP - VinceBar - Koni - Eibach - BlueBus - Journal

                  2012 Alpinweiss 128i - Coupe - 6AT - Slicktop - Manual Seats - Daily - Journal

                  Comment


                    Originally posted by heinzboehmer View Post

                    I figured, but just double checking . Maybe throw a screenshot of that function up for code review completeness?

                    C code LGTM. I looked through the assembly and it also seems fine, but my assembly skills are rusty, so take that with a grain of salt.
                    sure thing - here we go :-). Note that CAN_send_frame() is the untouched original function that sends CAN frames to the bus.

                    Click image for larger version  Name:	Screenshot 2025-06-20 at 2.11.34 PM.png Views:	0 Size:	52.9 KB ID:	309259

                    Thanks! - I've validated it 3 different ways now

                    1: This morning I went through the assembly by hand, confirming what it was doing and validating it against its sister functions. As part of this I made sure to track the before/after states of all registers, the stack, etc.
                    2: I loaded the result in to Ghidra as you can see above and confirmed that both the disassembly and the C interpretation match what I expect.
                    3: I asked ChatGPT to interpret and summarize the assembly to check that it's interpretation of what was going on matched my own.

                    I'm at the point now where I can't really test it any further without loading it and giving it a go.

                    To that end I've taken the exact program binary currently on my car, made the above modifications to it, done a before after comparison to make sure I didn't change anything else by accident and loaded it also into Ghidra to validate the assembly and C.

                    Next up is to flash the program and try it out. As I mentioned I'm not setup for CAN logging, so will simply be validating that the DME, and car, runs without error. From that point on it'll be over to you and Bry5on to actually log the new message and confirm full functionality (if you're still game that is 😉)

                    Also if there's anything else you want to see in more detail (existing CAN message functions, etc.) let me know!
                    Last edited by karter16; 06-19-2025, 06:20 PM.
                    2005 ///M3 SMG Coupe Silbergrau Metallic/CSL bucket seats/CSL airbox/CSL console/6 point RACP brace
                    Build Thread:
                    https://nam3forum.com/forums/forum/m...e46-m3-journal

                    Comment


                      This is absolutely epic. Ready when you are my man! It’s been a while since I’ve done a regular full binary flash (as opposed to converting the bootloader). Fun!
                      ‘02 332iT / 6 | ‘70 Jaguar XJ6 electric conversion

                      Comment


                        Originally posted by karter16 View Post
                        I'm a bit concerned that I wrote the machine code for the new functions and haven't found any issues whatsoever with that work since. Usually that just means that you haven't found the bug yet 😏
                        That's generally how I feel after I've spent all day coding a giant function and it compiles without issue the first time...suspicious...

                        With that said, amazing work on decompiling the DME. This is very exciting work you're doing.
                        Phoenix Yellow e46m3 Build Thread
                        Orient Blue E46 330i ZHP k24/dct/turbo Build Thread

                        Comment


                          I flashed the modified program to the DME this morning and good news, I didn't brick the DME. Even better news, I found the bug!

                          As soon as I turned the ignition on after flashing I knew something was up as the DSC light was going mad. Modules relying on outbound CAN were throwing errors. It was a silly mistake to make that can be seen in the code above. I was trying to set the 17th frame in a 15 frame table..... 🤦‍♂️ Anyway, relocated the new CAN message to the unused 13th frame and refreshed. outbound CAN appears to now be working, all modules are error free and I used INPA to watch live CAN data coming in to the MK60 so the existing messages appear to be working without error.

                          Without being setup to log CAN data that's as far as I can take it, so the binary is now with Bry5on to do some further testing when he gets the chance and to see if the new message is being transmitted and if there's good data on it.

                          From there it will be a case of running with the modified program for a while and making sure that there isn't anything funny going on or any intermittent issues, etc. This is putting a small amount of additional load on the DME and is making the CAN bus busier, so we'll need to monitor and make sure there are no transient issues or less apparent bugs.

                          Exciting progress though!
                          2005 ///M3 SMG Coupe Silbergrau Metallic/CSL bucket seats/CSL airbox/CSL console/6 point RACP brace
                          Build Thread:
                          https://nam3forum.com/forums/forum/m...e46-m3-journal

                          Comment


                            Originally posted by karter16 View Post
                            I flashed the modified program to the DME this morning and good news, I didn't brick the DME. Even better news, I found the bug!

                            As soon as I turned the ignition on after flashing I knew something was up as the DSC light was going mad. Modules relying on outbound CAN were throwing errors. It was a silly mistake to make that can be seen in the code above. I was trying to set the 17th frame in a 15 frame table..... 🤦‍♂️ Anyway, relocated the new CAN message to the unused 13th frame and refreshed. outbound CAN appears to now be working, all modules are error free and I used INPA to watch live CAN data coming in to the MK60 so the existing messages appear to be working without error.

                            Without being setup to log CAN data that's as far as I can take it, so the binary is now with Bry5on to do some further testing when he gets the chance and to see if the new message is being transmitted and if there's good data on it.

                            From there it will be a case of running with the modified program for a while and making sure that there isn't anything funny going on or any intermittent issues, etc. This is putting a small amount of additional load on the DME and is making the CAN bus busier, so we'll need to monitor and make sure there are no transient issues or less apparent bugs.

                            Exciting progress though!
                            My god the man has done it!! karter16 you are an absolute legend. Time to load this into the datalogger!
                            Click image for larger version

Name:	KarterCANlog.png
Views:	21
Size:	292.3 KB
ID:	309355
                            Click image for larger version

Name:	KarterCANlog2.png
Views:	21
Size:	285.2 KB
ID:	309356
                            ‘02 332iT / 6 | ‘70 Jaguar XJ6 electric conversion

                            Comment


                              Yes! It is very satisfying to see that log!!! I'm so stoked that this has worked out!

                              It's a good proof of the general approach for making such changes as well.


                              Sent from my iPhone using Tapatalk
                              2005 ///M3 SMG Coupe Silbergrau Metallic/CSL bucket seats/CSL airbox/CSL console/6 point RACP brace
                              Build Thread:
                              https://nam3forum.com/forums/forum/m...e46-m3-journal

                              Comment


                                Originally posted by karter16 View Post
                                Yes! It is very satisfying to see that log!!! I'm so stoked that this has worked out!

                                It's a good proof of the general approach for making such changes as well.


                                Sent from my iPhone using Tapatalk
                                I'm so stoked too! Looks like it's outputting:
                                Intake Air Temp and Radiator temp: subtract 48, just like DS2 message
                                EGT: basically leave as-is, unlike DS2 message (multiply DS2 by 16)
                                Relative Opening: not sure yet, some scalar that looks the same as DS2. DS2 multiply by .0030518
                                Lambda Integrator: Subtract 2^15 then multiply by some factor that I'm not sure yet



                                Click image for larger version

Name:	Karterdatazaptest.png
Views:	29
Size:	158.5 KB
ID:	309366
                                ‘02 332iT / 6 | ‘70 Jaguar XJ6 electric conversion

                                Comment

                                Working...
                                X