CRITICAL_SECTION:
class critical_section_t
{
public:
critical_section_t() : StatusReg( SREG ) { cli(); }
~critical_section_t() { SREG = StatusReg; }
private:
unsigned char StatusReg;
};
#define CRITICAL_SECTION() critical_section_t cs
это просто запрет прерываний и их восстановление на выходе из секции.
if (TxNext!=TxFirst) {
// запуск новой передачи по ДМА
}
и новая работа запустится на выполнение(если TxNext!=TxFirst).
Ничего не потеряется, за исключением случая когда буфер слишком мал или поток данных слишком велик.
мы рассчитываем на то, что DMA продолжит свою работу дальше, поскольку видели его работающим до начала копирования, однако это уже не такКакже не так? ДМА конечно уже отработал, но прерывание после входа в критическую секцию ещё не случилось ( cli запретило прерывания).
Поэтому после окончания критической секции DMA свою работу не продолжит (т.к. к этому моменту уже успел остановился), а начнется исполнение процедуры прерывания, вызванного окончанием предыдущей работы, тогда как новая работа так никогда и не будет сделанаПосле критической секции возникнет прерывание в котором будет выполнена проверка: