Сообщение от
Improver
Как? Заменить на millis()/micros() -- в данном случае это неимоверно усложнит программу... Честно -- я не представляю, как это сделать. Можно пример кода, или ссылку на то, как можно замедлить (синхронизировать) поток записи без применения delay() или другого подобного цикла ожидания?
Задержка — это просто пустой цикл, который ничем не отличается от цикла, который эту задержку вызывает. Сейчас структура основного цикла условно говоря такая:
Код:
while (в буфере нет места) {
задержка(); /* на самом деле просто вложенный пустой цикл */
}
записать_в_буфер;
Задержка тут не является никакой частью механизма синхронизации. В последней версии скетча она выполняла "сокровенную функцию", то есть оттягивала фиаско. Синхронизация же обеспечивается любым из рассмотренных раньше способов, суть которых сводится к атомарной установке флага в одном месте и проверке его в другом. Если она сделана и исправно работает, то никаких ухищрений в виде задержек больше не потребуется:
Код:
while(в буфере нет места) { /* ничего */ };
записать_в_буфер;
Вместо двух вложенных циклов будет просто цикл.
Сообщение от
KTSerg
В прерывании, при изменении индекса CRB (или просто в конце прерывания), устанавливать флаг, а в программе ждать установки этого флага и только тогда переходить к проверке (сравнению индексов).
Контроль такого флага даст уверенность, что сравнение индексов происходит сразу по окончании прерывания и не будет "прервано"...
Непосредственно перед циклом ожидания флага, обязательно его (флаг) сбросить.
Если будет чтение сектора, потом копирование большого числа байтов, прерывание несколько раз случится за это время.
Еще можно сразу после заполнения буфера загонять ардуину в сон (тут надо долго читать, какой именно из режимов сна правильно будет работать). Она будет просыпаться только на прерывание и забивание буфера, остальное время потреблять какой-то там наноампер.