STM32F4xx HAL Drivers - Page 1
Forum section: electronics / general

author: DeanA
author_rank: Regular Contributor
timestamp: July 19, 2014, 04:42:59 am
content: Hi All,I'm a first time user of ARM microcontrollers, but have used plenty of 8 bit micros programming in C.I've got the STM32F4 Discovery board and I've been trying to get my head around the STM32F4xx HAL drivers from the STM32cube. So far it is very confusing for me.My question is should I persevere trying to learn this HAL driver? Will it make my life easier in the long run? Should I just dump it and do things the way I've been comfortable with on the 8 bit micros, basically writing to the control registers directly. To me this seems much clearer than trying to decipher what these HAL functions are doing and how to use them.Regards,Dean.

author: AndyC_772
author_rank: Super Contributor
timestamp: July 19, 2014, 07:21:53 am
content: Funny you should ask, I've been doing much the same myself with an STM32F2 device this week.STM32Cube is new, and I think the graphical assistance to work out which functions can go on which pins is useful, no question there. As a tool to help design a schematic and ensure that any conflicts between pin functions can be resolved, it's definitely handy.I also like the fact that it will spit out everything you need to get a project started, with a lot of the essential device configuration already done: clock sources defined, PLL multipliers set, caches enabled and so on. For this reason if nothing else, I do think it's worth building your first design based on the main.c which STM32cube produces.That said, I renamed ST's main() function, removed the user code from it, and put it into a separate file. That way I'm not putting a lot of effort into modifying an auto-generated file that might get lost if I need to regenerate it to update something. I created my own main() which calls ST's function at the start.So far so good, but I also struggled to get to grips with all the HAL_* functions that configure the peripherals. If there's a proper manual then I didn't find it, only a rather cryptic reference guide listing the functions and their parameters, but offering no real description of how to use them. Stepping through the code, I also found a lot of bloat and overhead that's just not needed in my application.There's example code available too - confusingly also included as "part of STM32cube" even though it's a separate download from the GUI software and only really shares a name. But this code is a set of stand-alone examples for each peripheral, and if there isn't one that happens to set up the hardware as you want it, it's a game of guess-the-function all over again.It wasn't until I decided to start poking the hardware directly that I really started to get to grips with the device and make progress. The STM32's peripherals are complex and capable, and although the reference manual is (in many places) desperately in need of a re-write, at least all the information is there. I found it much quicker, more intuitive, and ultimately clearer to simply set all the device registers, using the macros in the ST header files to identify the bits, than to try and work out what function call(s) were needed and what their parameters should be.For example: here's how I set up USART1 for a simple command line interface to a host PC:Code:__USART1_CLK_ENABLE();HAL_NVIC_SetPriority(USART1_IRQn, 0, 1);HAL_NVIC_EnableIRQ(USART1_IRQn);USART1->BRR = (32 << 4) | 9; // set 115200 baud. (60M / 16) / 115200 equals 32 + 9/16thsUSART1->CR2 = 0;USART1->CR3 = 0;USART1->CR1 = USART_CR1_UE | USART_CR1_RXNEIE | USART_CR1_TE | USART_CR1_RE; // enable transmitter, receiver and receive interruptsNote, I'm still using a couple of HAL function calls, where they're nice and simple and clearly do what's needed. There's no rule that says it's "all or nothing". I used the HAL to set up the GPIOs too. I may replace everything with direct hardware access at some point, if it feels worthwhile at the time.IMHO the purpose of the HAL should be to make accessing and using the underlying hardware easier and the resulting code more portable - but ST has failed on both counts...- lack of proper, clear documentation explaining how to use the supplied functions, and what they're doing, means using the HAL doesn't actually make it easier. It's more like an additional layer of obfuscation.- portability isn't really an issue between devices in the same family, as they share the same peripherals and reference manual anyway. I'll address the issue of portability between families if and when it becomes an issue, which I strongly suspect will be "never".- using the HAL is no guarantee of portability anyway. I spent a fair bit of time last year learning to use one of the smaller STM32s (a Cortex-M0 device), and the libraries that ST provided for that device aren't compatible with the ones they now supply.My advice? Start with STM32cube, base your code on what it produces, but don't feel compelled to use the HAL for the new code you add on top. And unless your application has time to waste every time a timer interrupt goes off, start by ditching ST's ISR.

author: dannyf
author_rank: Super Contributor
timestamp: July 19, 2014, 10:41:07 am
content: Your questions are quite personal, thus my answers are not necessarily applicable to you.generally speaking, middleware, including the cube, is the way to go to program those chips, for portability, reliability and development speed. Freescales PE and Keils RTE are two good examples of that.they don't offer the best execution. That, however, can be mitigated with a user layer from you. For example, I develop all of my code based on my own peripheral routines. Initially, those routines were coded through the standard peripheral libraries. Over time, sine of them have been replaced by new routines using registers. This approach has the best of both worlds.as to cube, I think it is a good start but at this point, it is not usable: limited support for chips, peripherals, and functionality. Dumping the generated code into main basically renders it unusable.I would stay with the standard peripheral library for now but code it through a layer so your code can remain intact should you decide to go with direct register access, the cube or other 3rd party tools.hope it helps.

author: DeanA
author_rank: Regular Contributor
timestamp: July 19, 2014, 11:15:19 pm
content: Quote from: AndyC_772 on July 19, 2014, 07:21:53 amThanks, it's good to hear I'm not aloneQuote from: AndyC_772 on July 19, 2014, 07:21:53 amI've used the STM32Cube graphical tool to help me work out which pins SPI and timer outputs are on but have not tried the code it generates, I think I'll check this out next.Quote from: AndyC_772 on July 19, 2014, 07:21:53 amThat's where I'm struggling, trying to get my head around how to use the HAL functions.Quote from: AndyC_772 on July 19, 2014, 07:21:53 amGreat, that's exactly the path I was considering taking next.Quote from: AndyC_772 on July 19, 2014, 07:21:53 amThanks so much, you've confirmed exactly what I was thinking, perhaps now I can finally start making some progressRegards,Dean.

author: Dago
author_rank: Frequent Contributor
timestamp: July 20, 2014, 08:02:18 am
content: So far my experience with STM32 headers/wrappers (haven't tried the cube) are pretty... crappy. For learning I personally decided to rewrite all the header stuff and write my own code which has been a really good learning experience.I wouldn't re-invent the wheel if this was for a work project or something but for learning it has been a good choice. You really start understanding how the controller works pretty fast. Peddling around with someone else code and trying to figure out in what order your supposed call poorly documented functions doesn't teach you much.