Skip to main content
HTD
Senior II
May 3, 2022
Question

STM32CubeIDE projects: how to use objects generated in main.c file in other C files?

  • May 3, 2022
  • 13 replies
  • 4999 views

The goal is to not write my entire hardware handling program in main.c file, as tutorials often show.

I use TouchGFX, the project for Visual Studio doesn't even see main.c file or has any access to the hardware part of the code. It's OK, I use VS only for the UI part. I code the hardware handling part in STM32CubeIDE.

Let's say I enable I2C bus in .ioc file. That automatically generates code in main.c, the problem is, I want to make a driver (in another file) that uses that object (initialized I2C object) in my own piece of code, let it be even C++ class.

I already figured out how to bridge 2 projects (hardware part and UI part) with conditional include of a bridge file, that includes main.h and use externs. The condition is of course "#ifndef SIMULATOR". For the simulator I make dummy objects that just simulate the actual hardware. It all works.

The problem is - my bridge file includes main.h and has access to most HAL, but it doesn't see anything defined in main.c. The CubeMX code generator writes everything in main.c. How can I make my custom code contained in other file (my bridge file) see the objects defined in main.c? Is there a standard way of doing this, or maybe a clever trick?

This topic has been closed for replies.

13 replies

TDK
May 3, 2022

Declare the object as "extern" in a header file or somewhere else seen in your other C program.

If main.c defines this;

I2C_HandleTypeDef hi2c1;

Put this before it is used in other.c, or in other.h, or in main.h:

extern I2C_HandleTypeDef hi2c1;

"If you feel a post has answered your question, please click ""Accept as Solution""."
Bob S
Super User
May 3, 2022

In CubeMX click on the "Project Manager" tab along the top. Then on the left side click on "Code Generator". In the "Generated Files" section check the box for "Generate peripheral initialization as a pair of '.c/.h' files per peripheral. CubeMX will then generate i2c.c and i2c.h, and i2c.h will have the "extern" declaration that @TDK​ mentioned. It will also create a gpio.c/.h, usart.c/.h, etc., for whatever peripherals you enable. This gets almost all of the initialization code out of main.c.

HTD
HTDAuthor
Senior II
May 3, 2022

That seems to break TouchGFX project. Trying to run it from STM32CubeIDE almost fried my discovery board (white screen decaying on corners, first time it happen the display had like burned out corners and flickered, it healed after being powered off for like 30 minutes), running from TouchGFX caused build to fail without apparent reason (just something exited 1 exit code). I think TouchGFX doesn't play well with this option. Or is it supposed to work with TouchGFX and I've done something wrong?

BTW, I restored the board from "bricked" state by uploading the previous project that worked.

Bob S
Super User
May 4, 2022

Oops - sorry about that. I have no experience with TouchGFX. Though now that you mention it, there was another thread here lately about conflicting MX_Init_I2C4() functions with TouchGFX. If TouchGFX is creating its own set of MX_Init_XXXX functions, that might explain what went wrong in your case. [EDIT: Well, that was you in that other post, so, never mind]

wired
Senior II
May 5, 2022

I just read your suggestion and liked it, so I tried it in my project. Everything built just fine, and now I have a manageable main.c. Thanks for the tip.

wired
Senior II
May 5, 2022

I TAKE THAT BACK - IT DID NOT WORK FINE FOR ME!!!

I rebuilt the program OK< but when I loaded into the debugger and ran it, I had some kind of failure (and the operating current was not normal). Now every time I try to run the debugger, I get this:

0693W00000NpLO8QAN.pngI think my development board is fried!

All I did was enable the creation of .c/.h files, and also checked the box to make unused pins analog.

HTD
HTDAuthor
Senior II
May 8, 2022

For what I tested, TouchGFX needs all automatically generated initialization in main.c. At least, I haven't figured out how to change it and make it still work. However - I moved my custom code entirely to different files to make the code clean. It was super tedious and a little tricky to introduce new files and includes to all IDE-s involved (TouchGFX, Visual Studio and STM32CubeIDE), but I made an automated tool for that: https://github.com/HTD/TouchGFX-HAL-Bridge - I tested it only with my STM32H747I-DISCO board, I'm curious how it would play with other setups. The tool just adds a 4 new files, 2 code files and 2 header files. One part is a "core", for the hardware part (built for the device), one is for UI C++ code. BTW, the files are empty, it's just the template to connect the code that would otherwise go to main.c, now it goes to HALBridge.c and the methods are exposed as HALBridge class static methods to be called by the Model class. Under the hood - it just changes the project files to link the new files and include an additional include path.