Rastreie um fluxo binário de um arquivo de dispositivo

5

Estou depurando um fluxo binário que vem de um arquivo de dispositivo. Eu gostaria de ter a saída impressa em tempo real como valores hexadecimais.

Até agora, usei tail -f /dev/ttyAPP2 | hexdump -C , mas depois que comecei a perder alguns bytes na saída, entendi que isso poderia ser uma má escolha, pois não libera os dados até que um caractere de nova linha seja encontrado.

Existe uma cauda binária não oficial , mas atualmente não posso usar essa abordagem e estou procurando uma sugestão de como conseguir isso com Outros significados?

Exemplo

Primeiro, o tty é definido para o modo raw.

stty -F /dev/ttyAPP2 raw

Aqui está o que eu recebo ao ouvir o dispositivo (isso é saída real)

root@Vdevice:/dev# hexdump -C < /dev/ttyAPP2
00000000  55 00 21 00 02 26 00 02  0b 00 09 02 06 01 00 01  
00000010  99 0c ec 45 4f 01 03 47  41 54 45 57 41 59 43 54 

No entanto, o pacote esperado deve ser (isso não é uma saída real):

root@Vdevice:/dev# hexdump -C < /dev/ttyAPP2
00000000  55 00 21 00 02 26 00 02  0b 00 09 02 06 01 00 01  
00000010  99 0c ec 45 4f 01 03 47  41 54 45 57 41 59 43 54  
00000020  52 4c 00 00 00 00 00 8b  

A outra parte do pacote é impressa na chegada do segundo pacote (esta é a saída real)

root@Vdevice:/dev# hexdump -C < /dev/ttyAPP2
00000000  55 00 21 00 02 26 00 02  0b 00 09 02 06 01 00 01  
00000010  99 0c ec 45 4f 01 03 47  41 54 45 57 41 59 43 54
00000020  52 4c 00 00 00 00 00 8b  55 00 21 00 02 26 00 02
00000030  0b 00 09 02 06 01 00 01  99 0c ec 45 4f 01 03 47
00000040  41 54 45 57 41 59 43 54  52 4c 00 00 00 00 00 8b
    
por TheMeaningfulEngineer 03.02.2016 / 17:02

2 respostas

7

Você não precisa tail -f a tty. Se estiver enviando EOF ou, se for buffer de linha, você precisará configurá-lo.

stty -F/dev/ttyAPP2 raw

Agora você pode ...

cat /dev/ttyAPP2

... conforme necessário ...

Você pode tentar ...

</dev/ttyAPP2 \
dd bs=16 conv=sync | od -vtx1

... que sincronizará todos os read() do seu dispositivo em blocos de 16 bytes, preenchidos com nulo, e assim escreverá a saída com buffer de linha (como no seu terminal) em tempo real, independentemente da taxa de transferência, embora quaisquer valores nulos à direita possam distorcer seu fluxo.

Com o GNU stdbuf e um od :

dinamicamente vinculado
stdbuf -o0 od -vtx1 </dev/ttyAPP2

... gravaria a saída em tempo real, independentemente disso.

Você também pode armazenar em buffer para um arquivo temporário como ...

f=$(mktemp)
exec 3<>"$f"; rm -- "$f"
while   dd >&3 of=/dev/fd/1 bs=4k count=1
        [ -s /dev/fd/3 ]
do      od -An -vtx1 /dev/fd/3
        echo
done    </dev/ttyAPP2 2>/dev/null

... que, embora provavelmente não seja tão eficiente quanto as outras recomendações, pode valer a pena considerar se você quiser delimitar as leituras do seu dispositivo por EOF. Eu acho a técnica útil às vezes ao trabalhar com ttys, de qualquer maneira.

Também é possível forçar hexdump a imprimir menos bytes usando o formato de impressão personalizado. O exemplo abaixo será impresso toda vez que houver 4 bytes disponíveis:

hexdump -e '4/1 "%02x " "\n"' < /dev/ttyAPP2

    
por 04.02.2016 / 02:44
2

se a solução multilinha (9 linhas) estiver ok, verifique abaixo o script hextail.sh :

#!/usr/bin/env bash

#par1==buffsize, par2=xxd-columns-width, par3=sleepVal;    defaults: 256 16 0
size=${1:-256}; cols=${2:-16}; cnt=0; hbuff=$(eval printf '00%.0s' {1..$size})
while true; do
   hbuff=${hbuff:2}$(dd bs=1 count=1 2>/dev/null | xxd -p) #shiftLeft, add 1b
   printf '3[;H'; xxd -r -p <<<$hbuff | xxd -g1 -c$cols #cursor gotoxy 1,1
   echo total bytes: $((++cnt)) ;   [ -z $3 ] || sleep $3  #...and buff show.
done

implementa a cauda binária armazenando sua representação hexa na variável bash string. Primeiro byte no buff excluído ao anexar um novo byte no final.

exemplo de comandos de teste:

1) cat /dev/urandom | ./hextail.sh 1024 32 0.2      ...with 200ms sleep
2) ./hextail.sh < /dev/ttyAPP2
    
por 03.02.2016 / 18:44