Скрыть объявление
На нашем форуме недоступен просмотр изображений для неавторизованных пользователей. Если Вы уже зарегистрированы на нашем форуме, то можете войти. Если у Вас еще нет аккаунта, мы будем рады, если Вы к нам присоединитесь. Зарегистрироваться Вы можете здесь.

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

Тема в разделе "SDK и создание собственных прошивок", создана пользователем Br.Misha, 28 мар 2018.

  1. Br.Misha

    Br.Misha Новичок

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

    enjoynering Авторитетный участник сообщества

    Сообщения:
    580
    Симпатии:
    57
    часть кода где ISR обработчик в студию.
     
  3. Br.Misha

    Br.Misha Новичок

    Сообщения:
    50
    Симпатии:
    3
    Код (C):
    1. ICACHE_FLASH_ATTR void came_intr_handler(void *arg)
    2. {
    3.     uint32 gpio_status = GPIO_REG_READ(GPIO_STATUS_ADDRESS);
    4.  
    5.     // if the interrupt was by GPIO4
    6.     if (gpio_status & BIT(GPIO_BIT))
    7.     {
    8.  
    9.         // disable interrupt for GPIO4
    10.         gpio_pin_intr_state_set(GPIO_ID_PIN(GPIO_BIT), GPIO_PIN_INTR_DISABLE);
    11.  
    12.         //clear interrupt status for GPIO4
    13.         GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, gpio_status & BIT(GPIO_BIT));
    14.        
    15.         edge = !edge;
    16.         gpio_pin_intr_state_set(GPIO_ID_PIN(GPIO_BIT), edge ? GPIO_PIN_INTR_POSEDGE : GPIO_PIN_INTR_NEGEDGE);
    17.        
    18.         counter++;
    19.     }
    20. }
    а вот инит:
    Код (C):
    1.     ETS_GPIO_INTR_DISABLE();
    2.  
    3.     PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO4_U, FUNC_GPIO4);
    4.     GPIO_DIS_OUTPUT(GPIO_BIT);
    5.     PIN_PULLUP_EN(PERIPHS_IO_MUX_GPIO4_U);
    6.  
    7.     ETS_GPIO_INTR_ATTACH(came_intr_handler, 0);
    8.  
    9.     //clear gpio4 status
    10.     GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, BIT(GPIO_BIT));
    11.  
    12.     //enable interrupt
    13.     gpio_pin_intr_state_set(GPIO_ID_PIN(GPIO_BIT), GPIO_PIN_INTR_POSEDGE);
    14.     edge = 1;
    15.     step = WAIT_PILOT;
    16.  
    17.     ETS_GPIO_INTR_ENABLE();
     
  4. NeoroN

    NeoroN Читатель

    Сообщения:
    150
    Симпатии:
    22
    Я бы назначил отдельный МК на эту работу
     
  5. enjoynering

    enjoynering Авторитетный участник сообщества

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

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

    Код (Text):
    1. volatile uint32_t сounter = 0;
    2. volatile bool edge = true;
    3.  
    иначе компилятор может случайно наоптимизировать переменные. ну и все макросы огородить скобками.
     
    Последнее редактирование: 28 мар 2018
  6. Br.Misha

    Br.Misha Новичок

    Сообщения:
    50
    Симпатии:
    3
    этот прикол знаю, но данные переменные используются не только в прерывании. Да и когда отключить WiFi, то этого косяка нет.
    С volatile проверил - то же самое.
     
  7. enjoynering

    enjoynering Авторитетный участник сообщества

    Сообщения:
    580
    Симпатии:
    57
    похоже я нашел в чем ваша проблема - ICACHE_FLASH_ATTR

    тут остальное - ICACHE_FLASH_ATTR - ESP8266 Developer Zone
     
  8. Br.Misha

    Br.Misha Новичок

    Сообщения:
    50
    Симпатии:
    3
    Пробовал убирать, чтобы с флеша не читало постоянно - перезагружается просто позже.
     
  9. enjoynering

    enjoynering Авторитетный участник сообщества

    Сообщения:
    580
    Симпатии:
    57
    мой скудный уровень знаний иссяк. ждем что гугу скажут.
     
  10. nikolz

    nikolz Гуру

    Сообщения:
    5.076
    Симпатии:
    465
    Недостаточно данных для ответа.
    Нужно знать:
    1) Возможно ли прерывание приема этих данных либо разрыв не допустим.
    2) как именно обрабатываются данные внутри колбека
    3) Могут ли данные передаваться блоками и какими
    Ну пока все.
     
  11. pvvx

    pvvx Активный участник сообщества

    Сообщения:
    9.273
    Симпатии:
    1.318
    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.
    Прерывание по пинам написано безграмотно и не маскируется - имеют место повторные вхождения и переполнение стека.
     
    Последнее редактирование: 29 мар 2018
  12. pvvx

    pvvx Активный участник сообщества

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

    Br.Misha Новичок

    Сообщения:
    50
    Симпатии:
    3
    На самом деле, код в прерывании гораздо большего размера, я просто его уменьшил до минимума для примера, чтобы хоть как-то заработало.
     
  14. pvvx

    pvvx Активный участник сообщества

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

    nikolz Гуру

    Сообщения:
    5.076
    Симпатии:
    465
    напоминает частотомер.
    уж не помню сколько получалось
    но для АЦП внутреннего получа частоту 700 кгц
    а измеритель частоты делал в делькоментре то 200 кгц точно получал, может и больше было не на надо было.
    Так что скорее всего надо оптимизировать ваш метод решения задачи.
    Как правило на этапе выбора метода можно достигнуть выигрыша в разы, а на этапе оптимизации софта обычно не более десятка процентов.
     
  16. pvvx

    pvvx Активный участник сообщества

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

    nikolz Гуру

    Сообщения:
    5.076
    Симпатии:
    465
    Вы что ли тему создавали?
    Что вы всем указываете ?
    Маразматик вы наш.
     
  18. nikolz

    nikolz Гуру

    Сообщения:
    5.076
    Симпатии:
    465
    Попробуйте отключить WDT
    Поставьте
    int ets_wdt_disable(void);
    ets_wdt_disable();
     
  19. pvvx

    pvvx Активный участник сообщества

    Сообщения:
    9.273
    Симпатии:
    1.318
    Это вы про себя?
    Я указал ТТХ и реальные причины, по которым применение ESP8266 для данного дела негодится.
     
  20. valerivp

    valerivp Читатель

    Сообщения:
    150
    Симпатии:
    11
    У меня на ESP висит приемник 433, там частота ипульсов минимум в 10 раз выше. И перезагрузок не наблюдаю.
    Так что давайте подойдем с другой стороны. Какую задачу надо решить?
     

Поделиться этой страницей