Extraia caracteres de uma porta serial

Extraia caracteres de uma porta serial

Tenho uma pergunta fictícia para você: estou tentando extrair algumas linhas de um arquivo começando por uma sequência especial de caracteres e copiá-las para um arquivo. Tentei :

cat /dev/ttyACM0 | grep "something" > essai

O arquivo é criado, mas não contém nada!

Responder1

Para maior eficiência, grep e muitos outros comandos usamE/S armazenada em buffer, isto é, eles leem grandes blocos de dados de uma só vez (em vez de, digamos, um caractere por vez) e não geram dados até que uma certa quantidade tenha sido acumulada (em vez de, digamos, escrever uma linha por vez ou um personagem por vez)

Mas, quando a entrada de um programa vem de um terminal (como sua porta serial), o sistema operacional faz um favor ao programa e retorna uma linha por vez (o programa pode mudar isso colocando o terminal emcruoumodo não canônico; a maioria não).

E quando um programa usa oestúdiobiblioteca, a saída padrão para um terminal (a documentação chama isso de "dispositivo interativo") é, por padrão, armazenada em buffer de linha, mas a saída para um arquivo ou canal é totalmente armazenada em buffer.

Um programa que usa a biblioteca stdio pode escolher buffer completo, buffer de linha ou nenhum buffer chamandosetvbuf. Também pode ligarfflushpara forçar uma gravação sempre que desejar.

GNU grep leva um--line-bufferedopção, que executará oseguinte códigona função que gera uma linha correspondente:

if (line_buffered)
  fflush (stdout);

Juntando todas as peças:

Com este comando:

cat /dev/ttyACM0 | grep "something" > essai

catlerá uma linha por vez de /dev/ttyACM0. Depois de acumular alguns kilobytes de saída, ele gravará no pipe. Ele repetirá isso até que a leitura retorne uma contagem zero ou falhe (o que provavelmente não acontecerá até que a porta serial fique offline).

greplerá alguns kilobytes por vez do pipe e, depois de acumular alguns kilobytes de saída, gravará no essaiarquivo. Ele repetirá isso até que a leitura retorne uma contagem zero ou falhe, o que acontecerá se e quando o catprocesso for encerrado.

Portanto, você não verá nada aparecer no essaiarquivo até grepencontrar alguns kilobytes de linhas correspondentes.

Para obter a saída gravada no arquivo mais rapidamente, você pode dar ao GNU grep essa opção:

grep --line-buffered < /dev/ttyACM0 > essai

Como está lendo de uma porta serial, ele será armazenado em buffer de linha e a --line-bufferedopção também armazenará a linha de saída em buffer.

informação relacionada