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