cancel
Showing results for 
Search instead for 
Did you mean: 

How to write programs for STM32

I often write here that I don't use Cube/CubeMX. This sometimes rises questions, e.g. one forum member asked me off-forum:

> What would be the best way to program STM32 MCUs ?

> Don't you use the cubemx generated code ?

> Have you some sort of good guideline about stm32 programming ?

Unfortunately, I don't have any guidelines. I can tell what I am using - a generic programmer editor of my liking, make-driven gcc, command-line gdb for debugging with STLink. I don't use any "library" (i.e. intermediate code attempting to embrace all aspects of the STM32 such as Cube, SPL, libopencm3) and by extension don't use CubeMX.

We can discuss the rationale, merits and demerits of this approach which may appear spartan, but that's not what recommendations are about. The problem with recommendations is, that there are many options, and none of them is "the best", "the one" - all of them have their place and are useful, given particular circumstances of use.

Thus, Cube/CubeMX may be perfectly adequate for hobbyist "arduino-like" use, or in cases where the hard-real-time controller-like aspects are not important, or in cases which fit perfectly to the usage cases the CubeMX/Cube authors envisaged and won't depart from them ever. And there are other libraries and code related to STM32, often as part of bundles for some particular purpose (e.g. drone flight control software, RTOS, security software package); there are third-party libraries for various specific purposes; there are several IDEs, high-$, low-$ and free; and there are other programming languages and other tools to create programs for STM32. I may have heard about some of them, but not even tried most of them not to mention using them properly. How could I posssibly make a recommendation, then?

So, it's upon you to do the research and decide, what to chose.

But I do have a recommendation, a pretty generic one. Whatever the toolset, strive to write as many (mostly simple) programs as possible, try to excercise as much peripherals of STM32 as possible, try many modes of their operation, and try to interface with external circuits. Try various debugging techniques, build your own toolbox. And read the available literature. This sounds - and is - painful and takes time, but it's the only way to achieve perfection.

My 2 eurocents.

JW

PS. I wrote this post in the hope that forum members more knowledgeable than me will make the recommendations and answer the questions from the start of this post.

5 REPLIES 5

Take small bites. If you have no experience, don't take on projects which are too complex.

Use the libraries or existing infrastructure to experiment, you may choose to discard it later, but get something working first.

If you write code that requires a complete reading of the reference and technical manuals, don't be surprised it doesn't work if you don't bother, and don't expect everyone to read the manuals to you.

Don't expect to press a button and learn anything. Robots are stupid, I can train monkeys to press buttons. If you want employment in this field you need to know how the machine and the plumbing work.

I don't want to debug your code.. I can write working code the first time around, I don't need to share the failing experience of a 1000 pieces of broken code, I learn next to nothing from such exercises.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Piranha
Chief II

I do agree to Jan an Clive and can share my approach and suggestions.

For beginners, who really want to understand MCUs and make serious products. Buy some Nucleo or Discovery board and go through this thoroughly:

https://www.embeddedrelated.com/showarticle/453.php

As for IDE I can suggest EmBitz:

https://www.embitz.org/

It's not perfect, but it's fast (native code, not Java), small, free and all in all is good enough even for serious work. I don't use it's wizards and set up empty projects completely manually very similar to this example:

https://blog.bastelhalde.de/post/setting-up-embitz-1-11-for-an-stm32f7-hal-project

And then comes the most tricky part - code.

  • LL "base" - as almost all of these "functions" are only one line macros, I can't call these a drivers. To use You still have to understand hardware completely, but additionally You have to translate LL names to register names and the other way around. So it's the same register level coding but with DECREASED efficiency.
  • LL "full" and the old SPL - usable to some extent, but not really high level abstraction. Can configure peripherals, but for actual work still requires LL base or register level code.
  • HAL - high level abstraction, but of very bad architecture and quality. For example interrupt callbacks are implemented as "per event type" instead of "per peripheral instance". It separates and duplicates code for one instance events and merges code for different instances - exactly the opposite of what is typically needed. And it's totally flawed - no interrupt safety, missing memory barriers, cache management, full of other bugs and bloated.
  • Platform level thread safe layer - there is none.
  • Middleware - integration code is as bad as HAL.
  • Examples - also as bad as HAL.

My approach is to use ST's peripheral register definitions and write all the code by myself. I write my own high level drivers and additional platform level interfaces for peripherals, which are used similarly everywhere - for example USART, I2C, SPI, ETH. But I do not write any generic drivers at all for peripherals, usage of which are highly specific to particular project - for example TIM, ADC, DAC.

MikeDB
Lead

I'll add :

You will need to run these programs on some hardware. STM have a huge range of processors (google ST MCU Finder if you don't know that) and there probably isn't a development board for the exact processor you want to use. But there are quite a few ST and lots of third party boards so choose one with a similar processor so that you can get some code running quickly so that you are sure the processor you think you need is up to the task.

Totally agree on your comments on HAL - everything is upside-down/inside-out.

Maybe you and others should consider putting some of your high level drivers on Github as absolutely unsupported example code so as to give people a leg up rather than having to go through the pain of finding our for themselves how messed up HAL is.

The difficulty in posting alternative code to HAL/Cube is this is almost always commercial development. It's owned by the employer, not open source. Hundreds of thousands if not millions of dollars are invested in developing firmware to give the sponsor a competitive edge.

My preference is the old SPL as the basis for an abstraction layer. It covers the basics, and does make it easier to move among ST families. True, ST has dropped support for new processors, but it isn't that difficult to build a new SPL with the same APIs as older ones. I have a working SPL for the L0 and L4 families that allows me to easily refactor code when moving from the older L1, F1 and F4 based applications to newer ones. I expect there will be an L5 SPL in my future as ST rolls out M33 cores.

Don't ask, I don't own the code and can't release it. Copyright issues with ST would be too complicated in any case. If ST were to create an open source SPL with a GPL license it would go a long way toward providing a viable alternative to HAL. For that reason I don't ever expect ST to do it.

It's one thing to answer specific questions on a forum, quite another to release an entire company development framework that's ten years in the making. Posting drivers isn't useful without the entire support structure that goes with it. The HAL is a good example...complain about how obscure the example drivers are, but someone else's code is going to be just as obtuse without the documentation and examples to back it up. The request in another post for code to run the LCD on the 'L476 eval board isn't just about building a segment driver. It also needs the fonts and a minimal graphics library to handle drawing text.

In a way ST is performing a real service to the community with the HAL and Cube. It's a prime example of the old cliche that free software is worth every penny you pay for it. I'd like nothing better than for someone else to post the clean, tested and maintainable code I need for my projects, along with guaranteeing the 15 years of support it will require. Until then I'll rely on sitting in front of an IDE, JTAG and scope all day long.

I hope ST will continue to pour resources into a project too big to fail. I may be the lone voice in support of ST here, but I hope my competitors fully embrace using the Cube and integrate as much as possible into their products. I encourage them to put their trust in ST software, the newer the better, and push that new device into production as fast as possible. After all, you can always fix the bugs in the next release...

Jack Peacock