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