ECU – Software Stack – Part 2

Part 1 of this article summarized scope of work because software for an ECU basically have two core bulks – one is the core and main controller, while the second is the add-one modules and specialized IO. This second part is basically endless as we will be adding more features and more hardware, so in this summary I want to focus on the main controllers. The block diagram below outline the main components.

RTOS that I use can be FreeRTOS, ThreadX or whatever, but I always add a barebone, linear scheduler as well because that enables FW to scale better. Most of the times I just run barebone, but I can always add a thread shifter if needed. RTOS must provide a set of critical functions that all SW is allowed to use – two of them are functions like millis() and microes() to measure elapsed time. The key functionality is however an easy path to set up tasks and decide how they execute for the system to work.

HAL (Hardware Abstraction Layer) is whatever drivers you get from a vendor and that interface to hardware. The challenge with this layer is that it is not a proper abstraction layer as different vendors will have different drivers and diffenert aproack to do the same thing.

AL (Abstraction Layer) is my own C++ layer to access hardware or software that I want to re-use in an uniform way to protect code. Using HAL drivers comes at a price – overhead and specialized hardware interface + I sometimes need to deal with workarounds or simply want a simpler interface. Also I sometimes need low level drivers that are fast and C++ is well suited to have a nice interface to a tight assembly function should I need to. Ethernet as an example can be a hardware or software interface and I need an uniform way that hide this complexity. The AL is common in all my systems and RTOS is part of the AL library.

Primary CAN is the CAN port combined with the 8-30V PSU connector. I initially had a separate PSU connector, but decided that since all main boards have CAN-FD I can as well add one here using the NMEA2000 layout. This also gives me easy access to cable infrastructure. The primary CAN can be used like any other CAN port, but it is also linked to CLI giving access to all configuration.

USB is used as a serial driver to enable a PC to connect, even power a motherboard from USB and configure it using USB. We might add more sofisticated methods later, but as a start you will need to connect to the USB for (1) configuring the system and (2) downloading new firmware.

CLI (Command Line Interface) is a text based command utility that allow you to interact directly with the system, configure components, modules and load new firmware.

Bootloader is a small FW package that is executed at start-up to check if a new FW is needed. For the main controller we download FW as an image on the disk and as we restart that FW is loaded. For the modules this operation is controlled by the mainboard, so we download to mainboard that then download to the modules. The bootloader cannot be broken, but a FW upload might fail in which case we restart the download procedure. We also have the option to rollback to a previous download as we can store multiple images on Disc.

Power Management. As we have multiple IO modules drawing Power we need to monitor their power usage and switch them on/off as needed. All motherboards can switch on/off any sub-module as needed. This includes logic to blacklist non-working modules – in which case we raise a sub-system down alarm.

Dictionary is our central database partly in RAM and partly on disk. This is a list of variables, tables, modules etc – everything we use in the system. The Dictionary  list the content primarely being an index, but the actual data can be located in user modules or copied in the Dictionary + FW images will always be on disk. One module interface to another through the dictionary which makes it easy to build a distributed system as modules can be located on different nodes if required.

Disk is an extension of dictionary where selected variables are stored on SPI Flash when changed. FW images are only stored on disk. At start-up the system will read all parameters to initialize the system. After that we save parameters then changed.

Event Distribution, As variables in the dictionary change we can signal receive tasks to pick up the changes – this can be done per variable or for a set of variables. If we are on the same MCU this will mean one task change a variable and another one deals with that change within 50yS. If we are on different Nodes we can still interact within 500yS and maybe faster. Also multiple modules can interact with the same module with no extra effort. Signals within tasks are very efficient, but you can also do a check every 10ms scheme or similar. If the receiver of a signal is a communication port then the receiver will pick up data and transfer it on the bus as fast as possible.

Module IO is a generic protocol as the motherboard assumes nothing about a module. In the config we will have a list of what we expect and as we start each module we do an identification. Each module have an unique type number and id, so the motherboard can instantly see if this is what we expected or something else. If it is a new module we need to load it’s part of the dictionary so that modules using this one find data they look for. Process for staring is very fast and easy, while process for connecting new modules will require a bit more communication depending on module.

Obviously it is a lot more details to the functionality than mentioned here, but is should give you a brief idea of how it all plugs together.

ECU – Software Stack – Part 1

I have started the FW on the ECU that will take a while, but I can outline the main design principles I use:

ECU Hardware consist of a a motherboard with a M12-4 Power connector. I use the same format as NMEA2000, but allow for 8V to 30ichV PSU rather than only 12V. I do however add the CAN port so that we can re-use NMEA2000 infrastructure as well as claim NMEA2000 compability. So that gives us CAN as primary interface.

I also add an USB as a serial port because it is convenient to just plug the main board to a PC for direct, first time configuration this way. Through this we can do CLI scripting to configure the node and detect what’s on it.

My current motherboards have PCB layout for one Ethernet, but I am not sure I want to keep that. I have two Ethernet modules that are better as they have separate MCU’s offloading some of the work. So – I think the Ethernet port can be dropped in favor of other features on the motherboard.

Disk is SPI-Flash, SPI-FRAM or SPI-PSRAM. Each motherboard will as a minimum have a SPI-Flash.

The Motherboard is a powerfully MCU acting as a switch between all interfaces. I want to keep this as simple as possible, but it also have capabilities to run automation based on data from multiple modules.

What makes this design special is the add-on modules, because you take a small box and add up to 8 modules to get the IO you want. Each modul vary in IO, but they have the same interface to the motherboard. This is a star design so one module will need to send messages to another module through the motherboard – or more correctly the motherboard is configured to forward seleced messages to the modules – something you can configure.

My modules that are in progress are as follows:

  • CAN Module. Fitted with a small MCU and fully galvanic CAN interface using NMEA2000 standard we can make a CAN Hub with 8 ports easely. In fact we can link Nodes and create a CAN Hub that is as large as we want as long as we remember to do bandwidth calculations.
  • RS485 my newest board is mostly for Modbus. This old protocol is hard to avoid and is a very handy interface as many 3rd party components will support this.
  • Single Ethernet connection so we can hook up standard Ethernet and work.
  • Tripple Ethernet connection with a switch in the connection so that we have two external ports and one internal. This is needed for low level Profibus or Ethercat support, but it also allows us to daisy chain Ethernet and avoid a centralized switch.

As for the rest we need some actual IO:

  • Analogue IO. I designed a fast, high precision AI board capable of recording 3 channels at 65Kbps with 24 bit resolition. This is primarely designed for vibration sensors, but it is a generic 3 – single lines, or 2 delta lines fully galvanic isolated.
  • Digital Out – An 8 port digital out capable of multiple ampers and PWM with load detection and current sensors. This can be used as a Power source or as a 3-phase motor driver, solenoid driver, stepper motor driver or DC motor driver.

I have plans for multiple boards, but the only one I actually need fast is a Power Servo Controller. I have some 150Kg Servo drivers I want to put into usage and they need multiple voltages and proper servo signals – which brings me to one more module:

I will need a PSU capable of delivering some Ampere on multiple voltages from 48V, 24V, 12V, 8V and 5V. I use 24V as base, but IO modules sometimes need a secondary source with different voltage, so the 24V is basically for control systems and remember that we talk 8-30V and not just 24V.

I have one more module coming up  – this is work in progress, but it is a motor controller targeting 12KW motors. It’s actual capacity is 48V-1200V and some 50A, but it will be designed to sustain 12KW and hence be in the smaller and lower side of motor controllers. The interesting part on this is that total size is very small and that it comes with 10 possible Add-On modules.

It has current sensors, but Resolver, Encoder, Hall Sensors and end points + extra sensors you add through an add-on module. On the left side I have space to add a break-resistor or a sinus filter – the later is needed for induction motors as this can drive all type of 3-phase motore. The design parameters are 600V/20A, but the board is capable of 2 x that.

This is designed for a standard aluminium box and MOSFET’s are underneath directly connected to heatsinks, but we talk about something like 15W in loss on 12KW. I can mount extra heat sinks if needed, but I am not sure I need to on this one.

In short – this is a motor controller where you add the PLC as modules inside the controller to reduce need of extra space and components. My calculations indicate a cost base on ca 300.- USD even for low volumes, and these controllers are usually priced between 1000 to 4000.- USD depending on content.

As this also is an ECU motherboard it will use the same FW as the ECU’s but add current sensors and motor control – I hope to mount the first prototype during x-mas. I need to finish the design and order PCB’s, because I will probably need 3 rounds on this before I am happy.

The content of this HW summary will change as we move forward, but it serve as a reminder of what we need to solve in SW – that will be described in part 2.

ECU – CAN Modul w/USB

I was focused on making a CAN Modul, but as I tested yesterday I also realized that I easely can add a USB port on this to use it as a stand-alone USB/CAN Adapter – which is very handy since it has the M12-5 connector used by NMEA2000.

This modul has been straight up so far, but the added value of having USB as an option is worth an extra round. The center pin is wrong on the 3D package above, so just ignore it for now.

In general I would have liked USB on many of the moduls, but had to abandon it due to lack of space – I was intending to make a speciel version of the CAN modul then I realized that I had the extra space here – which is great.

NMEA2000 M12-5 also has 12V enabling us to just attach this on a NMEA2000 network and convert PGN’s etc, but my primary use is as an analyzer so I can see what is sent on a network + I can still use it as an ECU module. It’s  a win-win.

ECM – CAn Module

Finished CAN Modul. This uses a M12-5 Male because the NMEA2000 T-Connectors are female and most cables are female to male, so this can be connected directly on a NMEA2000 network with no extra fuzz.

One of the nice details are the 5V DC/DC on right bottom, a SSR to switch on/off 120Ohm resistor and a 12Mbps CAN-FD that handle 5000V in 1 minute. This one has a full galvanic isolation. NMEA2000 is only 250Kbps, but I am eager to test FD capabilities as well. The only thing missing is the SPI Flash, but I won’t need that for now.

Here you see the cable attached to the modul and a T-connector – looking at my fingers you also get an idea about how small this moduls are. This is not my first CAN modul and to my knowledge so far this was an error free run, but lets get SW running before we conclude on that.

What I need to work on is a RS485 modul to match – it’s on my list of things to do.

ECU – Dual Ethernet Module

This is a Dual Ethernet Module using M12-4 ports. I drafted this earlier. I need to use aSTM32H573 for this since the PHY chip is a 3 x Ethernet switch. The big point with this module is that it provides dual, redundant ethernets, Profinet and Ethercat capabilities.

I have Ethernet on the CAN Hub that I am still working on, but not every module need Ethernet so I am considering two modules – the one above and a single Ethernet based on W5500 or similar. The one above is straight forward – still a bit work in progress – while the W5500 one is ready to be ordered – 3D illustrated below.

The W5500 one can also deliver redundant Ethernet, but to my knowledge they cannot support Profinet RT or Ethercat. These will both be coming up soon, but I want to finish what I have first.

ECU – ECUModCAN

It is alway cool to solder up a modul, plug it in and see that it is working – ok half a modul.

Had to use the old CAN Hub as I have not soldered up any of the new main boards yet. I urgently need the NMEA2000 interface as a friend have problems in hes boat – so need to muck up a CAN sniffer asap. I am still a bit shocked over how small these modules are. The old SWD connector works fine, but it collided with the modul connector so had to cut it in half – think it’s time to make some new ones – these have worked fine for years.

The MCU is STM32H503CB because it was small, had a lot of IO/power and dead cheap. Costing ca 2.- USD in quantity of 25, but I also have STM32H523Cx that only cost a few more cents and have much more Flash/SRAM – the later is pin compatible with H503 so I can upgrade if I run out of Flash/SRAM. Alwasy nice to have that option, but 128K Flash is quite a lot since build-in bootloader on this is available on the modul interface.

modul 1 on

Kind of fun to connect to one main board abd ask it to switch on a module – I really like the concept I have here where mainboard can restart modules.

As for Flash I have 128Kb and I am not so concerned, but I accept that with a CAN port and support of CANopen and J1939 I might need the 256Kb or 512Kb options in STM32H523Cx – not sure. It is only a 50 cent difference in price delivered at my home from Digikey. That said H503 is one of the most formiddable MCU’s I have used. Running at 250Mhz with loads of IO and a M33 core it is very capable. H5’s can’t compete with H723 that I use on the mainboard in speed – specially since H723 have 64bit double support, but H503 is still far faster than a majority of MCU’s. It is a combination of speed, flash, ram and cost on the H5 series that is awesome.

BSA – Sub-Diagrams

Following up on my previous entry – I think the new header on sub-diagrams worked out well. Colors/background can be changed in preferences, but the symbol is very different from function call and it is square to make it easy to attach lines. I could have used the more classic UML Package, but that header is clumbersome with lines attaching to the symbol.

BSA – Line collections

UML State is in effect a sub-diagram and I need a few improvements on how I visualize sub-diagrams. Under is a classic example on how I would draw 2 diagrams with 8 events/methods that goes from diagram to diagram. While this is possible and sometimes wanted it is also a bit clumbersome.

 

To improve precentation I have added two changes – the first is to tag events (exit labels) with a cross so the circles look different from methods (input labels). The second is to allow lines to be collected and replaced by a thicker line that indicat this is a collection of events. If you click on this line you will see a list of events/methods that are hidden. This makes it easier if you have multiple events from a diagram that all goes to the same place.

The last change is to add a title label. I don’t want to use the same header used in function call, so I will try the one below and see how it works out. This will be visually different from function calls and it solves the issue with lines on top conflicting with a small label above the sub-diagram.

The new lines are a bit of work – the lines themself are easy to make, but the collection of event/methods needs a bit of work. As for the methods/events I think we also need an option to place fixed methods/events freely on all four sides. Another issue is how I visualize unused methods/events and mandatory ones. In an earlier version I visualized everything like illustrated above and went against it – I did not like the result, but I could visualize unused ones and hide the circles once events/methods are used – but, that is details for another day.

But, how do I edit code that execute inside a selected device ?

The obvious answer is that we let the device be associated with a diagram and that everything inside that diagram executes on the device! If we in addition decide that this diagram reprecent a module we can also alter the visualization a bit to differ it from standard diagrams then used from other modules. Methods called then become messages sent to that device while events becomes messages received from that device.

Back to the idea of using small circles on absolutely all events/methods – that option is implemented, but I switched it off because I did not like the resulting diagrams. All the small circles made the diagram fuzzy to read, but that should be different if they only reprecent “TODO’s” – you see a circle because you have an unused method/event and once you use it the circle is hidden. If I also implement a right-click menu I can chose to move or hide a connection point.

I hard-coded modules in my previous entry to reprecent ECU w/sub-parts, but the real package will be a used add-on created as modules with fixed diagrams. This means I need some new property options on diagrams to control behavior. The idea is that you import a SDK to a project and that it add itself to the tool bar. That SDK is only a previously saved module tagged as a SDK so that the interface add itself to the toolbar. BSA itself should only contain core modules as “build-in” – these are tools that you never will be able to change, but you are free to create duplicates that is extensions or behave differently. As we save a projects we also save the modules you have used so that your project is consistent.

BSA – System Diagram

One of the challenges is how to visualize ECU in BSA. The symbols below are highly exprimental and mostly added to drive the discussion about how to do this in a system diagram if you have an ECU with sub-modules. How do I visualize this in a diagram creating code for that ECU?

The “PWM Out” is intended for my 4 x DO module that has 4 PWM signals out. I can set PWM with parameters into the module using the example above, but for each PWM signal it will be multiple methods and events (not just the single method illustrated). I could have one symbol for the ECU itself and then one symbol for each resource available. The example “Analogue In” would generate an analogue signal at configured frequency that then is sent as an event into the application…

This could work, but I need to work on the idea a bit.

It will be a lot of modules on my ECU, but the current list is:

  • Mainboard
  • PWM Out module
  • Digital In Module
  • Analogue In
  • Analogue Out
  • CAN
  • RS485
  • Ethernet

Those highlighted already exist.

I also need to think about system diagram that is a diagram showing how ECU’s are virtually/physically wired – I will get back on that.