Skip to main content
brokenkeyboard
Associate II
March 22, 2020
Solved

General questions on STM32CubeIDE

  • March 22, 2020
  • 5 replies
  • 5640 views

Hello,

(Hobbyist there) A few years ago I tried to develop on STM32 microcontrollers (the so called 'blue pill' to be exact) but the toolchain installation and the whole code generating process made me give up (also there wasn't full linux support if I'm not wrong, up to this day I still can't find official linux drivers for the ST-link). Fortunaly ST released the STM32CubeIDE which encompasses everything, making things a lot more easier for beginners.

But after a few days of testing with the software and consulting documentations, I have a few questions and things I fail to achieve:

1) When creating an STM32Project, I can choose between C and C++, but I don't see the difference between the two. At the end I just have a bunch of .h/c files and no .cpp files whatsoever (and especially no main.cpp). What does this mean ? Do I have to manually create .cpp and .h files in the Src and Inc folders, and must I copy the content of main.c in my own main.cpp ? How to tell the software to compile using these files ? And by the way where should I put C/C++ libraries and how to tell the compiler to use them ?

2) I don't quite understand the CMSIS libraries. From what I understood they mainly contain registers define and very little functions, and must be used with the documentation of the ARM processor in hand. But I didn't understand if it was truly ARM or ST who published those libraries for ST MCUs (for example I read that it was indeed released by ARM but also read things like 'STM32 CMSIS-compliant libraries'). Also do the HAL and/or LL libraries rely on the CMSIS to work ? If not what are the differences of LL libraries and CMSIS libraries ? And do the HAL libraries rely on the LL libraries to work ?

3) And I understood that HAL libraries/drivers provide an abstraction layer and are more or less microncontroller-independant, unlike the LL libraires who provides a sometimes crucial hands-on control (controlling registers bits, etc.). But I'm confused on how to use them. I found the advanced settings option to switch between HAL and LL drivers for each peripheral, but I don't understand exactly what the 'Generated Function calls' option do. When all drivers are HAL selected, none of the .._ll_...c/h files are present in the project directory tree and the _hal_..c/h files corresponding to the peripherals selected are here, but also some that I didn't select when generating the project (like i2c) while others (that I also didn't select) are not there (like _hal_adc); and when selecting one driver as LL, GPIO for instance, the ..._ll_gpio.h/c appears, but also a bunch of others LL .c/h files, and others stay hidden. Why is that ? And does this mean that selecting the LL driver means using the LL driver and/or the HAL driver while selecting the HAL driver means using only the HAL driver ? Can I initialize the peripherals using the HAL driver and then use the LL driver as long as I know what I'm doing ? Can I only call files that are visually present in the project directory tree ?

4) And finally, when building the project (using the 'hammer' icon), I can choose between building for the release or for debug (btw I know I can (un)comment the #define USE_FULL_ASSERT for debugging the functions parameters ) but for uploading the code I only found the debug option. How can I just build in release mode (once the project is completed) and upload it ? Online I found people advising to use a special configuration for debug, but I thought it to be absurd and there had to be an option to just upload the compiled code.

Thanks in advance for your replies.

This topic has been closed for replies.
Best answer by KnarfB

Hi,

> 1) When creating an STM32Project, I can choose between C and C++ ...

> Do I have to manually create .cpp and .h files in the Src and Inc folders

Yes. I would not copy the stuff because C code will be re-generated when you are changing the device configuration. If you really want C++, write your own code in separate files and call your C++ entry point from the generated main().

> 2) I don't quite understand the CMSIS libraries.

Look at the licensing terms in each file. There are files from ARM for the cores and files from ST under Device. I bet (better: hope) these files were generated from some internal hardware description. They are the lowest level and correspond (somehow) to the .svd files used by the debugger for showing peripheral register values.

> Also do the HAL and/or LL libraries rely on the CMSIS to work ?

Yes. A typical HAL struct is UART_HandleTypeDef defined in stm32f0xx_hal_uart.h (for STM32F0). Its first member "Instance" is a CMSIS struct USART_TypeDef.

> And do the HAL libraries rely on the LL libraries to work ?

No, they are independent of each other.

> 3.

For all types of peripherals that you activate in the device configuration there should be a pair of hal .[ch] files generated. sometimes there are extra ex files and some files may be generated as dependencies of others. Only all those can be used.

4) And finally, when building the project

In the latest STM32CubeIDE (Version: 1.3.0) the green play button icon (menu: run) should do what you want.

5 replies

KnarfB
KnarfBAnswer
Super User
March 22, 2020

Hi,

> 1) When creating an STM32Project, I can choose between C and C++ ...

> Do I have to manually create .cpp and .h files in the Src and Inc folders

Yes. I would not copy the stuff because C code will be re-generated when you are changing the device configuration. If you really want C++, write your own code in separate files and call your C++ entry point from the generated main().

> 2) I don't quite understand the CMSIS libraries.

Look at the licensing terms in each file. There are files from ARM for the cores and files from ST under Device. I bet (better: hope) these files were generated from some internal hardware description. They are the lowest level and correspond (somehow) to the .svd files used by the debugger for showing peripheral register values.

> Also do the HAL and/or LL libraries rely on the CMSIS to work ?

Yes. A typical HAL struct is UART_HandleTypeDef defined in stm32f0xx_hal_uart.h (for STM32F0). Its first member "Instance" is a CMSIS struct USART_TypeDef.

> And do the HAL libraries rely on the LL libraries to work ?

No, they are independent of each other.

> 3.

For all types of peripherals that you activate in the device configuration there should be a pair of hal .[ch] files generated. sometimes there are extra ex files and some files may be generated as dependencies of others. Only all those can be used.

4) And finally, when building the project

In the latest STM32CubeIDE (Version: 1.3.0) the green play button icon (menu: run) should do what you want.

brokenkeyboard
Associate II
March 23, 2020

Hello,

Thanks for your answer, it is greatly appreciated. Things are a bit clearer now. I checked my software version and it happened to be the 1.12 (this is where having repositories for the software would have come handy, moreover there isn't even some automated update availability check), so I manually downloaded the newest version from ST's website (but instead of upgrading the old one I now have two versions of the software...) and reopened my project, the button is now there and I can happily use it. Just to be curious was there an option to show/hide it in 1.12 or was it just missing ?

And just to be sure, when creating my .cpp/h files and/or including C/C++ libraries I do not need to instruct the compiler anything as long as I put them in the Src and Inc folders (but is it advised to put the libraries here ?)

I'm still puzzled as to why the i2c lib (for example) is required when not using any communication protocol but I guess I won't push the investigation any further for the moment. And if the LL and HAL libraries aren't interconnected why do I still see the _hal_gpio.c/h files when using LL for the GPIO drivers ? Is it because ST expects people who want a hands-on to still require some HAL functions (like initialization) ?

And finally do you know where I can find documention on CMSIS libraries and .svd files ? I already found the relatively well hidden ..._User_Manual.chm (by the way if there are people working on ST who pass by there I'd like to point out that when opening those files they pretend to only document HAL drivers while describing HAL and LL drivers in reality, and the .chm format is kind of out-dated an is not exactly natively supported under Linux) and I suppose I must refer to the complete datasheet of the STM32 MCU I'm using to check the registers functionning, but is there some kind of general documentation as to how it works (globally) ?

Thanks for your patience.

brokenkeyboard
Associate II
March 24, 2020

EDIT: I've found the file 'STM32CubeF1GettingStarted.pdf' in the 'documentation' folder in the folder from the STM32 firmware library (.zip) that was automatically downloaded by STM32CubeIDE when creating my first project that uses this MCU family. It's quite well explained, and answers some of the questions I asked. But strangely It's not on ST's web page of the MCU I use, and contain many informations that are nowhere to be find on ST's web page for CubeIDE.

I wish I found this file earlier, which is kind of hidden when you didn't downloaded the .zip firmware package manually and would be helpful for other beginners starting with CubeIDE.

TDK
Super User
March 23, 2020

> And just to be sure, when creating my .cpp/h files and/or including C/C++ libraries I do not need to instruct the compiler anything as long as I put them in the Src and Inc folders (but is it advised to put the libraries here ?)

You're free to create whatever project structure you want, but including your own files in the Src/Inc is an acceptable and common approach.

> I'm still puzzled as to why the i2c lib (for example) is required when not using any communication protocol but I guess I won't push the investigation any further for the moment.

I2C files are only needed if you're calling them or trying to compile them. Not sure what you're seeing.

> And if the LL and HAL libraries aren't interconnected why do I still see the _hal_gpio.c/h files when using LL for the GPIO drivers ? Is it because ST expects people who want a hands-on to still require some HAL functions (like initialization) ?

Some HAL functions need the LL library, while others do not. Regardless, if you're using CubeMX, the necessary HAL/LL files will be copied to the directory when you generate code.

The best reference for the HAL functions is within the source file themselves. Some things change over time. For example, at the top of "stm32h7xx_hal_adc.c" it tells you everything you need to call in order to use the ADC.

"If you feel a post has answered your question, please click ""Accept as Solution""."
brokenkeyboard
Associate II
March 23, 2020

Hello and thanks for your answer,

About the i2c library, In the project generation with CubeMX (which is included in CubeIDE) I only activated the GPIO (with LL), NVIC and SYS (default) peripherals (see attachment). So according to KnarfB's answer I should only have the .c/h files drivers corresponding to those three peripherals (+ dependencies), but I have some drivers in the directory tree which I find hard to believe are required like I2c lib, see attachment (but maybe they are actually required for non-obvious reasons so I should do a deep check of the libraries).

When you said regardless you mean that wether or not the HAL GPIO library (for instance) needs the LL GPIO library CubeMX will copy both of them anyway ?

0693W000000UULnQAO.png0693W000000UULYQA4.png

TDK
Super User
March 23, 2020

Interesting. I don't have an explanation for why I2C is being brought in. Is HAL_I2C_MODULE_ENABLED defined in stm32f0xx_hal_conf.h? Just curious. There are bugs in CubeMX so I wouldn't spend a lot of time on it. Or, as you said, maybe there are non-obvious reasons for why they're included. You could delete the file and see if you get compiler/linker errors.

> When you said regardless you mean that wether or not the HAL GPIO library (for instance) needs the LL GPIO library CubeMX will copy both of them anyway ?

What I meant was that CubeMX will only bring in what's necessary. For example in your code, it doesn't bring in the LL TIM library because the HAL TIM library doesn't need it.

"If you feel a post has answered your question, please click ""Accept as Solution""."
Piranha
Principal III
March 23, 2020

> And finally do you know where I can find documention on CMSIS libraries and .svd files ?

What documentation do you need for them? They just define registers and bits, which are documented in reference manual. If you mean CPU core register documentation, then those are defined in a programming manual. And for some not so often required things you have to search for ARM's Technical Reference Manual.

> is there some kind of general documentation as to how it works (globally) ?

Application notes. For example AN4013 and AN4776 for timers.

brokenkeyboard
Associate II
March 23, 2020

Thanks for your answer,

I'll try to find those.

KnarfB
Super User
March 23, 2020

> I still can't upload my code if I don't enable the debug serial wire when creating the project with CubeMX

The MCU will be flashed through that interface, so you should enable it. You would only disable it if you need those pads for other functions or for security reasons. Thats possible, but requires extra effort.

brokenkeyboard
Associate II
March 24, 2020

Sorry I didn't see your answer, but during the day I noticed that actually in the CubeMX part of the CubeIDE software (where I generate the project, the .ioc file) I can disable the serial wire and free the 2 pins, and upload the code using the 'run' button...

But I need to reset the board (I'm using a 'blue pill' board) with the reset switch (or by unplugging the STLink) before every upload and pull the BOOT0 high with the headers; or else I get a ' No device found on target' error.

However I'm confused because in the console I read this line when uploading: 'SWD Debug  : Enabled', despite using no-debug in the .ioc file for the project and selecting the 'Release' version when creating/selecting the run configuration. Is it something I shouldn't be bothered with or is the 'debug' version of my code sent to the board ? If so, how can I actually send the 'release' version ?

And by the way why when creating a run configuration, 2 files are generated which only differ by 'shared file' (in 'common'), why is that ?

KnarfB
Super User
March 24, 2020

The SWD debug pins are "hard" configured in SWD mode during a hardware reset of the MCU regardless of what you are "soft" configuring in Cube. If not configured as SWD in cube, the firmware will override the reset configuration of the chip soon after reset by your "soft" configuration. Therefore, in that case, debugging only works with a hardware reset (NRST pin).

If SWD is "soft" configured, a reset... can be soft triggerd from the debugger without using the NRST signal.

There is a nice app note: AN4989 "STM32 microcontroller debug toolbox"

Unfortunately those app notes are hard to find :persevering_face:

KnarfB
Super User
March 24, 2020

In the video you mentioned, at 2:11 is show how to manage a Debug or Run configuration. In STM32CubeIDE there is a black drop-down triangle next to the icons for that or use the "Configurrion..." menu entries in the Run menu. In that Run/Debug configuration dialog, you can check/enter/change the .elf file to be used.

brokenkeyboard
Associate II
March 24, 2020

Well I did mention finding this menu, but I'll take this as a confirmation that I'm indeed uploading the 'release' version. But I still don't understand why I see the 'SWD Debug  : Enabled' line in the console when uploading and why in the 'debugger' part of the 'run configuration' menu I still see a bunch of debugger features that can't be disabled.

KnarfB
Super User
March 24, 2020

Uploading==Programming==Flashing is done with the same tools and is the first step of debugging. Both can share the same .launch file. A difference is in the Startup tab where in Run most things are grayed out, because Run doesn't halt the core at the main breakpoint.