Author Topic: STM32CubeIDE / CubeMX Workflow Tips and Tricks?  (Read 12189 times)

0 Members and 2 Guests are viewing this topic.

Offline randyyorkTopic starter

  • Newbie
  • Posts: 8
STM32CubeIDE / CubeMX Workflow Tips and Tricks?
« on: November 18, 2019, 05:31:00 pm »
Pardon the vague talking points. I was hoping to get some conversation going in hopes of picking up tips and tricks regarding how to efficiently use STM32CubeIDE with CubeMX integration. Things like managing workflow, keeping code clean, etc.

Growing pains / bugs / quirks aside, there doesn't seem to be a cohesive guide for how to actually use the ecosystem to go from "I have this ST part -> I need to get this peripheral up and running -> Here are the steps I need to do within the Cube environment". Are there any supporting documents that can explain what HAL code and Cube settings must be set to enable a particular operating configuration? It seems like this is something missing. For example, enabling the USB peripheral doesn't automatically (always) enable the USB OTG interrupt, and it seems anybody's guess why this has to be selected for certain parts and not for others.

In the past, before this integrated environment was available, I'd find myself meticulously avoiding the HAL layers and rewriting tight code following the device-specific programming manuals for each peripheral component. This worked well for personal projects, but this doesn't seem to be appropriate for production-ready designs where being able to switch to different parts and having multiple people understand code is beneficial. Given that peripherals are getting more complex, it makes sense to use HAL interfaces, but these seem to be half-baked. In the unhappy case of quirks that you stumble upon, you are SOL unless you can get a hold of support.

Another gripe that I'm facing is that the Cube-generated code is rather ugly. It is hard to fit everything in with existing coding standards, especially when trying to code within the templates / blocks that are predefined within the Cube environment.

In general, I'm wondering what the gurus are doing these days when using these parts outside of hobby projects...

Thanks!
 

Offline JohnnyBerg

  • Frequent Contributor
  • **
  • Posts: 474
  • Country: de
Re: STM32CubeIDE / CubeMX Workflow Tips and Tricks?
« Reply #1 on: November 18, 2019, 06:28:50 pm »
been there .. done that  ;D

Last week I went the same route. As you said, the generated code looks horrible. I did not like the project structure. Coding against HAL is difficult, and hard to port to a different controller. I did not manage simple read from the ADC.
Not up to my coding standards. The IDE is a remake of Atollic Studio and Eclipsed based. You have t be a fanboy for that. I don't like it.
The only thing I liked was the makefile.

Then I looked at mbed. I liked the coding, with a few line one can build something. I did not like the online IDE, the lack of a debugger and intellisense. The offline CLI is python, and very minimalistic. But the biggest deal-breaker is code size. The simplest program needs about 70kB flash, because of the linked RTOS. With a microcontroller having 16 or 32 kB flash a no go. mbed was out.

Next Arduino. I liked the coding, just as mbed. Code size is also ok. But the IDE has no intellisense, no debugger. Just like mbed, for small projects ok, but when you build something bigger, perhaps even in a team, it gets unworkable very fast.

I ended up with Visual Studio Code, the STM32Duino code base, and a toolchain. This has everything I wanted: intellisense, debugger, small code size, Makefile and everything very flexible and configurable.
I posted my skeleton on Github, for everyone to use and adapt.

My 2 cents ..
« Last Edit: November 18, 2019, 06:37:34 pm by JohnnyBerg »
 
The following users thanked this post: randyyork

Offline jhpadjustable

  • Frequent Contributor
  • **
  • Posts: 295
  • Country: us
  • Salt 'n' pepper beard
Re: STM32CubeIDE / CubeMX Workflow Tips and Tricks?
« Reply #2 on: November 18, 2019, 06:35:30 pm »
libopencm3 is fairly complete for many targets including several non-ST ones. If you want to switch targets, it's not much harder than switching under Cube. It's licensed under the LGPL, which effectively reduces to the MIT license as long as you don't modify the libopencm3 code itself. (EDIT: apparently not, you have to provide a link kit of some sort, like the old Unices.)

I'm in the process of porting an application out of HAL because their code generation did no favors for my cheerful disposition.
« Last Edit: November 18, 2019, 09:11:53 pm by jhpadjustable »
"There are more things in heaven and earth, Arduino, than are dreamt of in your philosophy."
 
The following users thanked this post: randyyork

Offline newbrain

  • Super Contributor
  • ***
  • Posts: 1844
  • Country: se
Re: STM32CubeIDE / CubeMX Workflow Tips and Tricks?
« Reply #3 on: November 18, 2019, 08:44:27 pm »
It's licensed under the LGPL, which effectively reduces to the MIT license as long as you don't modify the libopencm3 code itself.
Sorry, but this is just misleading.  :-//

For the embedded world, where libraries are almost exclusively statically linked, section 4 "Combined Works" apply.
In particular, check point d) 0).

There's no way this can be assimilated to the MIT license, even if the library is unmodified:
one has to convey what is needed to rebuild the application (objects, minimal sources and possibly tools/scripts) and link it with a different library version.

That said, parts of the HAL and "Middleware" from ST went from a very liberal, BSD/MIT-like license, to a liberal but ambiguously worded one: just choose your poison!  :blah:
Nandemo wa shiranai wa yo, shitteru koto dake.
 
The following users thanked this post: randyyork, jhpadjustable

Offline robint91

  • Contributor
  • Posts: 44
Re: STM32CubeIDE / CubeMX Workflow Tips and Tricks?
« Reply #4 on: November 18, 2019, 10:30:33 pm »
In all honest opninion the STM32 cube isn't that bad. Nordic has in my opinion a bad structure. My and yours time is precious. These microcontrollers are too big to solely rely on the ref manual. This is also true for the other manufacturers. We are trading flexibility with complexity.

I use mainly STM32's for my day job. A basic project start as follows, what does it need to, which external components do i need. Then starts the fun selecting a microcontroller. The cube tool is excellent for that. But most of the time i have an idea which family. Mainly F411, L45x, F746 or F071. Then you start pin planning , you give the pin aliasses  this will help in the software later. After that schematic, pcb. Maybe a few iterations on the pinplanning to optimize the routing. Build prototypes and generate software. A fairly painless experience in my honest opinion.

The cube configures the clock, uarts, timers, gpio,...
Basic stuff where I can't be bothered with looking it up in the datasheets. I just don't want to spend time reading basic stuff in the datasheets.  Cube is the perfect tool for that.
And for the more specialized stuff i will look into the datasheet. For example the hrtim, dfsdm,....
I would touch stm32duino and libopencm3 with a 1000m pole. LGPL and only being depended on the community is a problem when using the in commercial applications.

 
The following users thanked this post: samofab, randyyork, I wanted a rude username

Online thm_w

  • Super Contributor
  • ***
  • Posts: 8074
  • Country: ca
  • Non-expert
Re: STM32CubeIDE / CubeMX Workflow Tips and Tricks?
« Reply #5 on: November 19, 2019, 12:16:25 am »
Last week I went the same route. As you said, the generated code looks horrible. I did not like the project structure. Coding against HAL is difficult, and hard to port to a different controller. I did not manage simple read from the ADC.

Did you use the option "Generate a pair of .c/.h files per peripheral"?
That cleans up a lot of the mess and keeps functionality segmented, it also can help if you go back to update the original settings to keep the changes within one area (somewhat).

Reading from ADC should be as simple as enabling the specific ADC channel in cubemx, then adding this to your main:

Code: [Select]
HAL_ADC_PollForConversion(&hadc1, 10)
ADCValue = HAL_ADC_GetValue(&hadc1);

But there are some gotchas, sometimes the Cube values are set to really weird defaults (like the timer count maximum of 0..). Also if you are using multiple ADC channels, due to how the internal scan conversion works it can take some time to process.
We discussed in the other thread always use example code as well, to know right away which function is needed.

Profile -> Modify profile -> Look and Layout ->  Don't show users' signatures
 
The following users thanked this post: randyyork

Offline JohnnyBerg

  • Frequent Contributor
  • **
  • Posts: 474
  • Country: de
Re: STM32CubeIDE / CubeMX Workflow Tips and Tricks?
« Reply #6 on: November 19, 2019, 06:27:58 am »
Did you use the option "Generate a pair of .c/.h files per peripheral"?
That cleans up a lot of the mess and keeps functionality segmented, it also can help if you go back to update the original settings to keep the changes within one area (somewhat).

Sure I did, but that did not turn the ugly code in something beautiful.

Quote
Reading from ADC should be as simple as enabling the specific ADC channel in cubemx, then adding this to your main:

Code: [Select]
HAL_ADC_PollForConversion(&hadc1, 10)
ADCValue = HAL_ADC_GetValue(&hadc1);

But there are some gotchas, sometimes the Cube values are set to really weird defaults (like the timer count maximum of 0..). Also if you are using multiple ADC channels, due to how the internal scan conversion works it can take some time to process.
We discussed in the other thread always use example code as well, to know right away which function is needed.

I tried .. but I did not get it to work. The biggest problem was selecting the port, from where to read.

Code: [Select]
value1 = analogRead(PA4);
value2 = analogRead(PC2);

This i can read understand and maintain ..
 
The following users thanked this post: randyyork

Offline tmadness

  • Regular Contributor
  • *
  • Posts: 83
  • Country: us
Re: STM32CubeIDE / CubeMX Workflow Tips and Tricks?
« Reply #7 on: November 19, 2019, 07:54:14 pm »
I've been through this recently. The path I chose is CubeMX for generating the makefile+initialization code and used LL drivers. LL code is easier to understand for me and I don't need to deal with the HAL bloat, or trying to read deep within HAL APIs to figure out whats happening. BTW RM0090 reference manual for F4 helped out a bunch, look for a reference manual specific to your MCU line. The LL API command for ADC read, assuming a simple setup,  would be LL_ADC_REG_ReadConversionData12(ADC1) where ADC1 is just a memory address define inside of the LL library
 
The following users thanked this post: randyyork, I wanted a rude username

Online thm_w

  • Super Contributor
  • ***
  • Posts: 8074
  • Country: ca
  • Non-expert
Re: STM32CubeIDE / CubeMX Workflow Tips and Tricks?
« Reply #8 on: November 19, 2019, 11:20:51 pm »
Sure I did, but that did not turn the ugly code in something beautiful.

Ah understand.

Quote
I tried .. but I did not get it to work. The biggest problem was selecting the port, from where to read.

Code: [Select]
value1 = analogRead(PA4);
value2 = analogRead(PC2);

This i can read understand and maintain ..

Yeah, totally get why this would be an issue, it took me a while to grasp. The way their whole ADC system is setup is not "traditional" like this. Probably they thought most people want to use interrupt/dma based reads, so you can have the ADC constantly churning away in the background (a lot of their parts have multiple ADCs as well).

One way to do this is make a wrapper function "analogRead", which would configure ADC with a specific channel, perform the HAL poll for conversion, then return the result.

Or of course use stm32 arduino library, or maybe one of the other HAL's that are oriented in that way.
Profile -> Modify profile -> Look and Layout ->  Don't show users' signatures
 
The following users thanked this post: randyyork

Offline lawrence11

  • Frequent Contributor
  • **
  • !
  • Posts: 322
  • Country: ca
Re: STM32CubeIDE / CubeMX Workflow Tips and Tricks?
« Reply #9 on: November 21, 2019, 05:56:42 pm »
I've been through this recently. The path I chose is CubeMX for generating the makefile+initialization code and used LL drivers. LL code is easier to understand for me and I don't need to deal with the HAL bloat, or trying to read deep within HAL APIs to figure out whats happening. BTW RM0090 reference manual for F4 helped out a bunch, look for a reference manual specific to your MCU line. The LL API command for ADC read, assuming a simple setup,  would be LL_ADC_REG_ReadConversionData12(ADC1) where ADC1 is just a memory address define inside of the LL library

I also feel like doing this, what IDE do you use.
 
The following users thanked this post: randyyork

Offline tmadness

  • Regular Contributor
  • *
  • Posts: 83
  • Country: us
Re: STM32CubeIDE / CubeMX Workflow Tips and Tricks?
« Reply #10 on: November 26, 2019, 12:52:19 am »
I use VS Code for most of my development, but i use CubeMX IDE (Yuck!) for debugging and uploading. I could configure VS Code for debugging but my current project's timeline is constrained and I have to put out a solution soon. I think the latest video on EEVBlog with David and David  talks about configuring VS Code for full STM32 development. Its a bit time consuming but damn the javascript devs know how to build and maintain a good editor. VS code is is just so customizable, ya it runs electron, ya its built by the evil Microsoft, but damn is it good.
For my current setup I just installed the C/C++ plugin and and pointed VS Code to the generated source from CUBEMX, and intellisence just worked.
 
The following users thanked this post: randyyork

Offline lawrence11

  • Frequent Contributor
  • **
  • !
  • Posts: 322
  • Country: ca
Re: STM32CubeIDE / CubeMX Workflow Tips and Tricks?
« Reply #11 on: November 26, 2019, 02:36:43 am »
well thats weird, because its the debugging that actually sux due to gdb and eclipse bloat.

The best answer would be something like roelwy or segger but they dont permit stlink-v3

 
The following users thanked this post: randyyork

Offline JohnnyBerg

  • Frequent Contributor
  • **
  • Posts: 474
  • Country: de
Re: STM32CubeIDE / CubeMX Workflow Tips and Tricks?
« Reply #12 on: November 26, 2019, 08:00:07 am »
For my current setup I just installed the C/C++ plugin and and pointed VS Code to the generated source from CUBEMX, and intellisence just worked.

I use this setup for quite some time, and intellisense stopped working yesterday. After a few hours of digging, I found that there is a possibility to reset the intellisense database. After the reset, everything worked again.
 
The following users thanked this post: randyyork

Offline tmadness

  • Regular Contributor
  • *
  • Posts: 83
  • Country: us
Re: STM32CubeIDE / CubeMX Workflow Tips and Tricks?
« Reply #13 on: November 26, 2019, 06:16:37 pm »
well thats weird, because its the debugging that actually sux due to gdb and eclipse bloat.

The best answer would be something like roelwy or segger but they dont permit stlink-v3
Hey like I said, I'm only using CubeMX because I have to devote my resources elsewhere. Previously I've used the stlink utility to upload the binary but I needed debugging for this project. VSCode can be configured to run openocd+gdb but i've never explored that rout and I doubt my manager would be happy if spent half a day figuring that out.
 
The following users thanked this post: randyyork

Offline JohnnyBerg

  • Frequent Contributor
  • **
  • Posts: 474
  • Country: de
Re: STM32CubeIDE / CubeMX Workflow Tips and Tricks?
« Reply #14 on: November 30, 2019, 02:20:14 pm »
Found out that CubeMX also can generate LL(Low Level) code, and that is considerable smaller then HAL. For an experiment, I used that code as a basis for a C++ project. Blinking a led fits in 1068 bytes flash, and uses 8 bytes of RAM. The C version needs 1044 byes, so overhead for C++ is only 24 bytes. I disabled rtti en error propagation.

What a did was configuring the clocks, IO etc in CubeMX and then generate code with all the libraries included. Then I used the linker script, the startup_xx.s and the drivers as a basis for a new project, with my own structure and makefile.

This is my main:

Code: [Select]
int main()
    {
        Pin LED(GPIOA, LL_GPIO_PIN_4);

        while (1)
        {
            LED.reset();
            delay(500);
            LED.set();
            delay(500);
        }
    }

Size:

Code: [Select]
arm-none-eabi-size build/firmware.elf
   text    data     bss     dec     hex filename
   1068       8    1568    2644     a54 build/firmware.elf
« Last Edit: November 30, 2019, 02:31:38 pm by JohnnyBerg »
 
The following users thanked this post: randyyork

Offline tmadness

  • Regular Contributor
  • *
  • Posts: 83
  • Country: us
Re: STM32CubeIDE / CubeMX Workflow Tips and Tricks?
« Reply #15 on: December 01, 2019, 06:34:18 pm »
Interesting stuff. The small overhead coincides with what I've seen elsewhere on the interwebs. Most people tend to be touchy about using c++ on uCs, truth be told uCs with >512 kB of flash are pretty common and are reasonably priced. If such a higher capability uC is suitable for your application using c++ could be a lifesaver. But just out of curiosity how much of the latest standard of c++ (say c++ 17 or 20) do the arm-gcc compilers support?
 
The following users thanked this post: randyyork

Offline mark03

  • Frequent Contributor
  • **
  • Posts: 753
  • Country: us
Re: STM32CubeIDE / CubeMX Workflow Tips and Tricks?
« Reply #16 on: December 01, 2019, 08:17:36 pm »
There is really no justifiable reason for avoiding C++ in embedded work.  Well, maybe one:  A client once insisted that we use C when developing a driver framework, because after the work was transferred to his own SW team, he couldn't guarantee that less-experienced engineers wouldn't try to use features like multiple inheritance or the STL.  His "firewall" was forcing them to use C so those things wouldn't be possible.  Sad if you ask me, but you can't really argue with the logic.

The fact is, C++ code should be more readable and easier to maintain, without adding any code bloat whatsoever.  Classes, namespaces, and const are powerful organizational features; just don't do anything that is going to add run-time overhead.  Don't use exceptions.  Don't use the STL.  This should be common sense.

If anyone disputes this, I will rub their nose in the Kvasir project, which shows that C++ can actually enable *more* efficient code than C.  Admittedly it takes some ugly template metaprogramming to get there, and I don't really recommend it.  Parity with C is good enough.  No need to make the "C forever!!" people feel bad by beating them with even more efficient C++ code ;)
 
The following users thanked this post: randyyork

Offline splin

  • Frequent Contributor
  • **
  • Posts: 999
  • Country: gb
Re: STM32CubeIDE / CubeMX Workflow Tips and Tricks?
« Reply #17 on: December 02, 2019, 12:11:37 am »
There is really no justifiable reason for avoiding C++ in embedded work.  Well, maybe one:  A client once insisted that we use C when developing a driver framework, because after the work was transferred to his own SW team, he couldn't guarantee that less-experienced engineers wouldn't try to use features like multiple inheritance or the STL.  His "firewall" was forcing them to use C so those things wouldn't be possible.  Sad if you ask me, but you can't really argue with the logic.

Exactly. I seem to remember it said in the early days of ADA that it was such a huge language, with countless different ways to code a solution, that you could have a dozen different projects written by different teams each using a subset of the language that they had learned or felt comfortable with, such that no team could understand any of any other team's code.

I've probably exagerated that a bit... but it also applies to C++. Sure you can try to limit the allowed subset of C++ features used but there's always some smart-arse determined to make the code 'better' by pushing the boundaries. And not so smart-arses who step over the boundaries because they had no idea what they were or where they were.

I haven't used C++ for some time but one of the wost aspects were the WTF moments  - you know when you're single stepping through an innocuous piece of intiialization code, a few perfectly simple assignments, when the lights go out with a big bang; when the smoke clears you find yourself in some parallel universe.... 'Toto, I've a feeling we're not in Kansas anymore.' Slip on your ruby slippers and tap your heels (stack trace) and realise you fell through a one way wormhole into hell.

Like when, your using Eclipse and your fingers stumble on the keyboard; suddenly eventually its refactored your entire codebase to align with the latest holy order of the 'one true programming methodology because all others are the spawn of the devil and you will burn in hell if you don't use 11 space tabs interspersed with regular spaces in an apparently pseudo-random order, but actually to a cunningly crafted formula only revealed to the high priests'. Your code has been transposed into COBOL, your menus are now in Sanskrit, the IDE has changed to a set of windows you've never seen before with a dark grey typeface on slightly darker grey backgrounds and you've been signed up to a lifetime's subscription of 'Geriatric Russian ex-wrestlers dirty underpants rune-readers monthly'. (Other nation's ex-wrestlers are available).

You know you pressed a <ctrl> <alt> <shift> <alphnumeric> ish combo but have no idea which one or how to get back. You try typing PLUGH and end up in a maze of twisty little passages all alike...

I've probably exagerated that a bit...

Abstraction is a godsend or a curse - great when you're writing the code and understand how it's pieced together but potentially a nightmare when trying to review or maintain code where every sequence point could trigger a landmine of templated-polymorphic-over-ridden 'goodness'.

Quote
The fact is, C++ code should be more readable and easier to maintain, without adding any code bloat whatsoever.

The fact is, C++ code can be more readable and easier to maintain, without adding any code bloat whatsoever. It can be more readable and much harder to maintain, whilst adding lots of unexpected
things lurking in dark corners. I understand the language has evolved considerably in the years since I used it so it's lots 'better-er'. Or to paraphrase, beyond my ability to understand more than a small fraction of it.

Quote
Classes, namespaces, and const are powerful organizational features; just don't do anything that is going to add run-time overhead.  Don't use exceptions.  Don't use the STL.  This should be common sense.

Trouble is there's no internationally agreed standard for 'commom sense'. Try asking Donald.   :scared:
 
The following users thanked this post: randyyork, newbrain

Offline JohnnyBerg

  • Frequent Contributor
  • **
  • Posts: 474
  • Country: de
Re: STM32CubeIDE / CubeMX Workflow Tips and Tricks?
« Reply #18 on: December 02, 2019, 10:25:14 am »
Back to the topic starter question, this is a strategie I used in a project.

1. In CubeMx set everything up, mcu, clock config, IO, ADC etc.
2. Save the project in a temporary folder.
3. Generate code, using LL drivers (and not HAL), as a Makefile project.
4. Create the folder structure for the project, mine is like this:

- In .vscode there is a config to work easy with VSCode. The C++ extension is setup, Cortex Dug configured for debugging, some tasks for clean, build etc.
- The build folder is generated by make, and removed by make clean
- doc contains the reference guide, datasheet etc. from the mcu
- Drives is copied 1 to 1 from the CubeMx project, containing all mcu specific stuff, drivers etc.
- src contains my source files, every file in this folder is auto compiled by make.
- Makefile is my generic Makefile to build C++ projects, with some changes to work easy with STM32 stuff
- startup_*.s is copied from the CubeMx project
- the svd file comes from the internet (forgot source, just google). This gives a nice view of the registers of the mcu during debug.
- the .ld (linker file)  is copied from the CubeMx project

The source folder looks like this:

No explanation needed (I think?)

The C++ encapsulates the calls the the ST LL libraries, and the classes are small and very readable. Porting to a different mcu should be fairly simple.

This is what my main looks like:

Code: [Select]
char msg[64];
    unsigned int cnt = 0;

    int main()
    {
        DigitalOut LED(PA4);
        Adc adc(ADC1);
        AnalogIn CH0(adc, PA0);
        AnalogIn CH1(adc, PA1);
        AnalogIn CH2(adc, PA2);
        VRef VRef(adc);
        Temp Temp(adc);

        Usart SerialPort(PA9, PA10, 115200);

        while (1)
        {
            LED = On;

            uint16_t in0 = CH0.read();
            uint16_t vref = VRef.read();
            uint16_t temp = Temp.read();

            int len = sprintf(msg, "values [%d]: %d %d %d %d %d\r\n", ++cnt, in0, CH1.read(), CH2.read(), temp, vref);
            SerialPort.send(msg, len);

            LED = Off;
            Delay(1000);
        }
    }

Again, very readable, maintainable and portable. No need to explain what it does, the code tells the story.

Building with all debug info in the firmware gives these sizes:
Code: [Select]
arm-none-eabi-size build/firmware.elf
   text    data     bss     dec     hex filename
   6744     116    1904    8764    223c build/firmware.elf

Not bad, considering most of it comes out of the ST LL libraries.
« Last Edit: December 02, 2019, 10:29:30 am by JohnnyBerg »
 
The following users thanked this post: thm_w, randyyork

Offline tmadness

  • Regular Contributor
  • *
  • Posts: 83
  • Country: us
Re: STM32CubeIDE / CubeMX Workflow Tips and Tricks?
« Reply #19 on: December 02, 2019, 09:35:43 pm »
To add to that I got debugging working with the cortex debug plugin and openocd. in the .vscode folder have the following code in a file called launch.json:
Code: [Select]
{
    "version": "0.2.0",
    "configurations": [
        {
            "type": "cortex-debug",
            "request": "launch",
            "servertype": "openocd",
            "cwd": "${workspaceRoot}",
            "executable": "./Debug/uOvenPort.elf",
            "name": "Debug (OpenOCD)",
            "device": "STM32F429",
            "configFiles": [
                "C:\\EmbeddedTools\\OpenOCD-20191024-0.10.0\\share\\openocd\\scripts\\interface\\stlink.cfg",
                "C:\\EmbeddedTools\\OpenOCD-20191024-0.10.0\\share\\openocd\\scripts\\target\\stm32f4x.cfg"
            ]
        }
    ]
}

Obviously modify config files and device to one specific to your mcu and the location under executable to the compiled binary
 
The following users thanked this post: randyyork

Offline lucazader

  • Regular Contributor
  • *
  • Posts: 221
  • Country: au
Re: STM32CubeIDE / CubeMX Workflow Tips and Tricks?
« Reply #20 on: December 02, 2019, 10:37:47 pm »
I also use the cubemx to generate a makefile project and then do the rest of my development in vscode with a similar openocd setup as tmadness.

I find that sometime intellisense doesn't quite get all of the click navigation correct.
The best way to make sure it gets this correct is to use compiledb. This is a little python script (pip3 install --user compildb) that will generate a compile_commands.json file that vscode can then use to more definitively navigate the project.

I also change the makefile to change the ordering of which the objects are built, always building the startup file first. As If you build with LTO, some versions of gcc will error if this is not the first file which is linked (has to do with weak interrupt definitions getting optimistically optimised away too early)
To build with lto it's really easy. just change the optimization line "OPT = -Og" to your desired optimisation the add "-flto" eg "OPT = -Os -flto". This usually results in the smallest binary possible (but not always).
I also tend to add the -s makeflag to the makefile and then manually print out the file that is being compiled (eg "cc tim.c") so that the build terminal doesn't look so cluttered with all of the build arguments etc.

eg the terminal will look like this when building
Code: [Select]
cc stm32f3xx_hal_pwr_ex.c
cc stm32f3xx_hal_flash.c
cc stm32f3xx_hal_flash_ex.c
cc stm32f3xx_hal_i2c.c
cc stm32f3xx_hal_i2c_ex.c
cc system_stm32f3xx.c
ld application.elf
   text    data     bss     dec     hex filename
      0   40320       0   40320    9d80 build/release/application.hex

(yes i usually print of the size info of the hex file rather than elf, as the hex file size the the actual size that will be taken up in flash. you can print both the elf and hex to then know both the real flash usage and real static ram usage)

Below is what the last part of my makefile looks like to do that. you then only have to add "MAKEFLAGS = -s" at the top of your makefile to suppress the usual output
Code: [Select]
OBJECTS = $(addprefix $(BUILD_DIR)/,$(notdir $(ASM_SOURCES:.s=.o)))
vpath %.s $(sort $(dir $(ASM_SOURCES)))
OBJECTS += $(addprefix $(BUILD_DIR)/,$(notdir $(C_SOURCES:.c=.o)))
vpath %.c $(sort $(dir $(C_SOURCES)))

all: $(BUILD_DIR)/$(TARGET).elf $(BUILD_DIR)/$(TARGET).hex $(BUILD_DIR)/$(TARGET).bin
$(SZ) $(BUILD_DIR)/$(TARGET).elf

$(BUILD_DIR)/%.o: %.c Makefile | $(BUILD_DIR)
$(info cc $(notdir $(<:.c=.c)))
$(CC) -c $(CFLAGS) -Wa,-a,-ad,-alms=$(BUILD_DIR)/$(notdir $(<:.c=.lst)) $< -o $@

$(BUILD_DIR)/%.o: %.s Makefile | $(BUILD_DIR)
$(info as $(notdir $(<:.s=.s)))
$(AS) -c $(CFLAGS) $< -o $@

$(BUILD_DIR)/$(TARGET).elf: $(OBJECTS) Makefile
$(info ld $(TARGET).elf)
$(CC) $(OBJECTS) $(LDFLAGS) -o $@

$(BUILD_DIR)/%.hex: $(BUILD_DIR)/%.elf | $(BUILD_DIR)
$(HEX) $< $@

$(BUILD_DIR)/%.bin: $(BUILD_DIR)/%.elf | $(BUILD_DIR)
$(BIN) $< $@


Hope this helps some people.
 
The following users thanked this post: randyyork

Offline dkonigs

  • Regular Contributor
  • *
  • Posts: 142
  • Country: us
Re: STM32CubeIDE / CubeMX Workflow Tips and Tricks?
« Reply #21 on: October 10, 2020, 09:06:20 pm »
I know this topic has been idle for a while now, but as I'm just getting started with STM32CubeIDE I stumbled across it.
Has anyone found any documentation on the project structure that the code generation actually wants you to use for your projects? It seems to follow some sort of design (except when it adds random out-of-place root-level directories like "USB_HOST"), so I'm thinking it may make sense to actually follow it.

However, when adding something that falls into the category of "library code", "module of stuff", "device driver/interface code", etc, that's NOT plopped into place by the STM Cube infrastructure, its not always clear exactly where I'm supposed to put it.

Its also not yet clear whether it makes more sense to try and code within the structure this tool sets up for you, or whether to simply let the tool give you a "template" project and then just create your own sanely and logically structured real project that pulls in elements where appropriate.

General "software engineering" best practices for embedded projects seem to be something that tutorials and simplistic sample projects for all these platforms pretty much never cover in any useful way, so I'm always looking for guidance and real-world example projects that do a better job of that.
 

Offline jnz

  • Frequent Contributor
  • **
  • Posts: 593
Re: STM32CubeIDE / CubeMX Workflow Tips and Tricks?
« Reply #22 on: October 12, 2020, 09:14:39 pm »
FOR ME..... The STM Cube program is really good for selecting chip, seeing a pin out view, seeing which peripherals work on which pins, figuring out clock settings... and then basically not using any of their code.

I’ve been using a Nordic for a couple years so I don’t know, did the “LL” drivers ever go anywhere?
 
The following users thanked this post: Karel

Offline dkonigs

  • Regular Contributor
  • *
  • Posts: 142
  • Country: us
Re: STM32CubeIDE / CubeMX Workflow Tips and Tricks?
« Reply #23 on: October 16, 2020, 03:16:26 am »
Considering that I'm somewhat new to the platform, and that the latest versions of STM32CubeIDE and HAL seem decently fleshed out, I'm strongly tempted to actually try going with that approach directly.
Then again, I just found two unrelated cases in the USB_OTG_FS / USB_HOST code generation where the tool produces code that does not work as generated. Sure, the tool has input boxes that, if I could change their values, it would fix the issues. But those are disabled in the Cube UI. So yeah, its a case of "generate code, edit generated code".  (one was an interrupt priority level, the other was a GPIO direction setting)

That being said, it seems like I have at least 3 different approaches I can take that might meet my needs:
  • Work within the STM32CubeIDE generated code framework, using notes in the "USER CODE" areas (and version control diffs) to make sure I preserve my necessary edits whenever I regenerate.
  • Use an STM32CubeIDE generated-style project as a starting point, but diverge significantly as I clean things up. (Keep a pristine Cube-generated-code project around to diff whenever there are changes/updates, so I can pull them in manually.)
  • Use a completely clean project, with a more sensible directory layout, but do whatever it takes so that I can still build/run/debug from within the STM32CubeIDE tooling. Start from the generated code, but not necessarily the generated directory structure. Probably use a standalone-capable Makefile-style build process. (Also keep a pristine Cube-generated-code project around to diff whenever there are changes/updates, so I can pull them in manually.)
 

Offline tmadness

  • Regular Contributor
  • *
  • Posts: 83
  • Country: us
Re: STM32CubeIDE / CubeMX Workflow Tips and Tricks?
« Reply #24 on: October 16, 2020, 06:02:14 pm »
Ive invariably lost code by live editing like described in (1). For my last project I went with approach (3), copying only things I from a skeleton generated project. I'll probably end up using (3) in the future as well. Although I have to say I'm currently cheating on STM32 with NXP, and I don't know if I'll return back in the near future.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf