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

Вопрос GPIO Interrupt + WiFi STA connect

seom

New member
День добрый всем!
Есть такая проблема, которая иногда всплывает на англоязычных сайтах, но решения пока не нашел.
Постараюсь максимально коротко.

У меня в наличии модуль ESP-01.
Прошил прошивкой, которая вешает прерывание на GPIO2, слушает входящие импульсы и инкрементирует счетчик. На тестовой плате собран генератор импульсов, порядка 300 имп/мин. (для тестирования, кнопкой много не понажимаешь)))
Отключаюсь от wifi:
wifi_station_set_auto_connect(false);
wifi_station_disconnect();
Запускаю циклический таймер (1 раз в мин.), кот. делает простую вещь, а именно выводит на консоль значение счетчика и обнуляет его (все):
os_timer_disarm(&impulse_timer);
os_timer_setfn(&impulse_timer, (os_timer_func_t *)interval_cb, (void *)0);
os_timer_arm(&impulse_timer, DELAY, 1);
Данная прошивка работает без сбоев сутками.
---------------------------------------------------
В следующем варианте прошивки, подкючаюсь к WIFI в режиме STATION_MODE.
WIFI_Connect(STA_SSID, STA_PASS, wifiConnectCb);
Функция взята из exemples-ов, проект esp_mqtt.
Отдельно, без прерываний тестировал, проблем не обнаружил (корректно подключается к AP, переподкючается после потери связи, работает долгое время...)
---------------------------------------------------
А вот проблема возникает, когда прерывания обрабатываются вместе с поддержкой сетевого соединения. Стабильно, где то раз в час, вываливается исключение:
6:05:28.132, Fatal exception 0(IllegalInstructionCause):
6:05:28.132, epc1=0x40244c04, epc2=0x00000000, epc3=0x00000000, excvaddr=0x00000000, depc=0x00000000
6:05:28.132,
6:05:28.132, ets Jan 8 2013,rst cause:4, boot mode:(3,7)
6:05:28.132,
6:05:28.132, wdt reset

причем ВСЕГДА по одному и тому же адресу.
Если дизассемблировать app.out, то по этому адресу находится следующее:
40244c04 <gpio_intr_dispatcher>:
40244c04: fffa31 l32r a3, 40244bec <WIFI_Connect+0xa0>

Если в процессе работы модуля отключаю генератор импульсов, то и исключения перестают возникать.

Понимаю, что возникновение исключения как то связано с обработкой прерываний и одновременной поддержкой коннекта. Понимаю, что кол-во прерываний ОТНОСИТЕЛЬНО велико. Если бы надо было только отправлять данные, то от сети можно было бы отключаться, а по надобности подключаться и передавать данные. Но в перспективе должен получать управляющие команды с MQTT сервера, поэтому коннект нужен всегда.

Пользуюсь UDK Версия 2.0.9

Заранее очень благодарен за помощь.
 

CHERTS

Moderator
Команда форума
Ну начнем с того, что UDK тут скорее всего не виновата, а дело либо в вашей прошивке, либо в SDK от китайцев, но чтобы это понять нужно видеть код вашей прошивки, а так мы будем занимать гаданием на кофейной гуще.

Попробуйте использовать UDK 2.1.0 Beta и попробовать собрать Вашу прошивку с разными Espressif SDK, возможно что-то измениться.
 

pvvx

Активный участник сообщества
А вот проблема возникает, когда прерывания обрабатываются вместе с поддержкой сетевого соединения. Стабильно, где то раз в час, вываливается исключение
Если ошибка не у вас, то уменьшите время обработки прерывания GPIO.
Китайская часть обработки WiFi в любых исполнениях в каких-то моментах не терпит аппаратных прерываний на более 1 us.
Но скорее всего у вас свои ошибки...
 

seom

New member
Спасибо за ответ.
Да, действительно, пробовал только с Espressif SDK 1.5.
Следующим шагом попробую UDK 2.1.0 Beta и другие версии Espressif SDK.
Ниже код, до которого ужался, что бы отловить исключение.
WIFI_Connect - функция из проекта esp_mqtt

___________________________________________
Код:
static uint32 ImpCnt = 0;
void wifiConnectCb(uint8_t status)
{
   if(status == STATION_GOT_IP){
     os_printf("Connecting OK ");
   } else {   }
}
//---------------------------------------------------------------------
LOCAL void ICACHE_FLASH_ATTR interval_cb(void *arg)
{
   os_printf("%d seconds! (Imp=%d)\r\n", DELAY/1000, ImpCnt);
   if(ImpCnt > 0)
      ImpCnt = 0;
}
//---------------------------------------------------------------------
LOCAL void ICACHE_FLASH_ATTR intr_callback(unsigned pin, unsigned level)
{
   ImpCnt++;
}
//---------------------------------------------------------------------
void user_init(void)
{
uart_init(BIT_RATE_115200, BIT_RATE_115200);

os_delay_us(1000);

WIFI_Connect(STA_SSID, STA_PASS, wifiConnectCb);

   GPIO_INT_TYPE gpio_type;
   gpio_type = GPIO_PIN_INTR_POSEDGE;
   if (set_gpio_mode(GPIO_2_PIN, GPIO_INT, GPIO_PULLUP)) {
     if (gpio_intr_init(GPIO_2_PIN, gpio_type)) {
       gpio_intr_attach(intr_callback);
     }


os_timer_disarm(&impulse_timer);
os_timer_setfn(&impulse_timer, (os_timer_func_t *)interval_cb, (void *)0);
os_timer_arm(&impulse_timer, DELAY, 1);
}
}
___________________________________________
 
Последнее редактирование:

seom

New member
Скомпилировал прошивку с Espressif SDK 1.3 и вот уже в течение 2-х часов все работает без сбоев! Конечно боюсь опередить события, но до сих пор, больше часа без единого исключения прошивка не работала.
 
Сверху Снизу