Open aleta2020 opened 3 days ago
Может есть какой нибудь минимальный пример, где чисто пишется и читается чисто бд с одной записью? S2 у меня нет, могу заказать
извините, не понял, что значит "чисто пишется и читается чисто бд с одной записью"? Сделать циклическое чтение поля до "ошибки"?
Нет, взять бд, записать в ячейку значение и увидеть что записался мусор
В том-то и дело, что записывается и хранится то, что записывалось, а при чтении периодически происходит искажение значения. При повторном чтении прочитается, как правило, правильное значение. Вот такой скетч получился: в цикле читаю значение поля, проверяю на границы и вывожу в монитор, если выходит за диапазон.
У меня выдает такие результаты:
Для информации: S2 mini платы такого вида:
вижу багу, проявляется только на S2 =) Минимальный код
#include <Arduino.h>
#include <GyverDB.h>
GyverDB db;
void setup() {
Serial.begin(115200);
while (!Serial);
delay(500);
db.init(0, 50);
db.init(1, 50);
db.dump(Serial);
}
void loop() {
static int i;
i++;
int v;
v = db[0];
if (v != 50) {
Serial.print(i);
Serial.print(": 0 ");
Serial.println(v);
}
v = db[1];
if (v != 50) {
Serial.print(i);
Serial.print(": 1 ");
Serial.println(v);
}
}
Сбой происходит рандомно через несколько тысяч чтений....
подозреваю что проблема в самом ядре, т.к. отключение прерываний на период чтения полностью решает проблему. На плате программный USB, возможно он что то портит в рантайме и это беда
noInterrupts();
v = db[1];
interrupts();
Спасибо за информацию. Полазил по форумам - ничего похожего не нашел. Неужели никто на этом чипе с подобным не сталкивался? Это значит, что может "портиться" и какой-то другой функционал или память? А всё noInterrupts() не обернешь... Проверил выборочно предыдущие версии ядра ESP32 - такая же ситуация :-(
Не знаю, потыкал - пока не заметил каких то закономерностей, очень странное поведение
Закономерности нет: на разных платах - разная интенсивность. Даже на той же плате - после rst может частота "выбросов" измениться. "Обвешал" резисторами, конденсаторами и уменьшил мощность передатчика (как предлагают на форумах) - не помогает. :-( У меня в скетче еще запрос делается к сайту - периодически при коде 200 получаю в отладке "оборванный" json. Причем "обрывается" всегда в разных местах. Короткий текст успевает "проскочить", а длинный - обрывается. Но бывает и вообще пустой. Вот и думаю теперь: не из-за этого ли? Не разбирались: на какой операции происходит "искажение"?
Такое ощущение, что по адресу читаются некорректные данные, как такое возможно - хз. WiFi отключен
я так понимаю - возвращается значение адреса? причем одного и того же. И смещение выводимого адреса от адреса db одинаковое:
12:45:10.285 -> DB dump: 2 entries (24 bytes)
12:45:10.285 -> 00. 0x0 [Int]: 50
12:45:10.285 -> 01. 0x1 [Int]: 50
12:45:10.285 -> Адрес db: 1073488848
12:45:13.321 -> 3955: 0 1073921922
12:45:13.321 -> Разница: 433074
12:45:13.942 -> 121357: 0 1073921922
12:45:13.942 -> Разница: 433074
12:45:15.087 -> 352307: 0 1073921922
12:45:15.087 -> Разница: 433074
12:45:15.087 -> 353008: 0 1073921922
12:45:15.087 -> Разница: 433074
12:45:15.324 -> 391102: 0 1073921922
адрес db: Serial.print("Адрес db: "); Serial.println((uint32_t)&db);
разница: Serial.print("Разница: "); Serial.println(v-(uint32_t)&db);
Вопрос: в скетче v объявлено как int - почему при выводе v на печать такое число большое? Ведь int (без учета знака) 0… 65 535
Адрес объекта db никакой роли не играет, данные хранятся вообще в другом месте.
v-(uint32_t)&db
Эта разность вообще ничего не значит
int (без учета знака) 0… 65 535
Нет, размер int зависит от платформы, на еспшках это 32 бит
Если в примере перед v = db[1];
поставить delay(1);
, то некорректные данные вроде как исчезают вообще. "Вроде" - т.к. ждать долго приходится :-) , а delay заметно тормозит код. Пробовал delayMicroseconds(1000);
- тоже почти работает, а вот при delayMicroseconds(500);
появляются выбросы почти как без задержки.
В общем "костыль" сомнительный, но для данного кода существенно снижает вероятность ошибки...
Без delay на 2,4 млн. зафиксирована 41 ошибка (на 90 млн. 1436 ошибок) - существенно быстрее крутится - проще мерить.
При delayMicroseconds(500);
на 2,4 млн. циклов 33 ошибки.
При delayMicroseconds(1000);
на 2,5 млн. циклов 1 ошибка.
Код:
Запрещать прерывания выгоднее тогда
Здравствуйте! Столкнулся с проблемой: периодически при чтении полей БД, возвращаются "кривые" данные. Стал искать источник - удалил из скетча все лишнее. Пока зафиксировал проявление в виде скетча на основе примера из библиотеки Settings: Пример "выбросов" из монитора:
Скетч:
Тестировал на разных платах из разных партий:
WEMOS S2 mini (ESP32S2) - на всех проявляется в таком виде (где-то чаще "выбросы", где-то реже) - но на всех проявилось;
ESP-WROOM-32 - нет проявления;
WEMOS D1 mini - нет проявления;
По факту ошибка (если это ошибка) проявляется при чтении значения из поля. Обнаружил я ее, проверяя прочтенное значение на мин и макс допустимые значения. Пробовал и с сырыми данными работать и приводил к нужным типам (не помогло):
db[kk::slider] - причем в таком виде по команде Serial.println(db[kk::slider]) на ESP32S2 выдается значение поля, а на D1 mini - всегда большое число (видимо адрес)... db[kk::slider].toInt() db[kk::slider].toString() db[kk::slider].toText()
Искажаются разные поля: отлавливал цифровые поля и bool.
Технические данные:
Версия библиотеки - 1.1.6
SDK - v5.1.4-972-g632e0c2a9f-dirty
Какой используется МК - WEMOS S2 mini (ESP32S2) Chip is ESP32-S2FNR2 (revision v0.0) Features: WiFi, Embedded Flash 4MB, Embedded PSRAM 2MB, ADC and temperature sensor calibration in BLK2 of efuse V2 Crystal is 40MHz
Версия Arduino IDE 1.8.19