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

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

jcmvbkbc

New member
А есть ли возможность исключать не по файлам а по библиотекам целиком?
Ну да. Посмотрите в скрипт линковщика. У меня там есть такая строчка: build/app_app.a:*_flash.o
Слева от двоеточия -- шаблон библиотеки, справа -- шаблон имени файла в библиотеке. Если справа * -- получается вся библиотека. Если слева -- ...
 

anakod

Moderator
Команда форума
Ага, я уже увидел это, если такого будет достаточно то все мои проблемы должны быть успешно решены. Вы тестировали вариант такой сборки, да?
 

anakod

Moderator
Команда форума
Прекрасно сегодня вечером все протестирую и отпишусь.
 

anakod

Moderator
Команда форума
Прекрасно сегодня вечером все протестирую и отпишусь.
Вы даже не представляете себе насколько это восхитительно когда ты можешь писать код и не думать каждую секунду о итоговом размере, о том не забыл ли расставить где-нибудь гребанные дефайны кеширования и т.д. и т.д. :)
Большое спасибо, этот работает именно так, как мне кажется оно должно было по хорошему работать если бы китайцы не схалтурили.
Довольно скоро поделюсь своими наработками, тема получается достаточно интересная.

Чтобы закрыть вопрос с ручным распределением памяти, задам пару оставшихся вопросов:
1. Верно ли я понимаю что теперь оно по-умолчанию кладется в другую секцию благодаря изменению порядка объявления секций (т.к. никакого явного эксклуда тут нет)?
2. Допускает ли этот способ объявления перечисление нескольких исключаемых библиотек? Какой используется синтаксис? Я пока еще не экспериментировал в этом направлении.
 

jcmvbkbc

New member
Чтобы закрыть вопрос с ручным распределением памяти, задам пару оставшихся вопросов:
1. Верно ли я понимаю что теперь оно по-умолчанию кладется в другую секцию благодаря изменению порядка объявления секций (т.к. никакого явного эксклуда тут нет)?
Ага. При определении куда пойдёт секция используется первое подходящее правило. Я подумал -- зачем нам этот exclude...
2. Допускает ли этот способ объявления перечисление нескольких исключаемых библиотек? Какой используется синтаксис? Я пока еще не экспериментировал в этом направлении.
Допускает. Синтаксис такой: библиотека должна быть указана перед двоеточием и этот путь должен матчиться с тем, как библиотека указана в команде линковки. Можно использовать * в значении "произвольная группа символов кроме слэша". Т.е. для builds/app_app.a, например, сработает builds/*, а просто * -- не сработает. Если нужно несколько библиотек с разными паттернами имен -- нужно копировать правило целиком.
 

anakod

Moderator
Команда форума
А если библиотека из SDK, указывать ее просто именем или тоже нужен какой-то путь?
 

jcmvbkbc

New member
А если библиотека из SDK, указывать ее просто именем или тоже нужен какой-то путь?
Мануал молчит на этот счёт, а практика показывает, что нужен паттерн слева от имени, и * в нём матчит слэш. Т.е. если дана команда "ld -lmain", то *libmain.a:* подходит, а просто libmain.a:* -- нет.
 

pvvx

Активный участник сообщества
Либы из SDK используют почти всю iram(27 кило), остается всего 5 кило на процедуры с критичными зависимостями в вашем коде. Свободный heap, после инициализации SDK у нас всего 34к (SDK 0.9.5). Любое соединение и стек LwIP ещё отъедают память - чем больше соединений, тем больше и учитывая TIME_WAIT (и то с ограничениями и некондиции к стандартам) памяти у вас остается всего 8 кило, необходимых для организации единственного буфера приема TCP по размеру стека TCP (~6 кило и буфера для передачи в 1 mss 1560 байт) - иначе потеря данных. Зачем нужна C++ в 30 кило на данном чипе, без возможности организации любого статического буфера и соединений для выполнения простейших задач? Исходников SDK нет и не намечается, чтобы хоть на кило памяти изменить ситуацию. Я уже вручную считаю и учитываю размеры динамических структур, от этого пляшут и алгоритмы и используемые библиотеки :)
У RTOS SDK уже стеки коротки...
Тут в пору писать на ассемблере, а не на CИ.
Или тут просто спортивная тема как на xtensa-lx106-elf собрать C++ компилер и на нем странслировать "HelloWorld" к данному чипу? :)
 
Последнее редактирование:

anakod

Moderator
Команда форума
Разница в памяти (RAM а не кода) C++ и C вообще сомнительна, и если она и есть, то составляет единицы-десятки байт (например таблицы виртуальных функций). Чем именно C++ усугубляет проблему?
Разумеется можно писать на нем криво. Ну так это и на асме можно :)

> памяти у вас остается всего 8 кило, необходимых для организации единственного буфера приема
А это с пересчетом на какое количество соединений? Неужели LwIP съедает целых 26 Кб?
 

pvvx

Активный участник сообщества
Неужели LwIP съедает целых 26 Кб?
Для его нормальной работы требуется более 128 килобайт. Без них - только с нарушением стандартов.
Для детских поделок - пойдет и то что есть. Но в реальный мир инета такое включать не следует - будут вечные "падения" и т.д..
Разница в памяти (RAM а не кода) C++ и C вообще сомнительна, и если она и есть, то составляет единицы-десятки байт (например таблицы виртуальных функций). Чем именно C++ усугубляет проблему?
Разумеется можно писать на нем криво. Ну так это и на асме можно :)
Вот эти пару байт и нужны для реализации простого соединения по TCP на модуле ESP8266.
Иначе это выйдет программа на С++ выводящая "HelloWorld" и больше ничего не делающая.
Зачем такой C++ на котором требуется извращаться, чтобы написать что-то более чем "HelloWorld" ?
Почему тогда сразу не интерпретатор 'бэйсика' или 'явы' или 'фортрана' ... ? :)
Таблицу виртуальных функций требуется обслуживать. Часть кода для реализации C++ придется переносить в iram. А там уже нет места. У Lua писателей уже давно стоит проблема в размере кода - он не лезет в стандартную flash модуля и там реализовать что-то более настроек WiFi ничего не возможно. Ну типа только послать пакет UDP что модуль умер :)

Если вы считать не умеете, то сосчитаю за вас:
К примеру 34 кило байта – это 170 закрытых соединений TCP за 2 минуты LwIP-пом. При наличии espconn и прочих надстроек над LwIP-ом, это ещё сокращается и всё равно менее, т.к. нужен хоть малый буфер для разбора ... Для TCP стека LwIP должен держать на каждое соединение буфер не менее 8 кило. 4-ре разрешенных открытых соединения в espconn= вся память в нуль и в процессе приема espconn переливает последний mss (1450 байт) через память (т.е. имеем дубли). По тому только UDP :) и то там требуются динамические буфера…
У вас стоит роутер с фильтрацией и глушением радиэфира от внешних запросов к модулю? :)
Если нет, то для реализации на C++ предусмотрите закрытие всех соединений у LwIP, когда откроется ваше соединение. Чтобы больше ничего не смогло открыться пока вы обрабатываете запрос :). DHCP и прочее тоже придется закрыть. Только тогда хватит памяти, с учетом тех пару в "таблице виртуальных функций".
Вы сами себе урезаете функционал модуля, за счет внедрения C++.
Мотивы jcmvbkbc понятны - чисто спортивный интерес по компилятору. :)
 
Последнее редактирование:

Alex_S

New member
Мое мнение - С++ на столь слабой платформе имеет право на жизнь.
Как уже было сказано - он кушает не намного больше ресурсов, чем С (зависит от стиля программирования и использованных библиотек), но многие вещи позволяет делать проще, тем самым улучшая качество продукта.
При этом необязательно использовать всю библиотеку stl, простые контейнеры типа vector, string не намного менее эффективные, чем массивы в С. Главное - уметь их правильно пользовать.
Кроме того - есть много случаев, когда много ресурсов не надо. Например, обслуживание датчиков и отправка данных на сервер/исполнение команд с сервера. Собственного кода там не так и много, и ресурсов для приложения много не надо. Поэтому все равно на каком языке оно написано. А тут уж кому что удобнее.

К слову, я простые проекты под простые контроллеры типа меги8 изначально писал на C. Потом перешел на C++, и не заметил, что код перестал влезать в флеш или стало мало оперативки. Зато код стал гораздо более прозрачным и наглядным.
 

pvvx

Активный участник сообщества
Кроме того - есть много случаев, когда много ресурсов не надо. Например, обслуживание датчиков и отправка данных на сервер/исполнение команд с сервера. Собственного кода там не так и много, и ресурсов для приложения много не надо. Поэтому все равно на каком языке оно написано. А тут уж кому что удобнее.
Про это и написал - для такого проекта требуется вся память, что есть. Так расcчитано в SDK и так сделаны опции у LwIP. Ни байта меньше. Если займете несколько десятков байт - не будет полноценно работать :)
Мое мнение - С++ на столь слабой платформе имеет право на жизнь.
Как уже было сказано - он кушает не намного больше ресурсов, чем С (зависит от стиля программирования и использованных библиотек), но многие вещи позволяет делать проще, тем самым улучшая качество продукта.
При этом необязательно использовать всю библиотеку stl, простые контейнеры типа vector, string не намного менее эффективные, чем массивы в С. Главное - уметь их правильно пользовать.

К слову, я простые проекты под простые контроллеры типа меги8 изначально писал на C. Потом перешел на C++, и не заметил, что код перестал влезать в флеш или стало мало оперативки. Зато код стал гораздо более прозрачным и наглядным.
На Бэйсике лучше - ещё компактнее :)

Вопроса не стоит жить или не жить C++. Вопрос только в том, что он требует ресурсов от чипа, которых нет.
 
Последнее редактирование:

pvvx

Активный участник сообщества
А на С будет? )))
Будет, если постараться. :) И на C++ будет, если ничего из его ++ не пользовать. :)
Вы занимайтесь – доделывайте C++. Возможно у другого чипа будет побольше ресурсов (как памяти, так и частоты CPU). Тогда это пригодится. "Хороша ложка к обеду." )))
 
Последнее редактирование:

jcmvbkbc

New member
К примеру 34 кило байта – это 170 закрытых соединений TCP за 2 минуты LwIP-пом.
Т.е. соединений висящих в TIME_WAIT? Что-то много: в TIME_WAIT же не требуется retransmit буфер, всё его состояние -- это примерно 32 байта, а у вас получается в 6 раз больше.
 

pvvx

Активный участник сообщества
Т.е. соединений висящих в TIME_WAIT? Что-то много: в TIME_WAIT же не требуется retransmit буфер, всё его состояние -- это примерно 32 байта, а у вас получается в 6 раз больше.
Смотрите размер структуры pсb у LwIP в его исходниках.
struct tcp_pcb в include\lwip\tcp.h.
У espconn структура на открытое соединение тоже не хилая...
Плюс издержки сегментации pbuf и распределения памяти... :)
Espressif-цы не зря морочались с переносом переменных у printf в область кеширования flash - не лезло уже ничего.
espconn дублирует уже всё что есть у lwip - такой "патч" неверно избранного алгоритма обращения к lwip. А они всё завязали на ней. Всякие ssl и т.д. По тому не переписать, а только патчить и навешивать нового кода обходов ошибки. И похоже от этого закрыли исходники.

Простая прикидка дает:
У нас в Lwip сконфигурирован стек в TCP_WND = (4 * TCP_MSS), где TCP_MSS 1460 байт. Итого на буфер приема и передачи на одно соединение получаем 1460*8=11680 байт, плюс экстра буфер на 1 TCP_MSS. При этом ограничение открытых соединений у espconn= 5, а пользователей у AP= 4 (это по умолчанию, хотя любой эксплорер открывает сразу 5-ть соединений, если порт = 80). Статическая структура в памяти remot_info premot[5], в которую они выводят информацию при поиске своего соединения (то-же не хилая в размере) ограничена этими 5-ти штуками, но не ограничено изменение кол-ва соединений espconn_tcp_set_max_con() (но это мелочи :) – пусть пользователь думает что творит).

При засылке в соединение блока более 1 MSS сразу возникает потеря данных, т.к. у espconn нет ограничения по приему и она сразу подтверждает увеличение окна TCP на максимум и копирует принятый блок из буфера Lwip (pbuf) в память (zalloc(x+1)) и вызывает пользовательскую процедуру на обработку его, а тут приходит новый пакет :)
Если даже затормозить и вычесть размер окна, то Lwip набирает более 5 килобайт в свои буфера.
Про главную ошибку espconnуже везде писал и повторяться не буду.
 
Последнее редактирование:
Сверху Снизу