【问题标题】:Corrupted data over serial串行数据损坏
【发布时间】:2017-06-01 10:22:08
【问题描述】:

我有问题。我有 2 个硬件(类似于 pi),我正在尝试通过它们之间的串行电缆测试通信。两者都是基于 linux 的,但工具有限。我写了一个脚本来发送和接收文件。当我发送一个带有一些文本的 txt 文件时,一切正常。当我尝试发送二进制文件时,数据不一样,有时我得到更大的文件,有时更小,有时只是改变了一些字节。我想了好几个小时为什么会发生这种情况,我将设备设置为raw 模式(用于二进制文件)...

这是我写的脚本:

#!/bin/bash

    FILE=$2

    send()
    {
            if [ ! -f $FILE ]; then
                    echo "File $2 doesn not exist, please introduce a valid file"
            fi
            content=`cat "$FILE"` #Dump the file content into variable
            echo -E  "$content" > /dev/ttyO5 #send the whole content to the other device



    }
    receive()
    {

            if [ -f $FILE ]; then
                    echo "The file already exists. Do you want to overwrite it? (y/n
                    read opc
                    if [ "$opc" == "n" ]; then
                            exit 1
                    fi
                    rm "$FILE"
            fi

            while read -t 5 -r -n 1 c; do  # read char by char -r to avoid backslashes to be scaped
                    echo -E -n  "$c" >> $FILE # append char on file -n(to avoid creation of new lines and -E to avoid interpretation of backslashes.

            done < /dev/ttyO5

    }
    case $1 in

            's')
                    send
                    ;;
            'r')
                    receive
                    ;;
            *)
                    echo "Usage $0 [s | r] [FILE]"
                    ;;

    esac

要将设备置于raw 模式,我使用stty -F /dev/ttyO5 raw,这是设备的选项:

speed 9600 baud;stty: /dev/ttyO5
 line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>;
eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R;
werase = ^W; lnext = ^V; flush = ^O; min = 1; time = 0;
-parenb -parodd cs8 hupcl -cstopb cread clocal -crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr -icrnl -ixon
-ixoff -iuclc -ixany -imaxbel -iutf8
-opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0
ff0
-isig -icanon iexten -echo -echoe echok -echonl -noflsh -xcase -tostop -echoprt
echoctl echoke

我的想法告诉我,在解释某些字符时存在问题,并且可能会通过更改上述某些选项来解决问题。我尝试了几个,但我无法让它工作。如果有人看到我没有看到的东西,我将不胜感激。

问候

编辑:发现问题但未解决。阅读和猫不喜欢字符NULL\n。我怎么能读懂这 2 个字符?

【问题讨论】:

  • 这里的问题是您试图通过 catting 文件发送数据。如果文件是二进制文件,catting会导致垃圾输出。
  • 考虑使用类似that
  • @RamanSailopal 我不认为这是问题所在。我尝试从文件中读取每个字节的字节,并得到相同的输出。我像这样使用它while IFS= read -r -n 1 c;do echo -n "$c" &gt;&gt; /dev/ttyO5 done &lt; "$FILE"

标签: linux bash serial-port embedded


【解决方案1】:

在读取前添加IFS=以允许读取空格、制表符

 while IFS= read -t 5 -r -n 1 c; do

编辑:'\n' 和 '\0' 仍然无法读取。

比较以下两个输出

for i in {{0..9},a,b,c,d,e,f}{{0..9},a,b,c,d,e,f};do printf '\x'"$i"; done | od -c

for i in {{0..9},a,b,c,d,e,f}{{0..9},a,b,c,d,e,f};do printf '\x'"$i"; done | { while IFS= read -r -n1 c; do echo -E -n "$c";done;} | od -c

编辑:要读取换行符,请添加选项-d ''

 while IFS= read -t 5 -r -n 1 -d '' c; do

如果[[ $c = '' ]];所以在这种情况下是'\0'字符,例如使用printf'\0'来写它

以下命令证明所有字符都可以复制

for i in {{0..9},a,b,c,d,e,f}{{0..9},a,b,c,d,e,f};do printf '\x'"$i"; done | { while IFS= read -r -n1 -d '' c; do if [[ $c = '' ]]; then printf '\0'; else echo -E -n "$c";fi;done;} | od -c

编辑: 考虑到性能 read 很慢,考虑使用另一个 unix 工具:perl

perl -e '
    # $/ end of line of input, special variable
    # read one byte at time
    $/=\1;

    my $outfilename=shift;
    open $outfile,">>",$outfilename or die $!;

    while (<>) {
        # do something on output (for example print ascii number)
        print ord($_),"\n";

        # write to out file
        print $outfile "$_";
    }
' "$FILE" < /dev/ttyO5

【讨论】:

  • 谢谢,这解决了一个小问题,但主要问题仍然存在。我将上传一张图片,以使其更清晰
  • 您可能是对的,一个文件中有一些 000a 不在另一个文件中。我把 IFS= 和一些文件正确。现在我试图添加选项-d'',但它给了我非法的选项-d。我不确定我的机器是否支持该选项...还有其他方法可以查看该分隔符吗?
  • 哪个是bash的版本,你用的是内置的还是命令的? type read
  • 它是builtin
  • bash --version,操作系统?
猜你喜欢
  • 1970-01-01
  • 2012-04-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-28
  • 2015-01-30
  • 2019-11-21
相关资源
最近更新 更多