• Уважаемые посетители сайта esp8266.ru!
    Мы отказались от размещения рекламы на страницах форума для большего комфорта пользователей.
    Вы можете оказать посильную поддержку администрации форума. Данные средства пойдут на оплату услуг облачных провайдеров для сайта esp8266.ru
  • Система автоматизации с открытым исходным кодом на базе 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 ?
 
Сверху Снизу