stm32f4 g ++ ошибка, связанная с newlib _kill_r, _kill, _getpid_r, _getpid,

У меня проблема с компиляцией кода C ++ на микрочип stm32f4.

цель

Я пытаюсь достичь нескольких вещей здесь:

  1. скомпилировать код C ++ для stm32f4-discovery (что было сделано
    успешно на голой программе [с реализацией конструкторов
    и другие особенности C ++])
  2. написать код с использованием периферийной библиотеки, поставляемой ST (в данном случае я использую функциональность USART)
  3. Компилировать код без использования коммерческой IDE (это простая задача) с использованием инструментов GNU

вопрос

У меня есть два проекта настройки, один из которых является проектом c и будет правильно скомпилирован. Я также прошил stm32f4 с выходом этого проекта, и он работает правильно. Второй проект использует тот же код с небольшими изменениями в файле make и именах файлов для компилятора C ++ (без различий в коде). Проект C успешно компилируется, а проект C ++ выдает ошибки.

Оба проекта и их вывод на терминал можно найти Вот:
https://dl.dropboxusercontent.com/u/32204435/USART.tar.gz

Настроить

Я использую Ubuntu 12.04.3 LTS 64bit. Я установил набор инструментов arm-none-eabi по инструкции на этом сайте:
vedder.se/2012/07/get-started-with-stm32f4-on-ubuntu-linux/

Информация Анализ

Из того, что я могу сделать, есть ошибка с поддержкой newlib в компиляторе arm-none-eabi-g ++. Я не понимаю, почему возникает ошибка, потому что между двумя проектами нет различий в коде.
Функции из newlib, такие как printf, также выдают схожие ошибки, если используются. В примерах USART я ограничил любую возможность проекта использовать newlib (единственное исключение — для типов данных). Кажется, что ошибка вызвана не newlib, а из-за аппаратного заголовка (или известного как заглушки newlib), который отсутствует (syscalls.h). Я потерпел неудачу в любой попытке применить syscalls.h.

Может кто-нибудь помочь с созданием этого проекта с поддержкой C ++ и, возможно, даже предложить решение для использования кода в newlib без ошибок (например, printf [или, я знаю, большой спрос, cout из iostream])?

Я все еще учусь, мне 17 лет, и у меня нет учителя (самостоятельно руководимого), так что может показаться, что я неопытный, чем я и являюсь 🙂 Ожидайте пробелы в знаниях.

Счастливого Рождества!

1

Решение

Добавьте -fno-rtti и -fno-exception к te CFLAGS в Makefile.

Кроме того, вы можете добавить этот хак в файлы компиляции

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)
;
}

}

Это отключает перехват сигнала при проверке исключений.

Хороший хак!

2

Другие решения

Для использования rtti и исключений вам необходимо определить некоторые реализации системных вызовов:

В моем компиляторе (встроенный gcc 4.8 + newlib nano) этот обходной путь работает нормально (добавьте в новый файл с именем 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;
}

Если у вас по-прежнему возникают проблемы с неопределенными символами, такими как _write или _isatty, добавьте -lnosys к флагам компоновщика.

Полученный исполняемый файл немного толще, чем версия без исключения. (Около 8K) Но если вам требуются исключения, и механизм rtti не очень полезен на Cortex-M4 с 1M вспышки

0

По вопросам рекламы [email protected]