سؤال

I am having an issue compiling c++ code onto a stm32f4 micro-chip.

Aim

I am trying to achieve a few things here:

  1. compile C++ code to the stm32f4-discovery (which has been done successfully on a bare bone program [with the implementation of constructors and other c++ specific features])
  2. write code using peripherals library supplied by ST (in this case, I am using the USART functionality)
  3. Compile code with out using a commercial IDE (this is leaning task) by using GNU tools

Issue

I have two projects setup, one is a c project and will compile correctly. I have also flashed the stm32f4 with the output of this project and it has run correctly. The second project uses the same code with minor changes to the make file and file names for the C++ compiler (no difference in code). The C project successfully compiles and the C++ project throws errors.

Both projects and their output on the terminal can be found here: https://dl.dropboxusercontent.com/u/32204435/USART.tar.gz

Setup

I am using Ubuntu 12.04.3 LTS 64bit. I have installed a arm-none-eabi toolchain by the instruction on this website: vedder.se/2012/07/get-started-with-stm32f4-on-ubuntu-linux/

Information & Analysis

From what I can make there is an error with the support of newlib in the arm-none-eabi-g++ compiler. I don't understand why there is an error as there are no code differences between the two projects. Functions from newlib like printf also product similar errors if used. In the USART examples I have limited any possibility of the project using newlib (only exception is for data types). The error does not seem to be caused by newlib but from the hardware header (or known as newlib stubs) which is missing (syscalls.h). I have been unsuccessful in any attempt to apply syscalls.h.

Can anyone help out with building this project with C++ support and maybe even offer a solution to using the code in newlib without error (like printf [or, I know a big ask, cout from iostream])?

I am still learning, I'm 17 and have no teacher (self driven) so may seem to be inexperienced, which I am :) Expect knowledge gaps.

Merry Christmas!

هل كانت مفيدة؟

المحلول

Add -fno-rtti and -fno-exceptions to te CFLAGS on Makefile.

Alternatively, you can add this hack to te compilation files

extern "C" int __aeabi_atexit(void *obj, void (*dtr)(void *), void *dso_h) {
    (void) obj;
    (void) dtr;
    (void) dso_h;
    return 0;
}

void *__dso_handle = 0;

/**
 * This is an error handler that is invoked by the C++ runtime when a pure virtual function is called.
 * If anywhere in the runtime of your program an object is created with a virtual function pointer not
 * filled in, and when the corresponding function is called, you will be calling a 'pure virtual function'.
 * The handler you describe should be defined in the default libraries that come with your development environment.
 */
extern "C" void __cxa_pure_virtual() {
        while (1)
                ;
}

namespace __gnu_cxx {

void __verbose_terminate_handler() {
        while(1)
                ;
}

}

This disable signal traping over exception chequing.

Good Hack!

نصائح أخرى

For rtti and exceptions usage, you need to define some syscalls implementations:

In my compiler (gcc arm embedded 4.8 + newlib nano) this workaround, work fine (Add to new file named src/hack.cpp):

extern "C" int __aeabi_atexit(void *obj, void (*dtr)(void *), void *dso_h) {
    return 0;
}

/* Enable if your stub don't provide dso handle symbol */
#if 0
void *__dso_handle = 0;
#endif

extern "C" void __cxa_pure_virtual() {
    while (1)
        ;
}

namespace __gnu_cxx {
  void __verbose_terminate_handler() { while(1) ; }
}

extern "C" int _getpid(void) {
  return 1;
}

extern "C" void _kill(int pid) { while(1) ; }

extern "C" int _end;

static char *end_of_data = (char *) &_end;

/*
 * WARNING: No stack/heap colition check.
 * For check colition and stack growing overflow use SP register value
 * or RAM end limit depeding of processor architecture
 */
extern "C" char *_sbrk (int delta) {
        char *ptr = end_of_data;
        end_of_data += delta;
        return ptr;
}

If you continue having problems with undefined symbols, as _write or _isatty, add -lnosys to the linker flags.

The resulting executable file is slightly fatter than non-exception version. (About 8K) But if you require exceptions and rtti mechanism is tinny overhead on a Cortex-M4 with 1M of flash

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top