Programming with CubeMx and using direct registers for this project[STM32] - Page 1
Forum section: electronics / general

author: XaviPacheco
author_rank: Regular Contributor
timestamp: August 17, 2018, 12:11:19 am
content: I do not want to start a flame war about programming with CubeMx vs programming with crude registers as this topic has been widely discussed around the web with different kind of opinions. Now, I have interacted more with CubeMx as it is more friendly from a visual point of view. However, I haven't developed large projects using this microcontroller. I'm about to start a more complex project, so I do not know if I can effectively achieve everything with CubeMx, or if I have to spend more time learning how to program with registers.I want to develop a project using a STM32 nucleo board which mainly should:- Output a PWM signal @10kHz- Receive serial data from a Rapsberry Pi using UART and make decisions according to that data. One of those decisions is to vary the duty cycle of the PWM signal. I plan to receive the data using interrupts.- Read a speed sensor (reed switch (a pulse per rev) or Slot Type Optocoupler Speed Sensor (several pulses per rev)- Read a current sensor via SPI- Read an analog signal (use of ADC) and make decisions about it.- Other minors functions using GPIOs (drive small signal transistors as switches)I'm not describing the whole project and algorithms, just the main idea. Is everything well achievable with CubeMx? is FreeRTOS recommended for this project?I will start building the algorithms by myself using CubeMx to personally see what I can accomplish.I just want to hear your suggestions.

author: JS
author_rank: Frequent Contributor
timestamp: August 17, 2018, 06:57:15 am
content: I would use cube for initial states and then after the program start tweak the registers as I need. Cube gives a great starting point to get three project up and running in no time. Then you are on yuppie own, and tweaking the cube file after you started with your program starts to be messy at the very least.As you need to share the time between a lot of tasks a RTOS seems like a good idea, of course FreeRTOS is the obvious choice while using cube. The main reason not to use it is if you can't afford the memory it needs or your application wouldn't benefit from it at all, but a blinking led would benefit from a rtos over the wait or delay function example.In your case you need to keep up with the encoder (that's hardware, a counter forest everything and you check every once in a while) the serial port (as well, you doo have hardware for it). The frequency output, also HW driven. Etc. But on top off that you are likely doing some actual computing, if all is way too simple you can get away without the rtos, if you need too much efficency and get the absolute most of the uC you probably need to keep the rtos out. Any case in between the rtos should worth to use.JS

author: Dubbie
author_rank: Unknown
timestamp: August 17, 2018, 08:08:44 am
content: You can use cube to set up timers to deal with the speed sensor and the pwm. That should mean that you aren’t really left with any timing critical code, so you won’t have to be too “clever” to get it all working reliably.

author: genericpurpleturtle
author_rank: Contributor
timestamp: August 17, 2018, 11:52:51 am
content: At my work I use STM32 microcontrollers and I'm pretty much not allowed to use direct register manipulation. I'm supposed to use the STMCube and HAL high lever drivers for the peripherals. Not the most intuitive as at my prior work I programmed PICs with direct register manipulation but I haven't encountered anything I can't do without them and the ST I'm working with has a lot more registers which need setting up than the PIC so probably has saved time.The most helpful documents for how to use the HAL drivers are the comments in the .c files for the drivers themselves. The drivers come with a .chm file manual which you can search through. And if you search for a specific keyword, such as "timer", you should find the .c file which implements the HAL driver for that peripheral and the comments should give you a good idea how to use it.I've used the GPIO, SPI, UART, I2C and TIMER ones and got em all working. Little tip with the SPI and uart, always check the status of the peripheral before invoking the another function call with hal_spi_getstate. I was using the standard "blocking" (non interrupt and non DMA) SPI transmit and then trying to call a receive having thought that it would move onto the receive only after finishing with the transmitting. It does not.Also for the timer, if nothing is working try calling the HAl function to start the timer HAL_TIM_Base_Start() (there's also an interrupt version I believe.Those took my longer than they should have done to work out haha.

author: newbrain
author_rank: Super Contributor
timestamp: August 17, 2018, 01:40:08 pm
content: The suggestion of JS is quite good: use CubeMX for the initialization code, but then you can go commando.Still exploiting CubeMX (Cube is just the library set), there's a third option: use the LL libraries.They are just a thin veneer over the direct register access, but they have the following advantages:They are size-wise and speed-wise efficient, as the implementation is for the most part static inline functions (no call overhead)CubeMX can still generate initialization codeWith a competent IDE it's easy to see the possible values to be provided, as they share prefixThey can be mixed with the HAL, peripheral by peripheral (just choose in the CUbeMx) and, with care, inside the same peripheral.Of course, with the LL libraries you must have a deeper knowledge of how the peripherals work.BTW, the latest HAL is also using the LL internally, rather than direct register manipulation.A further note: the UART handling in the HAL is horrible, very inefficient and mostly pointless (large overhead for little gain in abstraction or ease of use), I'd suggest to roll your own based on LL or direct access.To get a taste for the LL, have a look at [...]\STM32Cube_FW_L4_V1.12.0\Projects\NUCLEO-L476RG\Examples_LL directory.

author: JS
author_rank: Frequent Contributor
timestamp: August 17, 2018, 01:47:50 pm
content: HAL libraries naming convention is so ridiculously ong that code end up being loong and hard to read. Then there are so many functions that you will (and should) expend a good time searching for the right function to do what you want, as you probably find some other that works but there is a simpler one hiding there.FreeRTOS does take some of that away, like when you need long timers you can use software timers and it's easier to make the uC do other stuff while it waits.I'm not the best coder, most of what I've done is in embedded using different platforms. It took me a long time to get confortable around HAL, then some more to get confortable around FreeRTOS, longer than I'd like, but once you get the idea it's a pretty smooth path and you can get into what you need. I would suggest you to build a code or two for each peripherical you need doing the things you will need them to do and test it, then you have your own reference for it. Debugging a full code gets trickier. My experience with NXP is much worse, with Atmel was pretty smooth transition thanks to arduino as you can easily build up code transitioning to bare metal programming as they call it sp you can get what you can't with the so limited enviroment for hobbyists.FreeRTOS does have two useful manuals of about 400 pages each, do a quick read of the mastering FreeRTOS and then keep the instructions one handy to reference at any point.JS

author: genericpurpleturtle
author_rank: Contributor
timestamp: August 17, 2018, 02:27:07 pm
content: Quote from: JS on August 17, 2018, 01:47:50 pmThe HAL library could definitely be better and less esoteric, but as with all things, once you have an idea of how to use it and where to look for things its okay. I'm sure learning all the registers would present its own set of difficulties and pains.

author: XaviPacheco
author_rank: Regular Contributor
timestamp: August 17, 2018, 02:29:47 pm
content: Thanks for your comments. I like the idea of generating the initialization code with Cube, and that's what I'll actually do. However, I'm not a good coder to be honest, always been more hardware oriented. For that reason, I think that developing effective routines would take me a long time. I have two months (it's relative) to make this project work, or at least do something reasonable.What I'll do first is to try each peripheric individually and then build an algorithm to join all them together according to the purpose of the application. There's a book called "Mastering STM32" which I consider a good starting point.

author: andyturk
author_rank: Frequent Contributor
timestamp: August 17, 2018, 04:00:26 pm
content: Quote from: genericpurpleturtle on August 17, 2018, 11:52:51 amHow does the "not allowed to use" work in your job? Do others review your code and prefer HAL based code? I'm just curious, since sometimes (I think) you have to touch registers directly.

author: JS
author_rank: Frequent Contributor
timestamp: August 17, 2018, 04:10:25 pm
content: Quote from: genericpurpleturtle on August 17, 2018, 02:27:07 pmI'm not suggesting to mock around poking registers directly, HAL or LL are fine, I do use HAL most of the time but getting used to it is quite time consuming. With a month or so to go will depend how much daily time he has to get it right. It took me a week or so but a week with too much time in my hands knowing I was going to need all that soon and in a hurry so I got to play around prior to having the death line or the specs st hand to start working on it.In any case, even working with HAL, init is quite extense so I recommend cube at least for a general setup... Then searching for the right functions is where most time should probably go. Once you get them the code should be pretty straight forward (application dependant) but we don't know much about it. Usually the real time restrictions and precission of opperation involved is what makes or breaks the simplicity of what was described.If you are a good HW developer having the interface prototype to the real world to test with a break our board should help quite a bit. A good programer might mock up a code to start messing around with HW after and test things the other way around. I usually do HW first as I'm more HW oriented as well, then a mock up code to test the HW interfacing and finally the final code to go with it. Also, HW delays as waiting for PCB or parts makes the waiting a good time to code.JS

author: Koen
author_rank: Frequent Contributor
timestamp: August 17, 2018, 04:18:10 pm
content: Have a look at ChibiOS's HAL. It's easy, clear, clean.

author: genericpurpleturtle
author_rank: Contributor
timestamp: August 20, 2018, 05:27:23 pm
content: Quote from: andyturk on August 17, 2018, 04:00:26 pmI work for a tiny company, just 2 of us writing the software, myself and my manager who infrequently looks over my code. If I'd try to write something directly manipulating registers I'd be told to do it again using the HAL functions.

author: Siwastaja
author_rank: Super Contributor
timestamp: August 22, 2018, 04:50:53 pm
content: Quote from: genericpurpleturtle on August 20, 2018, 05:27:23 pmFYI, sooner or later youwillencounter the situation that you simply cannot get a working solution by only using the "HAL functions" - some are simply completely broken, some are slightly buggy and require workarounds, some are too slow due to bloat and cannot be used in, for example, interrupt services. And some just are not flexible enough as-is to provide the features the chip datasheet advertised.When you hit this scenario, you have the following options (I've seen exactly this):1) Just make the code work and pretend you have followed the insane rules,1a) If your boss finds out and is sensible, they'll pretend you followed the rules as well,1b) If your boss finds out but isn't sensible, see 32) Change the product specification, for example, remove a feature you cannot implement,3) The company goes under due to impossibility to deliver. You resign, or get fired. Yes, incompetent middle management or micromanagement, or insisting to arbitrary rules, canreallykill a corporation. A small company, even more easily.Or, hopefully:4) Everyone's sensible, and the insane rule stops being in existence. Everyone laughs at their stupidity together, and life goes on.There's a yucky middle-ground, however, where everything kind-of works, never leading to a full-blown crisis, but such arbitrary rule becomes a productivity issue, causing timelines to strech and people to get stressed.Depending on the viewpoint, all this is either called a "style guide", or "micromanaging". In any case, it's alarming to see such a corporate style guide in a company of two (IMHO).