Попытался использовать usr::ring_buffer для выдачи отладочного лога в свободный УАРТ.
Алгоритм такой:
1. Задача заполняет его данными
2. В прерывании таймера проверяется не пуст ли буфер, если не пуст, то разрешается прерывание по пустому буферу передачика уарт.
3. В прерывании DRE посылается след.байт и запрещаются прерывания если байтов больше нет.
CODE
class TExtTxBuffer {
usr::ring_buffer<unsigned char, EXTERNAL_UART_TX_BUFFER, unsigned short> fifo;
public:
void WriteByte(unsigned char new_byte)
{
fifo.push(new_byte);
}
unsigned char ReadByte(void)
{
return fifo.pop();
}
void WriteAnsiString(unsigned char __flash *data)
{
while (*data) {
fifo.push(*data++);
}
}
void WriteAnsiString(unsigned char *data)
{
while (*data) {
fifo.push(*data++);
}
}
unsigned char BufferNotEmpty(void)
{
if (fifo.get_count())
return 1;
return 0;
}
};
void StopExtUartTx()
{
UCSR0B&=~(1<<UDRIE0);
}
#pragma vector=USART0_UDRE_vect
__interrupt void ExtUartTx()
{
OS::TISRW_SS ISRW;
unsigned char i=ExtTxPtr.ReadByte();
UDR0=i;
if (ExtTxPtr.BufferNotEmpty()==0)
StopExtUartTx();
}
В какой-то момент обнаружил что передача данных прекратилась. Остановил программу.
Увидел следующее (цифры примерные):
Код
First=10;
Last=9;
Count=0;
B соответственно код
Код
if (ExtTxPtr.BufferNotEmpty())
StartExtUartTx();
прерывание USART0_UDRE_vect запускать не стал.
Что неправильно делаю?
Неправильно объявил (не использовал volatile)?
Код
usr::ring_buffer<unsigned char, EXTERNAL_UART_TX_BUFFER, unsigned short> fifo;
Нужны ли критические секции перед вызовом BufferNotEmpty и WriteByte?
Спасибо.