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

Общие баги/глюки/проблемы в пакете Sming

manfredmann

New member
Непрерывная длительная передача данных по UART вызывает крах, и модуль перезагружается.

Есть задача, читать файл из spiffs и отсылать его по уарту.
Следующий код отправляет esp в ребут,

Код:
    char buf[BUF_SIZE];
    size_t i, r;
    while (!fileIsEOF(img_file)) {
        r = fileRead(img_file, buf, BUF_SIZE);
        for (i = 0; i < r; ++i) {
            Serial.write(buf[i]);
        }
    }
    fileClose(img_file);
BUF_SIZE равен 128. Файл достаточно большой, 180кб

Я думал, что где-то что-то делаю не так.

Код:
    int i;
    for (i = 0; i < 102400; ++i) {
        Serial.write('a');
    }
Аналогично, ESP перезагружается.
 

pvvx

Активный участник сообщества
Непрерывная длительная передача данных по UART вызывает крах, и модуль перезагружается.
Передавайте кусками по прерываниям таймера. Передали стартовый кусок в 128 байт, зарядили таймер для отработки SDK. По следующему входу в обработке таймера опять передали кусок и снова зарядили таймер, если не всё передано. Время таймера, чтобы поток был непрерывным составляет 128*кол-во бит при передаче символа UART/Baud rate. Для 9600 и 11 бит: 1 старт + 8 бит данных + 2 стоп (или 1 четности + 1 стоп) = 128*11/9600 = 0.146667 секунды или 146 ms.
При этом и WiFi и остальное будет работать.
------
Если встроить в sming данный код: https://github.com/pvvx/esp8266web/blob/master/app/sdklib/system/ets_run_new.c
То это:
Код:
    int i;
    for (i = 0; i < 1000000000; ++i) {
        Serial.write('a');
        run_sdk_tasks();
    }
будет работать.
Аналогично через ets_set_idle_cb(void * ets_idle_cb, void *arg) переделываются процедуры работы с таймером в Sming (Переключение контекстов примененное igrr не годится для arduino). При назначении процедуры таймера используется подстановка не пользовательской процедуры, а процедуры запускающей ets_set_idle_cb(пользовательская процедура, её операнд). Тогда в процедуре пользователя обработки таймера можно писать коды с временем выполнения хоть вечность, но периодически вызывая run_sdk_tasks().
 
Последнее редактирование:

anakod

Moderator
Команда форума
Результатом вполне доволен, в локалке работает отлично.
Т.е. это решает проблему с передачей данных? Мне кажется chunked без заранее указанной длины ответа не даст большого преимущества, или я что-то упускаю?

Передавайте кусками по прерываниям таймера.
Все верно. Можно конечно еще и вачдог выключать, но на долго останавливать работу модуля под свои задачи все равно совсем не хорошо.

Если встроить в sming данный код
А расскажите, пожалуйста, подробнее про реализацию? Первая версия, насколько я помню, имела ограничение - ее нельзя было вызывать в таймере. Текущая версия не имеет каких-либо доп. условий для использования? Не произойдет ли переполнения стека (рекурсии)? Верно ли я понимаю что здесь, по сути, происходит передача на итерацию исполнения основному циклу задач espressif? Сходу не совсем понял, был бы благодарен ссылке где можно почитать подробнее про ets_idle_cb, ets_idle_arg и т.д.
 

pvvx

Активный участник сообщества
А расскажите, пожалуйста, подробнее про реализацию? Первая версия, насколько я помню, имела ограничение - ее нельзя было вызывать в таймере.
Чтобы вызвать из таймера, надо в таймерную процедуру входить по другому. Это вроде описал уже. Но не обязательно использовать ets_set_idle_cb, т.к. исходники ets_run даны и вставьте туда что угодно.

Текущая версия не имеет каких-либо доп. условий для использования? Не произойдет ли переполнения стека (рекурсии)?
Данное решение потребляет во много раз меньше стека, чем решение от igrr.
Верно ли я понимаю что здесь, по сути, происходит передача на итерацию исполнения основному циклу задач espressif? Сходу не совсем понял, был бы благодарен ссылке где можно почитать подробнее про ets_idle_cb, ets_idle_arg и т.д.
Так сразу и сходу описать всё сложно. ets_idle_cb, ets_idle_arg запускаются сразу после выполнения по приоритету всяких тасков и таймеров в ets_run() или когда нет никаких актуальных/сработавших тасков и таймеров. Но чтобы цикл ets_run крутился, требуется прерывание. В ets_run всё останавливается на команде отключения проца и ожидания прерывания. После прерывания проверяются таблицы тасков и таймеров и если ничего нет, то опять встает на ожидание прерывания (малое потребление, т.к. проц заглушен).
Из стандартной ets_run "выхода нет" :), кроме как через ets_idle_cb после прерывания и проверки на сработавшие таймеры и назначенные 'таски'. И всё возвращается опять в ets_run.
Исходная ets_run из ROM-BIOS. Она вызывается после начальной инициализации, в конце call_user_start() и далее все процессы (и SDK и пользовательские) работают только из неё. По этому, если вы не завершили процедуру таймера (не передали управление в ets_run()), следующие таски и таймеры обрабатываться не будут (и не будут переключены флаги отработанных процедур в таблицах). Будут работать только аппаратные прерывания - данный глюк и наблюдаем с методом переключением контекста в Arduino IDE.
/* idle_cb(idle_arg) вызывает ets_run()
idle_cb 0x3FFFDAB0, idle_arg 0x3FFFDAB4 */
void ets_set_idle_cb(void * routine, void *arg)
{ idle_cb = routine; idle_arg = arg; }
SDK не пользуется ets_set_idle_cb().
Так-же не забываем, чтобы цикл в ets_run() "прокрутился" требуется аппаратное прерывание к примеру таймера. Иначе всё стоит на:
asm volatile ("waiti 0;"); // Wait for Interrupt
c ets_intr_lock(); !
WDT кроме его прерывания в SDK завязано теперь с таймером и проверкой исполнения тасков SDK по таблице. Если за определенное время не отработались указанные в таблице китайцев post - то будет перезагрузка.
Т.е. ArduinoIDE на сегодня = неработающая система :(, а решать как это исправить придется вам - я ей не пользуюсь.
 
Последнее редактирование:

anakod

Moderator
Команда форума
Я не пишу ArduinoIDE :), а в Sming преимущественно асинхронаая модель - поставил калбек, ждешь данне. Но как видите пользователи все равно любят "замораживать" чип на долго, поэтому Ваше решение было бы очень кстати.
И все же, как работает\что из себя представляет idle_arg? Это тоже процедура как и idle_cb? Калбак?
 

pvvx

Активный участник сообщества
Я не пишу ArduinoIDE :), а в Sming преимущественно асинхронаая модель - поставил калбек, ждешь данне. Но как видите пользователи все равно любят "замораживать" чип на долго, поэтому Ваше решение было бы очень кстати.
И все же, как работает\что из себя представляет idle_arg? Это тоже процедура как и idle_cb? Калбак?
idle_arg - это аргумент к функции idle_cb.
Вот например незя выполнить в событии wifi_station_disconnect() (или wifi_set_opmode() - он вообще там вызывает Fatal exception (28) :) ), то использую ets_set_idle_cb(stop_scan_st,NULL): https://github.com/pvvx/esp8266web/blob/master/app/web/wifi_events.c#L126
вызывающую stop_scan_st: https://github.com/pvvx/esp8266web/blob/master/app/web/wifi_events.c#L59
после завершения работы кривого китай кода, когда управление упадет обратно в ets_run().
Аналогично и тут: https://github.com/pvvx/esp8266web/blob/master/app/web/wifi.c#L460
А пользователям не решить массу задач в sming, т.к. в sming не поддерживаются основные события WiFi и работы с периферией по прерываниям т.д.
 
Последнее редактирование:

manfredmann

New member
Сделал сегодня git pull. Мой проект перестал собираться
Код:
[manfredmann@lucille DrawOnMy]$ make
C+ app/application.cpp
C+ /home/manfredmann/esp8266/Sming/Sming/appinit/user_main.cpp
AR out/build/app_app.a
LD out/build/app.out
out/build/app_app.a(application.o):(.text._ZN11ArduinoJson17DynamicJsonBuffer5allocEj[ArduinoJson::DynamicJsonBuffer::alloc(unsigned int)]+0x8): undefined re
ference to `m_printf'
out/build/app_app.a(application.o): In function `ArduinoJson::DynamicJsonBuffer::allocInOtherBlocks(unsigned int)':
/home/manfredmann/esp8266/Sming/Sming/SmingCore/Boards.h:17: undefined reference to `m_printf'
collect2: error: ld returned 1 exit status
/home/manfredmann/esp8266/Sming/Sming/Makefile-project.mk:270: ошибка выполнения рецепта для цели «out/build/app.out»
make: *** [out/build/app.out] Ошибка 1
[manfredmann@lucille DrawOnMy]$
 

condemil

New member
Кто-нибудь пробовал использовать IRsend, он у вас работал исправно? Есть предположение, что используемые задержки между дерганьем GPIO выполняются быстрее, чем необходимо для 38khz
 

alexhi

Member
Свежий Sming перестал компилится пишет:
C+ Libraries/si4432/si4432.cpp
In file included from Wiring/../include/user_config.h:27:0,
from Wiring/Arduino.h:6,
from Libraries/si4432/si4432.h:30,
from Libraries/si4432/si4432.cpp:27:
Libraries/si4432/si4432.cpp: In member function 'void Si4432::readAll()':
Libraries/si4432/si4432.cpp:400:98: error: iteration 7u invokes undefined behavior [-Werror=aggressive-loop-optimizations]
(int ) allValues[i+12], (int ) allValues[i+13], (int ) allValues[i+14], (int ) allValues[i+15]
^
system/include/esp_systemapi.h:32:48: note: in definition of macro 'debugf'
[HASHTAG]#define[/HASHTAG] debugf(fmt, ...) m_printf(fmt"\r\n", ##__VA_ARGS__)
^
Libraries/si4432/si4432.cpp:394:21: note: containing loop
for (byte i = 0; i < 0x7f; i+=16)
^
cc1plus.exe: all warnings being treated as errors
make: *** [out/build/Libraries/si4432//si4432.o] Error 1
 

Casper

Member
Скачал с GitHub Sming и заменил его c:\tools\sming\ После прошивки модуля в COM порт идут бесконечно иероглифы. Перепрошивка не помогает. Использую модуль ESP-12E
 

alexhi

Member
Проблема с однократным таймером:
запускаю таймер на 30 мин
timerRele1.stop();
timerRele1.initializeMs(1000 * 1800, timerRele1_tick).startOnce();

// далее после того как таймер запущен приходит команда по сети и переустанавливает этот же таймер другими значениями:
на 10 сек.
timerRele1.stop();
timerRele1.initializeMs(1000 * 10, timerRele1_tick).startOnce();
Но похоже таймер не перезапускается с другими значениями,а продолжает тикать с прежними.
Что может быть, timerRele1.stop(); не срабатывает?
 

aliaksei

New member
spiffy работает?

Даю команду spiffy.exe web/build 120000
Код:
Creating rom spiff_rom.bin of size 16384 bytes
Adding files in directory: files
Unable to open directory: files
Посмотрел исходники в C:\Espressif\examples\nodemcu-spiffy\, там не видно чтобы параметры комстроки как-то обрабатывались. На гитхабе https://github.com/xlfe/spiffy посмотрел - есть обработка только размера образа

Ставил из Espressif-ESP8266-DevKit-v2.0.8-x86.exe
 
Последнее редактирование:

aliaksei

New member
Сделал форк spiffy и добавил второй аргумент в командную строку https://github.com/polkabana/spiffy
Так же еще заметил spiffy требует размер образа в килобайтах, а Sming передает в байтах. Надо кому-нибудь поправить )
 

pvvx

Активный участник сообщества
Сделал форк spiffy и добавил второй аргумент в командную строку https://github.com/polkabana/spiffy
Так же еще заметил spiffy требует размер образа в килобайтах, а Sming передает в байтах. Надо кому-нибудь поправить )
У вас будет exception в https://github.com/polkabana/spiffy/blob/master/src/spiffs_gc.c#L317 и https://github.com/polkabana/spiffy/blob/master/src/spiffs_gc.c#L327
Это не все ошибки spiffs :(
После коррекции начальный адрес spiff может быть любым, но кратным 4096 байт (размеру сектора).
Так-же ваша версия spiffs вызывает WDT при диске более нескольких сотен килобайт... Но это другая история...
+ К вам могут пристать, т.к. удален файл LICENSE от spiffs...
 

aliaksei

New member
Какие ошибки, какие эксепшены? Я только добавил параметр командной строки и отправил пулл реквест автору ))
 
Сверху Снизу