STM32 hardware drivers - Page 1
Forum section: electronics / general

author: geot51
author_rank: Newbie
timestamp: April 29, 2017, 06:24:01 pm
content: Having spent more than 3 years on ATMEL's AVR, Cortex-M3 and Cortex-M4 MCUs I decided to move on STMicroelectronics' STM32 MCU and take a taste of theirs Cortex-M4 part.I choosed the STM32F410RB and I bought a Nucleo dev board and I started to learn some things around STM's drivers.I downloaded SW4STM32 and installed the STM32CubeMX as addon.I spent many hours reading between the lines and I have to say that I find the whole library too much frustrating with hardly any pattern on it. And of course too hard to use especially for a beginner like me. On the contrary, ATMEL's ASF is many light years ahead. Customizable like a hell, very easy in use and completely understanding throught the hundreds examples providing by ATMEL.Now I'm looking for a third party library with hardware drivers to begin with.It doesn't bother me to go deeper in the functions and write some lines for direct access to registers. I'm used to do this on Atmel Studio 7.0 and I really enjoy it.I managed to enable the STM32F410RB USART2 and write my own RX TX functions with direct access to registers because I found Cube's libraries a mess.But I'd like to have a little support from a library.Any suggestions?

author: Jeroen3
author_rank: Super Contributor
timestamp: April 29, 2017, 08:13:39 pm
content: ST is working on a minimalistic version of their HAL. I believe they call it LL drivers (low level).There is a topic on ST's messy HAL here already, so discussing that is of no point.You could also use the "standard peripheral library", but they have discontinued support for it.About HAL.

author: Sal Ammoniac
author_rank: Super Contributor
timestamp: April 29, 2017, 10:01:49 pm
content: I've always found it better to write my own hardware peripheral drivers rather than rely on the overly complex and often buggy vendor libraries.

author: julian1
author_rank: Frequent Contributor
timestamp: April 29, 2017, 10:14:45 pm
content: I've been playing with libopencm3, porting some of the examples to a new board. So far, I like it and it seems pretty lightweight.https://github.com/libopencm3/libopencm3-examples/tree/master/examples/stm32/f4I chose it, after Googling and finding a lot of opinions suggesting the ST options were not optimal. libopencm3 avoids auto-generated code which I know from experience can be difficult to maintain and update, and creates tooling dependencies. It also avoids trying to abstract over hardware differences - something that sounds nice in theory - but is an additional source of complexity for debugging (eg is this bug my code, the middle layer code, or a hardware issue). With that said I have not personally tried alternatives like Cube or SPL.https://www.eevblog.com/forum/microcontrollers/experiences-with-different-arms/

author: geot51
author_rank: Newbie
timestamp: April 30, 2017, 12:29:05 am
content: I was thinking that it would be nice to be built a new framework similar to Atmel's Software Framework.Easy in use and oriented for special mcu at a time, rather than a generic unity.USART is one of the most common peripheral in the microcontrollers' world. It is a pitty to see so much useless code hidden in the HAL_UART_Transmit() function.I still can't understand why...

author: NorthGuy
author_rank: Super Contributor
timestamp: April 30, 2017, 02:55:56 am
content: Quote from: Jeroen3 on April 29, 2017, 08:13:39 pmThat's exact the story with Microchip Harmony (their HAL for 32-bit PICs).Although they bought Atmel, so things may change.

author: westfw
author_rank: Super Contributor
timestamp: April 30, 2017, 05:52:52 am
content: I apparently have had much worse experiences with Atmel ASF than you have :-(I haven't tried to use it much, but my brief experiences were bad: 700+ bytes to initialize the clock, and fractional BRG code for the USART that just doesn't work...

author: geot51
author_rank: Newbie
timestamp: April 30, 2017, 10:57:32 am
content: Quote from: westfw on April 30, 2017, 05:52:52 amI haven't seen any other framework much easier and usefull like Atmel's ASF.I do admit that it seems a little different and difficult to beginners but, in contrast to ST's HAL, it does have a pattern.It's got some bugs, I recently discovery 2-3, but it's very strong though.Despite the difficulty, the main problem with ST's HAL doesn't lie in code's structure but in code's size.As I mentioned above they've put too much useless lines in simple functions.

author: thm_w
author_rank: Super Contributor
timestamp: May 01, 2017, 10:44:55 pm
content: Quote from: geot51 on April 30, 2017, 10:57:32 amYou have 128kB and this code is mainly for setup, is it really a big issue?Quote from: geot51 on April 30, 2017, 12:29:05 amBecause its generic code that is trying to cover many cases (rtos support, etc.). It handles some errors, state information, process locking and timeouts. Of course it can be written better but it does the job for basic projects.chibios supports f4 and has a HAL thats supposed to be simpler:www.chibios.org/dokuwiki/doku.php?id=chibios:product:hal:platformsOr maybe stick with atmel if its working for you.

author: aandrew
author_rank: Frequent Contributor
timestamp: May 02, 2017, 02:22:23 pm
content: Quote from: geot51 on April 30, 2017, 10:57:32 amI think you're worried about something that is inconsequential in the days of decent optimizing compilers. Many small functions don't bloat code nearly the same way they used to. The asserts can be compiled out, and what's left is actually not terrible, if not absolutely optimal.Honestly though, unless you're talking about a tight loop executed often the fact that it takes a half dozen more instructions doesn't matter in the slightest. Unless there's a clear need to do it, don't optimize.This is difficult for me to write, having grown up in the 1MHz 6510 days, cutting my teeth on early HC08 and PIC processors and writing careful x86 assembly language back when the NEC V20 was a screamer. I don't pine for those lost days, but I do kind of miss the internal competition to squeeze every last drop of performance out of a system. These days I focus on clean, easy to understand code and relish those little bits here and there that need the touch of the old ways. :-)

author: Jeroen3
author_rank: Super Contributor
timestamp: May 02, 2017, 04:22:58 pm
content: The so called modern optimized compiler is very reluctant in removing or inlining functions.You will be 3 stackframes deep toggling an IO. Complete waste.Don't rely on the magics of the compiler. You'll be in for a bad day if you ever decide to switch.Example:https://electronics.stackexchange.com/questions/301712/interrupt-latency-on-a-stm32f303-mcu

author: aandrew
author_rank: Frequent Contributor
timestamp: May 02, 2017, 05:02:49 pm
content: Again. Optimize where necessary. Avoid everywhere else.Do I care that I'm 3 stackframes deep to toggle a GPIO? 99% of the time, no, not at all. When I do, then I worry about it and instruct the compiler to be more aggressive.Just a quick test on a codebase I had handy: arm-none-eabi 6.2.1, with -Og, doesn't inline automatically and produces less than spectacular code (which is expected, since I told it I want to be able to debug without losing my mind). With -O3, all my HAL GPIO calls were inlined and the set/clear ones resolved to 3 thumb instructions each. The HAL_GPIO_Init() ones were a little goofier, ending up being about ten instructions each but this is harder to tease out since gcc is doing a good job of reordering and reusing values.Interestingly, with -Os, the GPIO functions are still inlined, presumably because they're small and it takes more space to set up/tear down a stack pointer and the call is also probably a far call since the codebase is about 200kB.First rule of optimization: don't optimize.Second rule of optimization: don't optimizeyet.

author: westfw
author_rank: Super Contributor
timestamp: May 03, 2017, 05:44:25 am
content: QuoteThe vendor libraries don't have "many small functions." they have honking huge functions that handle (for example) all the possible configuration options for the UART, including LIN and IRDA, both arithmetic and fraction BRGs, and so on, all un-carefully constructed in such a way that none of the code can be left out at compile time, even if the arguments to the init function are all constants in your code. :-(they're very enamored of the whole:Code:struct tc_config cfg; tc_get_config_defaults(&cfg); cfg.clock_source = GCLK_GENERATOR_5; cfg.clock_prescaler = TC_CLOCK_PRESCALER_DIV1; cfg.run_in_standby = false; cfg.counter_16_bit.compare_capture_channel = TIMER_PERIOD; tc_init(&tc_instance, TIMER, &cfg);style of code (that's an Atmel ASF example, BTW...)(search the forum archives here; there have been several extended discussions.)

author: Sal Ammoniac
author_rank: Super Contributor
timestamp: May 03, 2017, 04:03:23 pm
content: Quote from: aandrew on May 02, 2017, 02:22:23 pmReminds me of the quote attributed to a U.S. Senator: A billion here, a billion there, pretty soon, you're talking real money.

author: westfw
author_rank: Super Contributor
timestamp: May 03, 2017, 05:18:33 pm
content: It's somewhat true that the bloated libraries are relatively inconsequential on those 128k+ flash 80MHz CM3 microcontrollers that were "current" when the libraries were first written. But the vendors have moved on to CM0 "8bit replacement" chips with low prices, low pin counts, and smaller flash, and they are trying to use the same libraries. That the system clock initialization takes 700 bytes on a SAMD21xxx with 128k flash is OK (I guess.) That it still takes 700 bytes on a SAMD09 with 16k of flash is worrisome... (alas, the same problem shows up with libc; most "free" ARM compilers are using newlib, and even in "nano" form, it's quite large compared to what (for example) an avr-libc user might be used to.(ST hasSTM32F042 and such in the same category.)

author: DBecker
author_rank: Frequent Contributor
timestamp: May 04, 2017, 01:39:02 pm
content: Quote from: aandrew on May 02, 2017, 02:22:23 pmYou must not have looked at the generated code, or single-stepped while tracing excution. Pretty much every library call does a check that the passed-in peripheral is valid, and that the passed-in flag is valid for that specific peripheral. These aren't optimized out -- they end up in the compiled code. And since the libraries are designed to set a single flag at a time, the same checks are run multiple times for each register. It typically takes a dozen instructions or so to configure a peripheral in direct code. That same setup ends up as many hundreds of bytes in code size and thousands of executed instructions when using the library.

author: crispus
author_rank: Regular Contributor
timestamp: May 04, 2017, 01:52:56 pm
content: Quote from: thm_w on May 01, 2017, 10:44:55 pmFor ST microcontrollers, I use only ChibiOS HAL if even I don't use the OS itself. It's lighter, clearer and very easy to use (as any good HAL should be).

author: FreddyVictor
author_rank: Regular Contributor
timestamp: May 04, 2017, 02:08:30 pm
content: Quote from: DBecker on May 04, 2017, 01:39:02 pmAre you refering to the assert_param() functions in all the HAL functions ?My understanding of this is that when developing, you enable the USE_FULL_ASSERT #define in stm32fX_hal_conf.h filethis will indeed include all the parameter checks and will indeed slow down the codehowever, for production, just disable the #define and they will all be excluded (see bottom of hal_conf.h file):#define assert_param(expr) ((void)0)