У меня проблема с компиляцией кода C ++ на микрочип stm32f4.
Я пытаюсь достичь нескольких вещей здесь:
У меня есть два проекта настройки, один из которых является проектом 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 лет, и у меня нет учителя (самостоятельно руководимого), так что может показаться, что я неопытный, чем я и являюсь 🙂 Ожидайте пробелы в знаниях.
Счастливого Рождества!
Добавьте -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)
;
}
}
Это отключает перехват сигнала при проверке исключений.
Хороший хак!
Для использования 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 вспышки