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

Разработка ‘библиотеки’ малого webсервера на esp8266.

PostLast

Member
Я ErrWiFiSet и дальнейший зависон на вчерашних исходниках ловил просто в режиме подключения к точке. И от настроек сети и прочего похоже не зависит. Важно только Station mode.
начинается какая-то генерация c частотой 5.7кHz
Аппаратный таймер используется? Если в его прерывании задержаться такого типа проблема возникает.
 

pvvx

Активный участник сообщества
Я вашу прошивку практически не изменил. Несколько мест пере-инициализации UART заремарил, мне UART1 сразу при старте нужен, уменьшил скорость UART0 до 74888, чтобы постоянно не переключать скорость, прерывание по GPIO3 используются, но оно в это время не срабатывает.
Низкая скорость вывода логов влияет на общую скорость.
Я тут еще одну непонятку словил: опять же часто, но не всегда, через несколько секунд после старта меняются настройки GPIO.
Это ваше управление I2C и меняет. В стандартной прошивке нет ничего меняющего GPIO без указания от пользователя.
Скорее всего вы включили вывод GPIO0 на вывод дельта-сигму в его конфиге (регистрах управления).
Устанавливать GPIO и UART-ы до вызова init_wifi() не стоит. Там, китайцы, в зависимости от переменных в esp_init_data_default меняют UART-ы и настройки GPIO. Даже настройки SPI. Зависит от значений в esp_init_data_default и часть уже описывал ранее.
 
Последнее редактирование:

vad7

Active member
Это ваше управление I2C и меняет.
Инициализация i2C только в одном месте. i2c.c из UDK.
Мой код точно не лезет ни в какие регистры управления GPIO после стартапа.
А в стартапе только прерывание на GPIO3 ставится и GPIO2, GPIO0 для i2c настраивается.

void ICACHE_FLASH_ATTR
i2c_init(void)
{
//Disable interrupts
ETS_GPIO_INTR_DISABLE();

//Set pin functions
PIN_FUNC_SELECT(I2C_SDA_MUX, I2C_SDA_FUNC);
PIN_FUNC_SELECT(I2C_SCK_MUX, I2C_SCK_FUNC);

//Set SDA as open drain
GPIO_REG_WRITE(
GPIO_PIN_ADDR(GPIO_ID_PIN(I2C_SDA_PIN)),
GPIO_REG_READ(GPIO_PIN_ADDR(GPIO_ID_PIN(I2C_SDA_PIN))) |
GPIO_PIN_PAD_DRIVER_SET(GPIO_PAD_DRIVER_ENABLE)
);

GPIO_REG_WRITE(GPIO_ENABLE_ADDRESS, GPIO_REG_READ(GPIO_ENABLE_ADDRESS) | (1 << I2C_SDA_PIN));

//Set SCK as open drain
GPIO_REG_WRITE(
GPIO_PIN_ADDR(GPIO_ID_PIN(I2C_SCK_PIN)),
GPIO_REG_READ(GPIO_PIN_ADDR(GPIO_ID_PIN(I2C_SCK_PIN))) |
GPIO_PIN_PAD_DRIVER_SET(GPIO_PAD_DRIVER_ENABLE)
);

GPIO_REG_WRITE(GPIO_ENABLE_ADDRESS, GPIO_REG_READ(GPIO_ENABLE_ADDRESS) | (1 << I2C_SCK_PIN));

//Turn interrupt back on
ETS_GPIO_INTR_ENABLE();

i2c_sda(1);
i2c_sck(1);
return;
}

Смущает то, что в отладке тишина. И вылезает в тот момент, когда к i2c шине никто не притрагивается.
 

pvvx

Активный участник сообщества
Инициализация i2C только в одном месте. i2c.c из UDK.
Мой код точно не лезет ни в какие регистры управления GPIO после стартапа.
А в стартапе только прерывание на GPIO3 ставится и GPIO2, GPIO0 для i2c настраивается.

void ICACHE_FLASH_ATTR
i2c_init(void)
{
//Disable interrupts
ETS_GPIO_INTR_DISABLE();

//Set pin functions
PIN_FUNC_SELECT(I2C_SDA_MUX, I2C_SDA_FUNC);
PIN_FUNC_SELECT(I2C_SCK_MUX, I2C_SCK_FUNC);

//Set SDA as open drain
GPIO_REG_WRITE(
GPIO_PIN_ADDR(GPIO_ID_PIN(I2C_SDA_PIN)),
GPIO_REG_READ(GPIO_PIN_ADDR(GPIO_ID_PIN(I2C_SDA_PIN))) |
GPIO_PIN_PAD_DRIVER_SET(GPIO_PAD_DRIVER_ENABLE)
);

GPIO_REG_WRITE(GPIO_ENABLE_ADDRESS, GPIO_REG_READ(GPIO_ENABLE_ADDRESS) | (1 << I2C_SDA_PIN));

//Set SCK as open drain
GPIO_REG_WRITE(
GPIO_PIN_ADDR(GPIO_ID_PIN(I2C_SCK_PIN)),
GPIO_REG_READ(GPIO_PIN_ADDR(GPIO_ID_PIN(I2C_SCK_PIN))) |
GPIO_PIN_PAD_DRIVER_SET(GPIO_PAD_DRIVER_ENABLE)
);

GPIO_REG_WRITE(GPIO_ENABLE_ADDRESS, GPIO_REG_READ(GPIO_ENABLE_ADDRESS) | (1 << I2C_SCK_PIN));

//Turn interrupt back on
ETS_GPIO_INTR_ENABLE();

i2c_sda(1);
i2c_sck(1);
return;
}

Смущает то, что в отладке тишина. И вылезает в тот момент, когда к i2c шине никто не притрагивается.
Ну как тогда у меня работает modbus и прочее? Modbus как раз на ESP-01 ставлю всегда сигнал направления шины на GPIO0 и никаких глюков.
Логический Анализатор включен вечно к одной из макеток и ничего такого не наблюдается. Как установил или как управляю GPIO после старта, так всё и работает, без глюков.
Про переустановку GPIO в китайской части init_wifi() часть описана в самом Web:
constants.gif
Так-же все состояния GPIO выводятся на странице http://aesp8266/protect/gpio.htm и там не наблюдается глюко-шевеления. :)
Получше вникайте в логику управления GPIO и не валите всё на прошивку. После общей инициализации никто ваши пины не трогает (включая китайскую часть), а в TCP2UART управляются только выходы UART.
 
Последнее редактирование:

pvvx

Активный участник сообщества
Я ErrWiFiSet и дальнейший зависон на вчерашних исходниках ловил просто в режиме подключения к точке. И от настроек сети и прочего похоже не зависит. Важно только Station mode.
Ну наверно у вас сменены настройки при старте не на стандартные. Все варианты предусмотреть невозможно - будет толстая прошивка с ненужными проверками установок, которые заданы пользователем в коде без учета всего остального. :)
И ещё раз ErrWiFiSet - это не всегда ошибки, а биты попыток установить разное для WiFi. Процедурам установок WiFi передается много параметров за раз и если что-то не нравиться им, то они и выставляют биты, но часть необходимых параметров сжирают.
В режиме ST есть только одна ветвь, зависимость которой на процессы ещё не смотрел - включение sleep при поисках внешней AP, когда её нет. Но это влияет только на временное отключение процессов.
Вот последняя прошивка на тестовом модуле:
Counter erase the last flash sector in the Chinese SDK, to save 28 bytes: 469!
469 раз сменены настройки и пересбросы. Никаких глюков. А модулю уже почти год и это только за день 469 раз он переписал последний сектор. :) Дырки в flash пока не наблюдается ни на одном тестируемом модуле. Один модуль умер, но умерла сама ESP8266.
Дык какой зависон?
 
Последнее редактирование:

vad7

Active member
Ну как тогда у меня работает modbus и прочее?
Так как глюк плавающий, а система со многими неизвестными, бывает что получается так, что он не проявляется, но стоит к примеру закоментировать одну строчку, либо изменить задержку и начинает вылезать.
У меня только веб сервер включен и SNTP, даже без websocket пока.
Сейчас, пока отлаживаю, инит портов стоит вообще в init_done_cb().
Вот вы говорите, что я где-то включаю дельта-сигму. У меня вообще нет такого когда, даже не знаю еще, как ее включить.
Потом такие глюки не только у меня проявляются, как я понял.
Может влияет медленный вывод в UART, поставлю-ка я 921600 для теста....
 
Последнее редактирование:

pvvx

Активный участник сообщества
Вот вы говорите, что я где-то включаю дельта-сигму. У меня вообще нет такого когда, даже не знаю еще, как ее включить.
Просто неправильно установить регистры GPIO.
Потом такие глюки не только у меня проявляются, как я понял.
Только у вас. У вас же везде глюки - http://esp8266.ru/forum/threads/schetchik-mikrosekund.1094/#post-15919 и ещё недавно вы использовали ets_isr_unmask(0xFFFFFFFF) и спрашивали почему глюки...
Со временем разберетесь, как надо писать обращения к портам, если есть прерывания и прочее...
Из последних тут пишут об ошибках на глючащих модулях, с неизвестной flash. И ещё об старой версии SDK 1.4.x, где глюки с подключениями STATION и вообще работой WiFi при подключениях... Но разбираться с SDK 1.4.x нет смысла, т.к. уже умерла.

Вот вам пример неправильного обращения к регистрам периферии, включая GPIO:
вы используете макросы в которых делается OR или AND со значением регистра,
а там по началу идет чтение регистра в регистр CPU. Предположим, что в этот момент произошло прерывание и тоже сменило этот регистр. Вернувшись в макрос у вас далее производится OR или AND с уже устаревшим значением и далее вписывается в регистр... Таким образом вы сбиваете работу всему остальному.
Но скорее всего у вас просто алгоритмические ошибки. Найдете и разберетесь сами, т.к. я не собираюсь выставлять напоказ ваши ошибки каждый раз.
 
Последнее редактирование:

vad7

Active member
@pvvx, ets_isr_mask(0xFFFFFFFF) я и щас использую - удобная штука оказалась, когда надо всю память через i2c распечатать. Только в конце ставлю: while(1) WDT_FEED = WDT_FEED_MAGIC;

Вот еще иногда вылазит когда перезагружаешь модуль -
Fatal exception (29):
epc1=0x402074ad, epc2=0x00000000, epc3=0x00000000, excvaddr=0x00000009, depc=0x00000000


Это здесь:
// Очистка сегмента bss // mem_clr_bss();
uint8 * ptr = &_bss_start;
while(ptr < &_bss_end) *ptr++ = 0;
 
Последнее редактирование:

pvvx

Активный участник сообщества
Вот еще иногда вылазит когда перезагружаешь модуль -
Fatal exception (29):
epc1=0x402074ad, epc2=0x00000000, epc3=0x00000000, excvaddr=0x00000009, depc=0x00000000


Это здесь:
// Очистка сегмента bss // mem_clr_bss();
uint8 * ptr = &_bss_start;
while(ptr < &_bss_end) *ptr++ = 0;
Иногда - это когда?
Когда на выводе GPIO2 уровень нуля при сбросе? Это относиться к установкам выводов для нормального старта у ESP8266 и определяет это встроенный ROM-BIOS у ESP8266. Изменить это невозможно, но повторный рестарт с GPIO2 в нуле при повторном сбросе уже сделан в новой версии, о чем описал. При GPIO2 = 0 ESP8266 производит старт без загрузки - просто запускает выполнение кода в IRAM с адреса 0x40100000, а что там не смотрит. У всех других прошивок (чужих) это вызывает бардак - если там какой код от прошлой загрузки, то flash не подключена, переменные в памяти уже изменены и новый рестарт не происходит, а происходит неизвестно что - т.е. Fatal exception. Это и исправил только в последней версии - теперь там сидит код полной перезагруки и повторная перезагрузка с GPIO2 = 0 проходит нормально, в UART при этом пишется "Jump Boot...".
В wiki с GPIO2 вообще куча ошибок esp8266_gpio_pin_allocations [ESP8266 Support WIKI] :D
mode_changes [ESP8266 Support WIKI]
Состояния выводов старта защелкиваются при отпускании RESET и по ним ROM-BIOS определяет тип загрузки.
Прочитать это состояние можно в регистре GPIO_IN (0x60000318) в битах 16..31.

PS: И, блин, нас занесли в wiki ESP8266 — Википедия
wiki_esp8266.gif
Пора смываться и передавать проект кому... :)
 
Последнее редактирование:

vad7

Active member
Когда на выводе GPIO2 уровень нуля при сбросе?
Да. Накатил ваши изменения, загрузил, тут же нажал кнопку (я CHIP_EN перегружаю) - вылезло:
epc1=0x402074e5, epc2=0x00000000, epc3=0x00000000, excvaddr=0x00000000, depc=0x00000000
Fatal exception (29):

Это тот же код, только уже в другом месте.
Попробовал помучать еще модуль кнопкой - не падает.
И кстати, пока еще не словил генерацию на GPIO0 - что помог UART в 921600?
Интересно, надолго ли...
 

pvvx

Активный участник сообщества
Да. Накатил ваши изменения, загрузил, тут же нажал кнопку (я CHIP_EN перегружаю) - вылезло:
epc1=0x402074e5, epc2=0x00000000, epc3=0x00000000, excvaddr=0x00000000, depc=0x00000000
Fatal exception (29):

Это тот же код, только уже в другом месте.
Попробовал помучать еще модуль кнопкой - не падает.
Ну кому как. CHIP_EN - это отключение внутреннего стабилизатора питания чипа. К понятию перезагрузки не относится. :p
В розетку ~220В не пробовали чип включать? :)
И кстати, пока еще не словил генерацию на GPIO0 - что помог UART в 921600?
Интересно, надолго ли...
Пока опять не произойдет прерывание в вашем коде.
Тем более у вас используется ets_isr_unmask(0xFFFFFFFF). :D:D:D
С таким подходом можно ничему не удивляться...
 
Последнее редактирование:

vad7

Active member
CHIP_EN - это отключение внутреннего стабилизатора питания чипа. К понятию перезагрузки не относится.
Тогда получается хуже, то есть это как-бы скачки напряжения. Что в реальных условиях часто бывают.

Вот вам пример неправильного обращения к регистрам периферии, включая GPIO:
вы используете макросы в которых делается OR или AND со значением регистра,
Этот код из UDK.
Да и кто знает, может функция gpio_output_set запрещает прерывания.

Тем более у вас используется ets_isr_unmask(0xFFFFFFFF). :D:D:D
Ну опечатался, бывает, ets_isr_mask, конешно, а вы сразу ехидничать. :)
 
Последнее редактирование:

pvvx

Активный участник сообщества
Тогда получается хуже, то есть это как-бы скачки напряжения. Что в реальных условиях часто бывают.
Отключение питания в реальных условиях? Это неисправность БП.
Тем более это не перезагрузка модуля, а включение по подаче питания. Вся память (включая RTC, т.к. туда не подведено внешнее питание) сплошной рандом и работает только полная загрузка со всеми GPIO выставленными как положено. Всеми - это более 7 шт.
Этот код из UDK.
Да и кто знает, может функция gpio_output_set запрещает прерывания.
Это код для примера. В том примере нет других задач.
Ну опечатался, бывает, ets_isr_mask, конешно, а вы сразу ехидничать. :)
А без разницы. Как потом то вы восстановите работоспособность системы? У неё были назначены какие-то активные прерывания, а вы их все убили навсегда. :D
Тут уже не ехидничать надо, вам много раз говорилось (по началу как-бы не замечая, в надежде что сами разберетесь) - разберитесь что творите.
 
Последнее редактирование:

vad7

Active member
Отключение питания в реальных условиях? Это неисправность БП.
Бывает электричество, знаете-ли отключают, и несколько десятков раз на дню, а может и в минуту, иногда.

Как потом то вы восстановите работоспособность системы?
В данном случае не нужно, так как отладка. А выгрузку памяти через веб буду потом писать, когда основное сделаю. Итак уже кучу времени потратил на простейшую задачу.
На AVR уже давно бы пахала, правда без веба. :)
 

pvvx

Активный участник сообщества
Бывает электричество, знаете-ли отключают, и несколько десятков раз на дню, а может и в минуту, иногда.
И? Дальше модуль включается, а не перезагружается.
При включении GPIO2 должен быть в "1" - иначе будет протектед. А вот при перезагрузке - это сделано и теперь всё равно в каком уровне GPIO2.
В данном случае не нужно, так как отладка. А выгрузку памяти через веб буду потом писать, когда основное сделаю. Итак уже кучу времени потратил на простейшую задачу.
На AVR уже давно бы пахала, правда без веба. :)
Тогда зачем пишите, что вебсвалка как-то не так работает? :) Вы все процессы SDK убили и что-то хотите?
И при чем тут AVR? Если в нем отключить прерывания для других процессов он наверно догадается сам и включит нужные? Та он хуже и давно умер. Его поел ARM. :p
 

pvvx

Активный участник сообщества
Вот начинается:
[SDK Patch] выпуск SSL на ESP8266_NONOS_SDK_V1.5.2
2. Возвращаемое значение wifi_station_get_connect_status может быть неправильным в некоторых случаях. Извините за неудобства.

Исходники в git обновлены на новые либы libnet80211.a и libmain.a и пропатчена вечная ошибка у китайцев...
SSl пока они не доделали, использоваться в вебсвалке не будет.
 
Последнее редактирование:

vad7

Active member
Тогда зачем пишите, что вебсвалка как-то не так работает?
Я описываю свою проблему, а не наезжаю на ваше творение.
Тем более, что выбрал его, как наиболее стабильное и адекватное.

И? Дальше модуль включается, а не перезагружается
Тогда тем более не понятно из-за чего падает. То, что на GPIO2 где-то 1.2V это я вольтметром измерил после циклического исключения. И если в этот момент сделать GPIO2 = 3V, то эксепшены не прекращают сыпаться.

И при чем тут AVR?
К нему есть полная, понятная дока, к тому же в одном файле.
Устройство на мк, мне думается, должно выдерживать любые пропадания питания, хоть 100 раз в минуту. И не впадать в ступор от этого. Для этого и есть всякие ватчдоги и мониторы питания.

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

Его поел микрочип, делающий более кривые мк. Убрал конкурента. Бизнес...
 
Последнее редактирование:

pvvx

Активный участник сообщества
Устройство на мк, мне думается, должно выдерживать любые пропадания питания, хоть 100 раз в минуту. И не впадать в ступор от этого. Для этого и есть всякие ватчдоги и мониторы питания.
А ESP виснет? У него, как и у других MCU есть строгое правило установки выводов по сбросу, выбирающих тип загрузки. Если вы это нарушаете - как он может работать адекватно?
Его поел микрочип, делающий более кривые мк. Убрал конкурента. Бизнес...
Микрочип ныне на другой архитектуре не на своей - MIPS32 M4K и тоже на GCC. :p AVR не выдерживает ЭМИ, практически никакого - нет опыта в военных разработках и защите I/O. Т.е. все перешли на открытые ядра (архитектуру) и на открытые компиляторы и среды разработки... Ну кроме AVR :) Да и потроха выросли в соответствии с законом Мура и всё уже не лезет в один маленький PDF.
Тогда тем более не понятно из-за чего падает. То, что на GPIO2 где-то 1.2V это я вольтметром измерил после циклического исключения. И если в этот момент сделать GPIO2 = 3V, то эксепшены не прекращают сыпаться.
Вполне возможно, вы же отключаете внутренний стабилизатор, а не RESET и фиг знает что там при таком старте идет с данного пина через его диоды в кристалл и как встает его логика от такого питания от пина GPIO...
 
Последнее редактирование:

pvvx

Активный участник сообщества
Все таки сделал подгрузку оверлеев на ходу...
ovl_sht71.gif
Вот загрузил драйвер SHT71. Он там запустился и показывает:
mdb_sht71.gifSHT71.gif
Для инициализации он взял из таблицы параметры по адресу 60, 61 - номер ножки SCL и SDA.
Далее:
в 62 - счетчик опроса датчика - новые данные. Данные с датчика усредняются за два замера в 0.54 секунды (один замер 0.27 сек). Всё делается по прерываниям и готовности датчика.
в 63 - флаг ошибки или отключенного драйвера.
в 64 - температура в 0.01 градуса (со знаком)
в 65 - влажность в 0.01% (со знаком)
Оверлеи/драйверы можно грузить и командной из web-диска. Этим снимается ограничение на 1 мегабайт исполняемой части flash...
Примерно так теперь будут грузиться драйвера/оверлеи/отладка.
Веб-свалка будет поддерживать один активный оверлей - можно загружать по очереди, когда надо. Он размещается в IRAM и может использовать все функции прошивки (таблица переменных и прочее создается для каждой версии свалки с помощью скрипта piton и потом транслируем любые оверлеи и грузим на ходу). Ограничение по размеру пока 8 кило, но если включить опцию IRAM=48к, то 16+8 кило... Rodata/bss до 1 кило (остальные переменные, кратные 4 байт, размешаем в IRAM).
Пока всё в отладке... Код не скинут, надо чистить... да допилить мелочи. На один готовый драйвер это пока не нужно... :)
Как-бы в долговременных планах есть ещё запись логов усреднений типа за 5 минут в циклический буфер на один год с десятка датчиков и выводом этих графиков с выбором даты и прочего на разные шаги - по типу точка за 5 минут, 30 минут, 8 часов и т.д. до графика за год. Часть уже писана и тоже работает...
 
Последнее редактирование:
Сверху Снизу