Действительно ли Ticker.h безопасно использовать?

У меня есть этот код

#include <Ticker.h>  //Библиотека тикеров
Ticker blinker;
/* ... */

//blinker.attach(1, []() { digitalWrite(LED,!digitalRead(LED)); }
while(!client.connect(laptop,port)) {
   Serial.println("Connecting...");
   delay(1000);
}

Все работает нормально, пытается подключиться, а затем подключается.

Если я раскомментирую строку, прикрепленную к этому «мигающему» тиккеру, то произойдет сбой сразу после первой печати «Соединение...». Когда я смотрю на трассировку стека, там упоминается, что сбой происходит во время задержки (1000) в моем цикле while (который, предположительно, является моментом, когда программа завершает работу и мигатель может выполнить некоторую работу)

Могу ли я что-нибудь сделать, чтобы этот таймер работал лучше?

, 👍0

Обсуждение

Из какой библиотеки объект «мигалка»? Где в игру вступает «Timer.h» из названия?, @Gerben

Я был в замешательстве - я имел в виду Ticker.h - я обновил код, чтобы сделать его более понятным - извините за это, @joelhoro

Какое сообщение появляется после сбоя? Чтобы увидеть это, вам придется установить скорость терминала на 74400. Это будет выглядеть примерно так: «ets 8 января 2013 г., первая причина: 2, режим загрузки: (3,6)» — номер «первой причины:» является самым важным., @romkey

По какой-то причине не удалось получить первопричину..., @joelhoro


1 ответ


4

Обновление: в исходном вопросе упоминались таймеры, поэтому этот ответ предназначен для обработчика прерываний аппаратного таймера. Это не относится к Ticker, о чем сейчас и идет вопрос.

Обратный вызов, который вы прикрепляете к blinker, будет вызываться как обработчик прерывания, поэтому важно убедиться, что он уже загружен в память исполняемых инструкций (iRAM) на ESP8266. Когда вы передаете анонимную функцию в blinker.attach(), она не помечается для хранения в iRAM.

Вместо этого попробуйте следующее:

void ICACHE_RAM_ATTR blinker_handler(){
    digitalWrite(LED,!(digitalRead(LED)));  //Переключить вывод светодиода
}

...

blinker.attach(1, blinker_handler);

ICACHE_RAM_ATTR сообщает системе, что код должен храниться в оперативной памяти инструкций. У нас не так много iRAM (32 Кбайт), поэтому не стоит делать это слишком часто, но это важно для обработчиков прерываний (еще одна причина делать их короткими и приятными).

,

о, это очень полезно, спасибо. Я использовал тикеры в других случаях, и, похоже, они работали нормально, хотя я прикреплял к ним обратные вызовы вместо IRAM (о чем я понятия не имел). Я попробую ваше предложение., @joelhoro

Подскажите, пожалуйста, какова цель timer1_write(600000);?, @Mark Smith

@MarkSmith Я думаю, это было в исходном примере до его обновления., @romkey

@joelhoro с обновлением — теперь, когда мы говорим о тикере, а не о таймере, — я не думаю, что это правильный ответ. Я думал, вы говорите об обработчике прерываний аппаратного таймера - это было бы правильно. Но я уверен, что обратный вызов Ticker не работает как обработчик прерываний. Я отредактирую ответ, чтобы указать на это, но думаю, что будет другое решение., @romkey