Enviar raw para serial com dados 0xA

1

Eu tento enviar para a porta serial uma string echo -ne '\x55\x90\x17\x01\x00' > /dev/ttyACM0 , monitoramento usb me mostrar esses dados:

ffff8c957536f540 2932377867 S Bo:2:005:3 -115 5 = 55901701 00

este funcionando corretamente, todos os dados enviá-lo em uma string, o comando de dispositivo aceito. mas se os dados incluírem 0xA, seus dados sempre serão divididos em duas linhas. por exemplo:

echo -ne '\x55\x90\xa\x01\xde' > /dev/ttyACM0

monitoramento usb me mostre isso:

ffff8c957536f540 3046024649 S Bo:2:005:3 -115 3 = 55900a
ffff8c957b719000 3046024661 S Bo:2:005:3 -115 2 = 01de

string dividida em 2 linhas, é claro, o dispositivo ignorou este comando.

Minha pergunta, como enviar qualquer dado com 0xA incluído. Isso algo errado com stty, eu gasto muito tempo, mas ainda não o sucesso. ou por favor confirme, isso não é possível enviar 0xA no meio da string do console Linux para uma porta serial.

    
por Victor L 24.09.2018 / 05:39

2 respostas

3

Isso se parece muito com um problema que foi discutido na lista de e-mails do Bash durante os últimos dois dias. O Bash usa o buffer de linha para saída, portanto, um printf ou echo que contém novas linhas no meio chama a chamada de sistema write() para cada "linha".

$ strace -ewrite bash -c 'echo -ne "foobar"' >/dev/null 
write(1, "foobar", 6)                   = 6
+++ exited with 0 +++

$ strace -ewrite bash -c 'echo -ne "foo\nbar\n"' >/dev/null 
write(1, "foo\n", 4)                    = 4
write(1, "bar\n", 4)                    = 4
+++ exited with 0 +++

Se o dispositivo para o qual você está gravando for sensível, isso pode resultar em mais de um pacote distinto mais adiante. Uma conexão serial ou um fluxo TCP (*) não deveria se importar, mas algo mais parecido com os pacotes UDP.

Parece que você não pode contornar isso no Bash, mas você pode usar algum outro utilitário que não divida a saída para linhas no meio de um único comando de saída. Todos os outros shells que testei imprimem o acima em uma chamada write() , e o mesmo acontece com a utilidade printf externa do GNU coreutils. Deve estar em /usr/bin/printf em Linuxes, então /usr/bin/printf '\x55\x90\xa\x01\xde' deve funcionar:

$ strace -f -ewrite /usr/bin/printf '\x55\x90\xa\x01\xde' >/dev/null 
write(1, "U0\n6", 5)            = 5
+++ exited with 0 +++

Alternativamente, você pode canalizar a saída através de dd , que por padrão armazena a saída em blocos de 512 (além do anterior), o que deve ser suficiente no seu caso. ( dd obs=512 para ser explícito sobre isso.)

(conexões TCP não devem se importar, mas a questão na lista foi exatamente sobre printf ... > /dev/tcp/... . As gravações distintas podem afetar a segmentação do fluxo TCP, e aparentemente alguns hosts com bugs se preocupam com isso. )

    
por 24.09.2018 / 11:16
0

Isso não significa que os dados sejam "divididos" em duas linhas.

Em suma, você está escrevendo os dados corretamente, é a maneira que você exibe os dados que parecem ter "duas linhas".

0xA é o caractere ascii "linefeed", que é o caractere "newline" do Unix / Linux ('\ n').

Quando você olha para os dados do monitor USB, o terminal (ou quase todos os outros softwares de exibição de texto no Unix / Linux) moverá a exibição para a próxima "linha". Na maioria dos terminais, isso significa que o driver de exibição irá inserir um retorno de carro com o avanço de linha.

A melhor maneira de verificar seus dados é capturar os dados do monitor USB e canalizá-los para o comando od , com a opção de visualizar caracteres hexadecimais ( od -t x1 ). Então você deve ver os dados reais que você escreveu.

    
por 24.09.2018 / 06:14