Skip to main content
Senior
February 4, 2024
Solved

What is the correct way of using classes in main.c

  • February 4, 2024
  • 13 replies
  • 8093 views

Hi,

I have plenty of embedded code that was written in a mixture of C/C++ with target of NXP processors, now I am going to port it onto STM32 targets, I wrote a mini class OutputPort as a test in CubeIDE:

 

OutputPort.h:

 

#include "stm32f767xx.h"

class OutputPort

{

public:

OutputPort(GPIO_TypeDef* gpio, uint16_t gpioPin);

virtual ~OutputPort();

 

private:

GPIO_TypeDef* gpio;

uint16_t gpioPin;

 

public:

void Toggle();

void Set();

void Reset();

};

 

OutputPort.cpp:

 

#include "OutputPort.h"

#include "stm32f7xx_hal.h"

 

OutputPort::OutputPort(GPIO_TypeDef* gpio, uint16_t gpioPin)

{

this->gpio = gpio;

this->gpioPin = gpioPin;

}

OutputPort::~OutputPort() { }

void OutputPort::Toggle() { HAL_GPIO_TogglePin(gpio, gpioPin); }

void OutputPort::Set() { HAL_GPIO_WritePin(gpio, gpioPin, GPIO_PIN_RESET); }

void OutputPort::Reset() { HAL_GPIO_WritePin(gpio, gpioPin, GPIO_PIN_SET); }

 

main.c :

/* USER CODE BEGIN Includes */

#include <OutputPort.h>

/* USER CODE END Includes */

 

/* USER CODE BEGIN 2 */

Port* Led1 = new Port(GPIOB, GPIO_PIN_0);

/* USER CODE END 2 */

 

The compiler reports: error: unknown type name 'class'

 

Then I change the main.c to main.cpp as I did with NXP processor which are also ARM Cortex,

it looks like the compilation is OK, but the linker reports error:

Core/Startup/startup_stm32f767zitx.s:99: undefined reference to `main'

The line 99 of startup_stm32f767zitx.s is a jump instruction (jump to main):

/* Call the application's entry point.*/

bl main

 

Chao_0-1707061972606.png

Anyone knows any workaround?

 

Regards

Chao

 

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

It's not compiling C++ files. Right click project in Project Explorer, select Convert to C++.

13 replies

TDK
February 4, 2024

Classes don't exist in C. You can rename it to main.cpp, or you can put your code in other.cpp and call it from there.

"If you feel a post has answered your question, please click ""Accept as Solution""."
ChaoAuthor
Senior
February 4, 2024

Thanks.

 I changed the main.c to main.cpp and the linker reports error:

Chao_0-1707066477792.png

The line 99 of startup_stm32f767zitx.s is a jump instruction (jump to main):

/* Call the application's entry point.*/

bl main

 

Regards

Chao

 

Pavel A.
February 4, 2024

@Chao To use C++ successfully, one has to know it )) Just to "have plenty of code" does not count. Find a course?

 

 

TDK
February 4, 2024

Put the definition of main within an extern "C" { }.

Or maybe you're not compiling C++ files.

"If you feel a post has answered your question, please click ""Accept as Solution""."
ChaoAuthor
Senior
February 4, 2024

I put an extern "C" { }  in two ways for test:

1. surround the main() { }:

extern "C" {

main()

{

... ...

}

}

2. surround the whole main.cpp except for #include <OutputPort.h> that declares a C++ class

But none of them works.

The following is a build after a clean:

Chao_0-1707072084502.png

I wonder why the compilation of OutputPort.cpp and main.cpp is absent.

Is it possible that something is incorrect in toolset setting?

In NXP's IDE, I got this after I have made a change in main.cpp:

Chao_1-1707072481454.png

and the following are the contents of main.cpp in my NXP project:

 
#include "PE_Types.h"
#include "PlcManager.h"
 
int main(void)
{
  PE_low_level_init();
  PlcManager *plcManager = new PlcManager();
  while (true)    {   plcManager->Run();   }
}
 

Regards

Chao

 

TDK
TDKBest answer
February 4, 2024

It's not compiling C++ files. Right click project in Project Explorer, select Convert to C++.

"If you feel a post has answered your question, please click ""Accept as Solution""."
ChaoAuthor
Senior
February 5, 2024

Great!

It works now, g++ is used at last.

The current method is to call MyMain() function that is in MyMain.cpp instantiating classes.

Thank you so much

Chao

ChaoAuthor
Senior
February 5, 2024

The current method is to call MyMain() function in main.c, and the MyMain() function is in MyMain.cpp that instantiates classes.

Andrew Neil
Super User
February 5, 2024

Use this button to properly post source code:

AndrewNeil_1-1707126843903.png

 

To get that extra row of icons, press this button:

AndrewNeil_2-1707126843901.png

 

A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.
TDK
February 6, 2024

> so is it possible to convert this example from other toolchain/IDE (say MDK-ARM) to CubeIDE?

See here:

https://wiki.st.com/stm32mpu/wiki/How_to_move_from_SW4STM32_to_STM32CubeIDE

Can also just try "Import ac6 System Workbench for STM32 Project" without the extra steps.

"If you feel a post has answered your question, please click ""Accept as Solution""."
Pavel A.
February 6, 2024

In CubeIDE, do "Import"....  then in the dialog select "Import STM32CubeIDE example".

This option is slightly better than "Import ac6 System Workbench..." as the import tool has more clues. Internally, of course, it will use the SW4STM variant of the example, so all advices on importing from SW4STM and fixes after  the import, apply. See also here.