• Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Существует ли с++ среда для esp8266?

Alex_S

New member
Собственно, сам компилятор для него есть в SDK. Но либы, похоже, есть только для С.
Кто-то заморачивался с написанием кода на С++?
 

CHERTS

Moderator
Команда форума
Собственно, сам компилятор для него есть в SDK. Но либы, похоже, есть только для С.
И компилятора C++ нет, он был у меня в X64 сборки DevKit v1.0.4, но сейчас я x64 не буду собирать и как следствие с++ компилятора не будет. Да и не нужен он, см. выше почему.
 

Alex_S

New member
Насчет расхода памяти - не такая и большая разница что по флешу, что по оперативке. Зато писать на плюсах гораздо проще и приятнее.
 

CHERTS

Moderator
Команда форума
Насчет расхода памяти - не такая и большая разница что по флешу, что по оперативке. Зато писать на плюсах гораздо проще и приятнее.
Возможно, но китайские разработчики иного мнения, как следствие сидим на том что есть.
 

jcmvbkbc

New member
Собственно, сам компилятор для него есть в SDK. Но либы, похоже, есть только для С.
Кто-то заморачивался с написанием кода на С++?
Я заморачивался. igrr заморачивался.
Тут есть следующие моменты:
- исключения: поддержки в g++ сейчас нет, а когда появится вы сами не захотите ими пользоваться :) Потому что даже hello world с единственным исключением в память не лезет;
- хедеры SDK: прототипов функций мало и они не всегда соответствуют действительности;
- нужно править скрипт линковщика и руками вызывать глобальные конструкторы/деструкторы; см. http://www.esp8266.com/viewtopic.php?f=9&t=478
- нужно определить операторы new/delete для работы с API espressif, см. http://www.esp8266.com/viewtopic.php?f=9&t=1136

Про либы не понял: если собирать тулчейн crosstool-NG вы получите всю стандартную библиотеку с++.
 

Alex_S

New member
- исключения в ембеддед редко встречаются.
- либы - я имел в виду SDK.
- определить new/delete - нужно во многих ембеддед средах.
Пасиба за линки - почитаю и попробую!

П.с. Оказывается, и на русскоязычном форуме и на иностранном живут одни и те же лица )))
 

Alex_S

New member
jcmvbkbc,
Спасибо за рекомендации!
Под винду квест оказался непростой, но сейчас вроде компилирует нормально.
В сборке от CHERTS компилятор и основные либы таки уже есть, добавил только libc, libhal, и инклуды для них отсюда:
https://github.com/esp8266/esp8266-wiki/raw/master/libs/libc.a
https://github.com/esp8266/esp8266-wiki/raw/master/libs/libhal.a
https://github.com/esp8266/esp8266-wiki/raw/master/include.tgz

Ну и ес-сно, в своем проекте определил новые new, delete, и прочие необходимые методы, добавил инициализацию глобальных объектов, адаптировал makefile.
Все вводные взяты в указанных темах.
Спасибо!

Результирующий hello_world_cpp - в аттаче.
Непоняток пока две:
1. Почему-то вывод в последовательный порт в функции user_init происходит на неправильной скорости. Возможно, уарт не успевает перестроить скорость. Но через секунду по таймеру все выводится правильно.
2. Не хватает хедеров для библиотечных функций, таких как os_timer_disarm, os_timer_setfn, ets_timer_arm_new, и т.д. Так же непонятно откуда компилятор берет их определения в исходном примере hello_world. Ведь пример компилируется успешно...
 

Вложения

jcmvbkbc

New member
1. Почему-то вывод в последовательный порт в функции user_init происходит на неправильной скорости. Возможно, уарт не успевает перестроить скорость. Но через секунду по таймеру все выводится правильно.
Я вижу, что вы в конструкторе A::A() статического объекта a выводите в UART, до вызова uart_init.
2. Не хватает хедеров для библиотечных функций, таких как os_timer_disarm, os_timer_setfn, ets_timer_arm_new, и т.д. Так же непонятно откуда компилятор берет их определения в исходном примере hello_world. Ведь пример компилируется успешно...
А вы включите -W -Wall и увидите, что ниоткуда он их не берёт и ругается тихонько. Для С++ прототипы придётся писать, да. В крайнем случае можно седом сделать затычки вида void f(...) из файла eagle.rom.addr.v6.ld
 

Alex_S

New member
Я вижу, что вы в конструкторе A::A() статического объекта a выводите в UART, до вызова uart_init.
Нет, в конструкторе я только инициализирую поля. Этот класс всего лишь для проверки инициализации глобальных объектов. Проверка показала, что таки, их надо инициализировать ручками. Вывод в нем только в методе print.
А вы включите -W -Wall и увидите, что ниоткуда он их не берёт и ругается тихонько. Для С++ прототипы придётся писать, да. В крайнем случае можно седом сделать затычки вида void f(...) из файла eagle.rom.addr.v6.ld
Вот оно что... Об этом я не подумал.
 

jcmvbkbc

New member
Нет, в конструкторе я только инициализирую поля. Этот класс всего лишь для проверки инициализации глобальных объектов. Проверка показала, что таки, их надо инициализировать ручками. Вывод в нем только в методе print.
М... Точняк :)
В любом случае, это не может быть "уарт не успевает перестроить скорость", скорость перестраивается синхронно при записи в регистр делителя.
 

Alex_S

New member
jcmvbkbc,
есть еще одна непонятка при попытке использовать вектор...
Линкер ругается:
Код:
c:\espressif\xtensa-lx106-elf\xtensa-lx106-elf\include\c++\4.8.2\bits/vector.tcc:344: undefined reference to `__dso_handle'
c:/Espressif/ESP8266_SDK/lib\libc.a(mallocr.o):(.literal+0x14): undefined reference to `_sbrk_r'
c:/Espressif/ESP8266_SDK/lib\libc.a(mallocr.o): In function `_malloc_r':
\build\tree\RC-2010.1_kuma\p4root\Xtensa\Target-libs\newlib\newlib\libc\stdlib/mallocr.c:2152: undefined reference to `_sbrk_r'
\build\tree\RC-2010.1_kuma\p4root\Xtensa\Target-libs\newlib\newlib\libc\stdlib/mallocr.c:2189: undefined reference to `_sbrk_r'
c:/Espressif/ESP8266_SDK/lib\libc.a(freer.o): In function `_malloc_trim_r':
\build\tree\RC-2010.1_kuma\p4root\Xtensa\Target-libs\newlib\newlib\libc\stdlib/mallocr.c:3309: undefined reference to `_sbrk_r'
\build\tree\RC-2010.1_kuma\p4root\Xtensa\Target-libs\newlib\newlib\libc\stdlib/mallocr.c:3351: undefined reference to `_sbrk_r'
c:/Espressif/ESP8266_SDK/lib\libc.a(freer.o):\build\tree\RC-2010.1_kuma\p4root\Xtensa\Target-libs\newlib\newlib\libc\stdlib/mallocr.c:3327: more undefined references to `_sbrk_r' follow
c:/espressif/xtensa-lx106-elf/bin/../lib/gcc/xtensa-lx106-elf/4.8.2/../../../../xtensa-lx106-elf/bin/ld.exe: build/httpd.out: hidden symbol `__dso_handle' isn't defined
c:/espressif/xtensa-lx106-elf/bin/../lib/gcc/xtensa-lx106-elf/4.8.2/../../../../xtensa-lx106-elf/bin/ld.exe: final link failed: Bad value
.
По идее вектор для выделения памяти должен использовать new. New и delete у меня определены в одном из cpp файлов. По идее линковщик должен найти их и использовать, но зачем-то он лезет через _maloc_r.
Попробовал переопределить и его - но не помогает.

И непонятно откуда вылезло __dso_handle...
Что я мог сделать не так?
 

jcmvbkbc

New member
У меня с такими определениями простой пример использующий std::vector собирается. Покажите ваш код, что ли.
Прямые обращения к malloc есть, например, в коде поддержки исключений. Возможно нужно указать -fno-exceptions при сборке libstdc++, пока не понял.
 

Alex_S

New member
Нашел закономерность.
Такое происходит если объект вектора глобальный... Или находится в глобальном объекте.
Вот еще одно подтверждение тому, что глобальные объекты - зло )))

Пример в аттаче.
Если объект "а" объявить локально в функции user_main - то все собирается отлично...
 

Вложения

Последнее редактирование:

Alex_S

New member
Продолжаем исследования. Проблема появляется даже не в стандартной библиотеке, а в случае, если глобальный объект имеет деструктор, объявленный явно. Ес-сно, вектор так же имеет деструкторы, поэтому и не компилится.
Осталось понять как деструктор влияет на использование библиотечных функций _malloc_r, _malloc_trim_r, _sbrk_r и __dso_handle.
Самое интересное в том, что деструктор глобального или статического объекта не должен никогда вызваться. Так зачем же он добавляет эти зависимости?
 
Последнее редактирование:

jcmvbkbc

New member
Нашел закономерность.
Такое происходит если объект вектора глобальный... Или находится в глобальном объекте.
Вот еще одно подтверждение тому, что глобальные объекты - зло )))

Пример в аттаче.
Если объект "а" объявить локально в функции user_main - то все собирается отлично...
У меня под линуксом ваш пример и так отлично собирается.
 

jcmvbkbc

New member
Продолжаем исследования. ... Осталось понять как деструктор влияет на использование библиотечных функций _malloc_r, _malloc_trim_r, _sbrk_r и __dso_handle
Пока у вас вылезает __dso_handle большого смысла разбираться со всем остальным нет. Что вам выводит xtensa-lx106-elf-g++ -v ?
 
Сверху Снизу