При большой частоте внешних прерывания перезагружается

Br.Misha

New member
Здравствуйте!
К есп подключено устройство, которое дергает ножку есп примерно 2-3 тысячи раз в секунду. Сразу всё было нормально, но когда добавить работу с сетью (подключение к серверу по tcp), то устройство начало перезагружаться спуска секунд 10 после запуска.
Скажите, плиз, есть ли смысл заморачиваться с обработкой прерывания такой большой частоты или лучше не париться и делать обработку этих данных на другом мк и передавать уже их потом на ЕСП?
 

Br.Misha

New member
Код:
ICACHE_FLASH_ATTR void came_intr_handler(void *arg)
{
    uint32 gpio_status = GPIO_REG_READ(GPIO_STATUS_ADDRESS);

    // if the interrupt was by GPIO4
    if (gpio_status & BIT(GPIO_BIT))
    {

        // disable interrupt for GPIO4
        gpio_pin_intr_state_set(GPIO_ID_PIN(GPIO_BIT), GPIO_PIN_INTR_DISABLE);

        //clear interrupt status for GPIO4
        GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, gpio_status & BIT(GPIO_BIT));
       
        edge = !edge;
        gpio_pin_intr_state_set(GPIO_ID_PIN(GPIO_BIT), edge ? GPIO_PIN_INTR_POSEDGE : GPIO_PIN_INTR_NEGEDGE);
       
        counter++;
    }
}
а вот инит:
Код:
    ETS_GPIO_INTR_DISABLE();

    PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO4_U, FUNC_GPIO4);
    GPIO_DIS_OUTPUT(GPIO_BIT);
    PIN_PULLUP_EN(PERIPHS_IO_MUX_GPIO4_U);

    ETS_GPIO_INTR_ATTACH(came_intr_handler, 0);

    //clear gpio4 status
    GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, BIT(GPIO_BIT));

    //enable interrupt
    gpio_pin_intr_state_set(GPIO_ID_PIN(GPIO_BIT), GPIO_PIN_INTR_POSEDGE);
    edge = 1;
    step = WAIT_PILOT;

    ETS_GPIO_INTR_ENABLE();
 

enjoynering

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

вроде ничего криминального в вашем коде нет (но я еще тот специалист), кроме как одного момента. не знаю как ESP, а в ATMEL те переменные которые будут меняться во время ISR надо объявлять так.

Код:
volatile uint32_t сounter = 0;
volatile bool edge = true;
иначе компилятор может случайно наоптимизировать переменные. ну и все макросы огородить скобками.
 
Последнее редактирование:

Br.Misha

New member
этот прикол знаю, но данные переменные используются не только в прерывании. Да и когда отключить WiFi, то этого косяка нет.
С volatile проверил - то же самое.
 

Br.Misha

New member
Пробовал убирать, чтобы с флеша не читало постоянно - перезагружается просто позже.
 

nikolz

Well-known member
Здравствуйте!
К есп подключено устройство, которое дергает ножку есп примерно 2-3 тысячи раз в секунду. Сразу всё было нормально, но когда добавить работу с сетью (подключение к серверу по tcp), то устройство начало перезагружаться спуска секунд 10 после запуска.
Скажите, плиз, есть ли смысл заморачиваться с обработкой прерывания такой большой частоты или лучше не париться и делать обработку этих данных на другом мк и передавать уже их потом на ЕСП?
Недостаточно данных для ответа.
Нужно знать:
1) Возможно ли прерывание приема этих данных либо разрыв не допустим.
2) как именно обрабатываются данные внутри колбека
3) Могут ли данные передаваться блоками и какими
Ну пока все.
 

pvvx

Активный участник сообщества
3 тысячи прерываний - это промежуток между ними в 300 us? Или они могут следовать друг за другом, пачками?
Время обработки ваших прерываний более дцати us. Для уточнения надо распечатать asm и узнать сколько там обращений к внешней шине 26 МГц с её FIFO (обращений к регистрам GPIO и прочим низко-скоростным устройствам, вызывающим сигнал ожидания CPU). Так-же надо учесть где расположен код - если он вытесняется из "кэш" Flash, то его скорость исполнения падает до примерно как CPU работает ниже 10 МГц.
Прерывать работу драйвера WiFi можно до 1 us. Иначе будут сбои.
Предел прерываний, к примеру от таймера, при одном обращении к регистру GPIO - порядка > 10 us. Далее переполнение стека или вылет WiFi. При включении CPU на 160 МГц - минимальное время сокращается до 5..7 us между прерываниями и отключенном WiFi.
Прерывание по пинам написано безграмотно и не маскируется - имеют место повторные вхождения и переполнение стека.
 
Последнее редактирование:

pvvx

Активный участник сообщества
Если ведется только подсчет импульсов, то рекомендуется использовать аппаратные возможности ESP32 или RTL у таймера.Там счет возможен до нескольких МГц.
 

Br.Misha

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

pvvx

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

nikolz

Well-known member
напоминает частотомер.
уж не помню сколько получалось
но для АЦП внутреннего получа частоту 700 кгц
а измеритель частоты делал в делькоментре то 200 кгц точно получал, может и больше было не на надо было.
Так что скорее всего надо оптимизировать ваш метод решения задачи.
Как правило на этапе выбора метода можно достигнуть выигрыша в разы, а на этапе оптимизации софта обычно не более десятка процентов.
 

pvvx

Активный участник сообщества
напоминает частотомер.
уж не помню сколько получалось
но для АЦП внутреннего получа частоту 700 кгц
а измеритель частоты делал в делькоментре то 200 кгц точно получал, может и больше было не на надо было.
Так что скорее всего надо оптимизировать ваш метод решения задачи.
Как правило на этапе выбора метода можно достигнуть выигрыша в разы, а на этапе оптимизации софта обычно не более десятка процентов.
Забудьте про это, т.к. не по теме. ТС нужно чтобы работал WiFi, а не ваши испытания с отключенным WiFi.
А во время работы WiFi у ESP8266 имеются запреты прерываний до 1 секунды. В Arduino есть ещё SPIFFS, который работает с Flash и дает запреты прерываний при чтении, записи и стирании сектора, плюс опустошение "кеш".
Предельные замеры частоты прерываний у ESP8266 можно найти на форуме, отлистав пару лет. Это исследовало много людей...
И если говорить о выборе, то для данной задачи выбран неверный чип. Счас не 2013 год, в котором появился ESP8266 и лучших альтернатив немерено.
 
Последнее редактирование:

nikolz

Well-known member
Забудьте про это, т.к. не по теме. ТС нужно чтобы работал WiFi, а не ваши испытания с отключенным WiFi.
А во время работы WiFi у ESP8266 имеются запреты прерываний до 1 секунды. В Arduino есть ещё SPIFFS, который работает с Flash и дает запреты прерываний при чтении, записи и стирании сектора, плюс опустошение "кеш".
Предельные замеры частоты прерываний у ESP8266 можно найти на форуме, отлистав пару лет. Это исследовало много людей...
И если говорить о выборе, то для данной задачи выбран неверный чип. Счас не 2013 год, в котором появился ESP8266 и лучших альтернатив немерено.
Вы что ли тему создавали?
Что вы всем указываете ?
Маразматик вы наш.
 

nikolz

Well-known member
Здравствуйте!
К есп подключено устройство, которое дергает ножку есп примерно 2-3 тысячи раз в секунду. Сразу всё было нормально, но когда добавить работу с сетью (подключение к серверу по tcp), то устройство начало перезагружаться спуска секунд 10 после запуска.
Скажите, плиз, есть ли смысл заморачиваться с обработкой прерывания такой большой частоты или лучше не париться и делать обработку этих данных на другом мк и передавать уже их потом на ЕСП?
Попробуйте отключить WDT
Поставьте
int ets_wdt_disable(void);
ets_wdt_disable();
 

valerivp

New member
Здравствуйте!
К есп подключено устройство, которое дергает ножку есп примерно 2-3 тысячи раз в секунду. Сразу всё было нормально, но когда добавить работу с сетью (подключение к серверу по tcp), то устройство начало перезагружаться спуска секунд 10 после запуска.
Скажите, плиз, есть ли смысл заморачиваться с обработкой прерывания такой большой частоты или лучше не париться и делать обработку этих данных на другом мк и передавать уже их потом на ЕСП?
У меня на ESP висит приемник 433, там частота ипульсов минимум в 10 раз выше. И перезагрузок не наблюдаю.
Так что давайте подойдем с другой стороны. Какую задачу надо решить?
 
Сверху Снизу