tl;dr The STM32/Cube software ecosystem is the worst I have ever seen. Does anyone feel the same? How can we fix it?
Here is my war story...
PS. I am new to embedded dev coming fresh from web-frontend/backend/iOS. Feel free to point out obvious rookie mistakes!
3 weeks ago I was tasked with porting custom firmware (developed with the Standard Peripheral library - now replaced by the HAL/Cube) from an custom STM32F407 board, to a new custom board with the STM32F411CEU chip. The program simply dumped data from the IMU and GPS onto an SD card when a button was pressed.
Everything went *relatively* smoothly apart from the fact that the GPS unit on 2 separate devices was destroyed. You can imagine how difficult that was to work out, but hey - welcome to embedded dev! Our office whiteboard is now covered in ESD warnings and every morning when I get out of bed I put on my ESD band around my ankle - lesson #1
.
Then I needed to pull the IMU data from the I2C2. Sounds simple, right?. I told my colleagues it would be less than a day of work. The I2C1 worked perfectly on a Nucleo board, but I2C2 did not work on either board. After a long process of debugging, probing, endless Googling, scouring forums I concluded that the I2C2 was broken. Lots of people had reported problems. I tried nearly everything, and each time I would try something I found that the darn BUSY_FLAG was set. The general sentiment seems to be that the I2C bus on STMFx series was very broken. I only recently heard about the infamous CPAL library, which seems to have been created because ST messed up so badly. But nowhere do they tell you. I came across the CPAL in a single Stack Overflow post where somewhere mentioned this library they had used long ago but could not remember the name. I had a [Wisdom of the Ancients](
http://xkcd.com/979/) moment. This comic pretty much sums up my entire three weeks programming STM32. I found myself constantly wishing I could read German with so many Google journeys leading to [http://www.mikrocontroller.net/forum]. I even considered asking my friend's Polish girlfriend to translate a forum for me because I saw a couple of interesting keywords in English popping out of a search result snippet.
I then verified that the I2C2 worked with the new HAL drivers from the Cube in a blank project. With no way to fix it, no other pins available to use other I2C peripherals, I had to move to the HAL drivers. I initially tried to just replace the I2C with the HAL I2C. After many hours of fixing compile errors, it did not work. Same BUSY_FLAG problem. Then I tried replacing the entire Standard Peripheral folder of drivers, and everything else. This was an insane amount of work and I eventually had to give up. So many wacky configurations, etc.
So now I was staring down the barrel of an entire rewrite of a perfectly working, well-tested codebase (the code and drivers were battle-tested many times in industrial projects), all because of a single I2C bus not working. I thought - OK, the HAL drivers will have bug-fixes moving forward, have support for my MCU (STM32F411CEU, which is not supported by StdPeriph), this rewrite would probably have been neccessary anyway. And every page on the ST website prophesizing that "the Cube" is the way of the future and I should migrate.
I was quite excited about the prospects of the Cube. Supposedly it would let me configure all my pins, check conflicts, generate code for all my protocols (a checkbox for DMA - woohoo!), FreeRTOS, USB virtual com, etc. I budgeted three days to port the code.
Holy fuck was I wrong. I have never used such poor quality software in my life. Nothing works out of the box at all. The examples don't cover any of the actual ways you would use the drivers. A virtual com example only available for the STMF429 chip, and only as a USART to VCP bridge. FreeRTOS integration not even a 1/4 finished - but with no note to the user that it is not implemented. USART examples for polling, interrupt driven and dma, but only for a contrived example of sending messages back and forth between two boards. I must have tried all the examples and nothing worked. The generated code is messy with pin configurations strewn all over the place, starting your project off with nice spaghetti code before you write a single line.
I would be so much better off *without* the cube.
Every single perhiperal was a *huge* battle with so many little bug fixes, workarounds, and hacks to the Cube's generated code along the way. When I finally got the USART working, it was by removing a the enormous interrupt routine that the Cube had generated which was causing over-run errors.
When I look back on the codebase I now have, it feels like the aftermath of a warzone. So many bandaids, patches, configuration settings that *just* work. I have a code base which I do not dare to change a line without flashing to the device and checking everything still works.
Icing on the cake for ST is if you look at the back of an STM32F4 Discovery kit ($15 USD - oo so cheap!) it mentions four "Development Toolchains": Altium Tasking, Atollic TrueSTUDIO, IAR EWARM, Keil MDK-ARM. Minimum price: $3000. Wow. What a joke.
After this experience I would never use STM32 for a new project again. Atmel looks like where its at. Big long datasheets, a free IDE (visual studio based!), cross platform support, a nice library with 1000s of examples, an ecosystem to share code, etc, etc. I am aware that it might seem like the grass is always greener, but when you are in a landfill the greeness of the grass is less of a concern.
So...am I alone? And how can we fix it?
STM32 make cheap, powerful chips, and have a lot of smart developers in their ecosystem, but I think the Cube has too much momentum right now (and is in too many powerpoint slides) to prevent it from collpasing in on itself and forming a singularity.
I have some ideas about how to fix this ecosystem which I will outline later.