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

Решено rst cause 4

АндрейМ

New member
Пишу свой модуль для РК. В качестве основы взял разработку pvvx'a. Все бы хорошо, но время от времени выскакивает перегрузка от вочдога.
Архитектурно мой кусок организован по cooperativ со своим арбитром, который вызывает нужный модуль и перевзводится на следующий интервал. Длинных кусков нет (надеюсь :) ).
Сверх точность не нужна - блоки выполняются последовательно, арбитр миллисекундный.

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

Фактически интересует две вещи:
1) Каковы настройки вочдога по умолчанию?
2) Насколько велика вероятность, что вочдог реагирует на баги в SDK?

Если у кого есть опыт с подобным, поделитесь
 

nikolz

Well-known member
Пишу свой модуль для РК. В качестве основы взял разработку pvvx'a. Все бы хорошо, но время от времени выскакивает перегрузка от вочдога.
Архитектурно мой кусок организован по cooperativ со своим арбитром, который вызывает нужный модуль и перевзводится на следующий интервал. Длинных кусков нет (надеюсь :) ).
Сверх точность не нужна - блоки выполняются последовательно, арбитр миллисекундный.

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

Фактически интересует две вещи:
1) Каковы настройки вочдога по умолчанию?
2) Насколько велика вероятность, что вочдог реагирует на баги в SDK?

Если у кого есть опыт с подобным, поделитесь
Если правильно понял то вы делаете в колбеке таймера?
почему бы не делать это на стандартном SDK.
я делаю без проблем.
чтобы сказать что-то конкретное надо увидеть Ваше творение.
вочдог можете остановить или рестартовать если надо длительный цикл.
 

pvvx

Активный участник сообщества
Архитектурно мой кусок организован по cooperativ со своим арбитром, который вызывает нужный модуль и перевзводится на следующий интервал.
Необходима работа системы с вызовом ets_run() (в ROM-BIOS).
WDT имеет два цикла. Кроме WDT SDK проверяет выполнение разных тасков и второй цикл организован на другом таймере (не системном, а повязано в многих закрытых процедурах SDK... В общем это где-то к 1.5 секунде. Отключить это всё не имеется возможности. На сам опрос аппаратного WDT в моем SDK есть исходники, но это только часть всей системы WDT.
1) Каковы настройки вочдога по умолчанию?
esp8266web/wdt.c at master · pvvx/esp8266web · GitHub

вочдог можете остановить или рестартовать если надо длительный цикл.
Не остановить всю систему WDT, тем более не рестартуется он в стандартном SDK. В моем ещё кое как можно управлять аппаратной частью именно WDT, но второй части опроса с флагами тасков и таймера в исходниках нет. Таймер там не тот, который используется пользователями а который 64-х битный и вы о нем ничего не знаете... :p
 

АндрейМ

New member
Если правильно понял то вы делаете в колбеке таймера?
почему бы не делать это на стандартном SDK.
я делаю без проблем.
Код:
#define get_millis() (system_get_time()/1000)

uint32_t prev_ms = 0;
int ICACHE_FLASH_ATTR poll() {
    if (pollLock)
        return 1;

    uint32_t ms = get_millis();
    uint32_t next_poll = DEVICES_POLL_INTERVAL;
    uint8_t i;
    uint32_t save_ms = ms;
//os_printf("**poll %u %u\n", pollDriversCount, ms);

    if (ms < prev_ms) {
        ms += (0xffffffff - prev_ms);
    } else {
        ms -= prev_ms;
    }
//os_printf("**poll %u %u\n", pollDriversCount, ms);

    for (i = 0; i < pollDriversCount; i++) {
        if (pollDriver[i].nextPoll <= ms) {
            os_printf("++poll %u %u\n", i, ms);
            uint32 tstart = system_get_time();
            pollDriver[i].nextPoll = pollDriver[i].portDriver();

            tstart = system_get_time() - tstart;
            os_printf("<poll %u\n", tstart);

            if (pollDriver[i].nextPoll < 10)
                pollDriver[i].nextPoll = DEVICES_POLL_INTERVAL;
        } else {
            pollDriver[i].nextPoll -= ms;
        }
        if (next_poll > pollDriver[i].nextPoll)
            next_poll = pollDriver[i].nextPoll;
    }
    prev_ms = save_ms;
    os_timer_arm(&nextPoll_timer, next_poll, 0);
    return 1;

}
Наследство libev.
а что такое "на стандартном SDK"?

Необходима работа системы с вызовом ets_run() (в ROM-BIOS).
ets_run нашел, я так понимаю арбитр для system_os_task?
 

nikolz

Well-known member
Например так:
В user_init(void)
пишем
os_timer_setfn(&timer, (os_timer_func_t *)timer_cb,0); //назначаем колбек функцию
os_timer_arm_us(&timer,100*1000,0); //запускаем таймер на 100 мс я использую дискретность в мкс можно грубее ms
в колбек функции timer_cb исполняете нужный вам модуль и после него снова запускаете таймер например на 50 ms
os_timer_arm_us(&timer,50*1000,0);
-------------------
В user_init(void) устанавливаете счетчик модулей в ноль (count=0)
В timer_cb по счетчику вызываете очередной модуль и задержку исполнения для следующего
------------------------
В результате по таймеру с произвольно заданными интервалами вызываются сколько угодно модулей.
И не надо никаких свалок, все функции описаны в документации подробно и даже с примерами
 

АндрейМ

New member
Например так:
...
В результате по таймеру с произвольно заданными интервалами вызываются сколько угодно модулей.
И не надо никаких свалок, все функции описаны в документации подробно и даже с примерами
Если коротко - оно уже так реализовано. Только из-за гибкости необходимых обработчиков нужна несортированая очередь. Видимо я неполностью описал реализацию.

опрос датчиков разнес по ко-процедуре меньшими интервалами. И минимальный интервал для os_timer_arm поднял до 50 мс. Вроде полегчало. Возможная задержка внутри таймерного прерывания могла достигать 60-79 мс

Для модели - собственно описание копроцедуры вот и таймеры вот.
 

nikolz

Well-known member
Если коротко - оно уже так реализовано. Только из-за гибкости необходимых обработчиков нужна несортированая очередь. Видимо я неполностью описал реализацию.

опрос датчиков разнес по ко-процедуре меньшими интервалами. И минимальный интервал для os_timer_arm поднял до 50 мс. Вроде полегчало. Возможная задержка внутри таймерного прерывания могла достигать 60-79 мс

Для модели - собственно описание копроцедуры вот и таймеры вот.
Возможно что у Вас какие-то драйвера датчиков используют задержки. и циклы для ожидания готовности.
Например датчик DS1820
Я для таких датчиков делаю драйвера с использованием таймера и колбека.
 

АндрейМ

New member
Возможно что у Вас какие-то драйвера датчиков используют задержки. и циклы для ожидания готовности.
Например датчик DS1820
Я для таких датчиков делаю драйвера с использованием таймера и колбека.
Код:
int cnt;
int _1WireStatus = 0;
#define crStaticVar _1WireStatus
int ICACHE_FLASH_ATTR read1WireTemp() {
    float temp;
    crBegin
    ds18_start_convo(NULL); // all devices
    crReturn(DELAYDALLASTEMPREADY);
    int portRef;

    for (cnt = 0; cnt < MAXds18Count; cnt++) {
        if (ds18_dev.ds18_[cnt].enabled) {
            portRef = ds18_dev.ds18_[cnt].portRef;
            uint32_t stt = system_get_time();
            temp = ds18_read_tempC(&ds18_dev.ds18_[cnt].addr);
            stt = system_get_time() - stt;
            os_printf("ds_read_time %u %u ms\n", cnt, stt);
            if (temp == -1000) {
                Sensors[portRef].err = 1;
                os_printf("Error ds18@%d %d\n", cnt, portRef);
            } else {
#ifdef USE_SGN2K
                if (Sensors[portRef].subpos == 0) {
                    temp += sgn2k.tempCorrectionT20;
                }
                if (Sensors[portRef].subpos == 1) {
                    temp += sgn2k.tempCorrectionT21;
                }
#endif
                Sensors[portRef].value = temp;
                Sensors[portRef].err = 0;
//        ds[cnt].PollCount++;
            }
            crReturn(DEVICE_POLL_MIN_INTERVAL);
        }
    }

crFinish
crStaticVar = 0;
return DEVICES_POLL_INTERVAL;
}
не понял пока, стоит ли дробить меньше. Тут опрос получается 11 мс.
 

pvvx

Активный участник сообщества
ets_run нашел, я так понимаю арбитр для system_os_task?
Да. Всё вызывается из него и возвращается в него. Управление ему отдается после инициализации навечно и один раз. Он вызывает task и программные таймеры.

os_printf при заполнении FIFO (сотня байт) входит в режим ожидания выводов символов и получаетcя задержка. Отключайте отладочный вывод в задачах требуемых минимальное время исполнения...
 
Последнее редактирование:

АндрейМ

New member
os_printf при заполнении FIFO (сотня байт) входит в режим ожидания выводов символов и получаетcя задержка. Отключайте отладочный вывод в задачах требуемых минимальное время исполнения...
Я почему-то так и подумал, когда увидел таймстампы на приеме ))))
 
Сверху Снизу