ST Firmware Quality Sucks

Well – I got a STM32H743 Nucleo kit yesterday and wanted to autogenerate code for it from CubeMX (or STCubeIDE more exctly) – out of the box – it generates code that DOES NOT COMPILE on an eval kit. Sadly this is not the first time, it has become more the rule than the exception.

STMicroelectronics really need to get their Software R&D and QA manager in order if they have some. CubeMX is a good idea and concept, but the software that is generated is not guaranteed to work. Sometimes it is their new drivers and this happens far to often – this time I am puzzled as I need to dig into why I get the Message below.

The error above is from STCubeIDE where this code was generated – and as I said – this is on their evaluation kit!

My first thought is that i maybe should stick with STM32F407Vx – H753 is far more powerfully, but it usually takes about “10 years” for ST to get their FW drivers and support in shape. I seriously think they should sack some of their SW/QA managers because this is not acceptable and very bad for ST business.

I will get this working, but a more rational reason for considering STM32F407V is because it is identical to STM32F405RG with exception for the 100 pin package and added Ethernet. This is why I evaluate STM32H743 and H753. H7 are still a bit new and expensive unless you buy 10,000 units from ST – in which case you get it for < 9.- USD.

STM32H743

I decided to have a look at the STM32H7x3 series running at 480Mhz. The Nucleo board uses the 144 pin ZI version, but they also have a 100 pin V version. 100 pin is attractive because it gives me access to external memory, Ethernet and more + if I should go for a 100 pin I can as well chose the top-notch – they don’t cost that much more and 1Mb Flash + 1Mb SRAM is convenient.

We all know that Raspberry PI is superior if you want large displays, but I am looking for smaller, embedded displays where I find Raspberry PI to be clumsy due to wiring needs + it’s a few options of interest with this larger MCU.

  • 480 Mhz M7 core
  • double precision FPU
  • Up to 2Mb Flash
  • 1Mb SRAM
  • Fast SPI Memory and external memory
  • 4 x DMA controllers
  • 4 x I2C
  • 8 x USART/UART
  • 6 x SPI up to 150Mhz
  • 4 x SAI
  • SPDIFRX, MDIO,SWPMI
  • 2 x SD/SDIO/MMC
  • 2 x USB
  • Ethernet
  • 22 x Timers
  • 3 x 16 bit ADC’s
  • 2 x 12 bit DAC’s
  • 2 x Op amps
  • 1 x digital filer
  • LCD-TFT
  • Graphics accelerator
  • Camera interface
  • And more

 My interest in this is only experimental at the moment.

Ethetnet Switch Hat


I just received HLP-7688A module and looking at the size I must admit that I tempted to create a Switch/Router in Hat format. I am not os sure about the SPI on this, but it has 2 UART’s, so assuming I can control the code on the Linux module this could be interesting with Wifi and 3-5 10/100 Mbps Ethernet ports. The switch can manage 150Mbps so it is decent. Bandwidth to the backbone will be far less obviously, but it is an interesting idea.

The advantage compared to using Raspberry PI is (1) No SD Card boot, (2) multiple Ethernets and switch functionality and (3) Hat format. In fact I could support PoE out and use the WAN as another backbone to support larger switches. Just an idea.

I am still waiting on the dev-kits before I can play with this module.

Plain as Shell language

I am slowly getting the SW stack for BasicPI together and wonder if I should implement a minimal shell language based on Plain. I can regardless run a Plain appliction at start-up for configuration, but a shell language means that we are able to connect on a CLI console and write/execute scripts and commands ad-hoc

Technically this can be done in two ways – I can compile the script on the PC which will require a specialized terminal with a build-in compiler, or I could try implementing a minimalistic compiler embedded as a shell script.

I think the answer to this is that I consider these options as I write the “Assembler” for Plain. I have so far only done a proof of concept on Plain, so it’s a bit left before I have a working system.

Regardless implementation technique the concept with a “shell” script is that you connect with a terminal and edit/execute the script. Pretty much the same way as we did in old 80s Basic computers. This means the program source needs to be stored on the device, something which is a pain with 1Mb Flash.

Some of the old Basic interpreters used a neat trick of replacing keywords with a 1 byte ID to reduce size – I can do that. But we still have to deal with comments etc. The advantage is that you can connect ad-hoc to any device and change the behavior by changing the script. The drawback is that you start adding complexity to an embedded system – which is something I want to avoid.

Plain will regardless be easy to disassemble since we have 1:1 between instructions and statements in the high level assembly language.

Working with Linux and embedded Python I must admit that I look forward to be working with Plain and a distributed system language rather than the old, fashioned device languages + I must admit that Python never will be a language that I will like due to the syntax and features like exception mechanism.

Thank your for reading my Friday morning rant 🙂

Eport Pro-EP10 – Linux in a RJ45

I just received an Eport Pro-EP10 and must admit that I am impressed about the form factor. This is a standard RJ45 just a little longer than a normal RJ45. but with a full Linux computer, RJ45 Ethernet and UART on the other end. It should run OpenWRT, but setting up the toolchain is a bit complex so I have not gone far. At a price of 19.- USD I think the unit is a bit expensive, but it is an  very interesting solution. The challenge I have is however to find pin layout of this module. The vendor have a lot of downloads, but noting describing the package and pin layout so I can wire it up yet. 

  • MIPS 32 bit CPU @320Mhz
  • 32Mb RAN, 16Mb Flash
  • Linux w/Ethernet and UART
  • 10/100 Mbps Ethernet
  • 400Kbps UART
  • All in a RJ45 Connector

I am currently using a Linux module in a contracted project and a gentle warning about how much work and know-how that is required to set-up and use a Linux core is on it’s place. Embedded Linux is awesome, but it is not a plug & play job to adapt a Linux kernel. This is the one reason I hesitate to dig into modules like this and rather go down Raspberry PI path. On Raspberry you get a ready to plug in distribution that is well supported. But, lets see what I find out. Products like this are awesome, but Asian Products sadly have a documentation issue. It is not much I can do without information about how to Connect this Device – pin layout.

alStream

A MCU like STM32F405 have multiple serial devices and though their hardware is very different they perform the same job of sending/receiving ino. alStream is a base class for all components with a serial stream interface like USB, UART, CAN, SPI, I2C and even UDP/Ethernet. The objective is to provide a uniform messaging service where all interfaces of this type is equal except the Init() call that need to soft-wire the hardware. The draft consist of the following: 

  • Open() Open the stream.
  • Close() Close the stream.
  • Send() Send a message.
  • Receive() Receive a message.
  • SetReceiveTask() Set task to be notified  about received content.
  • SetSendTask() Set task to be notified about empty send queues.

The interface about will be repeated on all serial classes simply by using alSerial as base. alOS provide standard interface functions allowing alStream to interact with OS functions without any direct binding, so I use alOS::SetSignal() to make callbacks. That will signal a task to execute. Setting signals is better than a direct callback because it allows me to do the processing from within a tight interrupt routine. Also keep in mind that SetSignal increase a counter and that the task will be called once for each signal, meaning you have a natural mechanism for spreading bursts of messages out in time.

easyIPC SW Stack

This is the same as is on my previous entry, but I focus on easyIPC and Plain. easyIPC is a lot of modules to communicate with the rest of the system and while we easily can add user modules in C++, we can also add them in Plain.

Plain is compiled code running in a Virtual environment aJnd the strength is that Plain through easyIPC also can access resources on other Hat’s to form a larger system. This is a lot of work, but the objective is to make it very easy to build distributed systems and increase Productivity.

 

BasicPI Firmware Stack

This illustrates the BasicPI Firmware Stack in progress. What I always do in embedded applications is to make a “standard” main.cpp as follows:

  • void AppInit()
  • {
  •    // wire hardware
  • }
  • int main()
  • {
  •    AppInit();
  •    // start OS
  • }

A team I worked in years ago agreed on this standard so we should be able to easy recognize the basic architecture in any application and avoid wasting time figuring out how main() works. How you do this is not as important as the fact that you and your team does it in a systematic way.

I use C++ so it is very easy to hide all external FW with an abstraction layer. I hide even FreeRTOS because I will replace it later. The modules shown here are just an example, it will be numerous others as I progress. The key is that I want a standard “OS” with known functions so that I can easily move move user modules from Hat to Hat, or make changes to the lower layers without worrying about required SW/FW changes.

Yes, this will bloat a little, but to be honest less that I expected. I use ST HAL drivers for now, but in highly optimized versions and I will remove some of them given time. Right now they are a conveniance.

FreeRTOS should not need any introduction. CubeMX offer installation of FreeRTOS with a single button and I found it easy to install and use + a thread shifter is always handy to have around. FreeRTOS is mature, open source and heavily maintained. The only abstraction I needed here was to hide the functions I needed to use.

L Kernel is a Linear Kernel that exist on top of FreeRTOS. FreeRTOS threads require stack and they can only change as fast as SysTick runs. L Kernel tasks needs no stack and they execute as fast as the MCU is capable of. L Kernel can also run without FreeRTOS and you control that from AppInit(). With no threads you can bit-bang if required and use a alHWTimer (or SysTick) to run a small list of maintenance tasks. L Kernel is also excellent for event driven schemes, buffer handling, software timers etc.

alLed is a funny, new extension – I decided that I use so much time blinking leds that I needed a system to wire it and support blink sequences. This allows an easy path for user apps to signal state through a led.

I threw easyIPC into AL on this drawing, but easyIPC itself is actually an user module, while alEasySPI is a specialized SPI driver. I can’t use alSPI for easySPI because I need to monitor the line for SW signals with very short reaction time. I set the spec to 4 ms, but < 1 ms is realistic. This is the drawback of the SW trick I use + running the SPI on 30+Mbps means it will require some CPU to process. I probably can check faster than 1ms, but that will take a toll on CPU usage. I expect that easySPI will require < 5% CPU usage With 1ms responce times.

I still have not tested Half Duplex SPI and it is busy in real life, and a hot summer with 35 degrees Celsius outside + SW is the largest task on my projects. It is one task that makes you realize how much work that has gone into the word “it is simple” on Arduino.

The upside with nice weather is however that I have to work in my mess of a garden, and my back usually kick in after while forcing me to go inside and sit still – an excellent excuse for working on my projects 🙂

Thanks for Reading!

XPortHub Rev 1.2 Annotated

 

  1. CAN
  2. CAN
  3. RS485
  4. RS485
  5. Terminal switch for CAN & RS485
  6. USB
  7. Micro SD Card
  8. SPI Flash
  9. RTC Battery
  10. Power connector
  11. I2C
  12. SPI
  13. TTL UART
  14. RS232
  15. RS232
  16. Raspberry PI Connector
  17. STM32F405RG
  18. SWD Connector

Changes from Rev 1.0

1 Corrected wrong SPI Flash package
2 Added resistors to SPI 1 to support Half-Duplex SPI
3 Replaced supercap with CR1220 battery holder.
4 Several PCB changes to optimize ground plane.
5 Changed DIP switch order to match port order on board.
6 Changed to new SWD header.