ttyS0 からの読み取りと書き込み

ttyS0 からの読み取りと書き込み

私は、USB 経由で仮想マシンに Raspberry PI Zero W を接続しています。これは、/dev/ttyS0PC と RPI の両方で確認できます。現在、USB ケーブル経由で RPI から仮想マシン (PC) に何かを送信しようとしています。

次のコードを使用してポートを読み取ろうとしています:

    #include <stdio.h>   /* Standard input/output definitions */    
    #include <string.h>  /* String function definitions */    
    #include <unistd.h>  /* UNIX standard function definitions */    
    #include <fcntl.h>   /* File control definitions */    
    #include <errno.h>   /* Error number definitions */    
    #include <termios.h> /* POSIX terminal control definitions */    

    /*     * 'open_port()' − Open serial port 1.     *     
    * Returns the file descriptor on success or −1 on error.     */    

   int fd; /* File descriptor for the port */

   int open_port(void)    
   {            
     fd = open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NDELAY);   

     if(fd == -1) 
     {       
       /*        * Could not open the port.        */        
       perror("open_port: Unable to open /dev/ttyS0 − ");      
     }      
     else        
      fcntl(fd, F_SETFL, FNDELAY);      

    return (fd);    
  }

  int close_port(void)
  {
    close(fd);
    return (fd);
  }


  int main()
  {
    printf("Serial reader has started...\n\n");
    while(1)
    {
      open_port();
      close_port();
    }

    return 0;
  }

RPI 側では、文字 1 を送信する小さな bash スクリプトを作成しました。

while :
do
    echo "sending character 1 to /dev/ttyS0"
    echo "1" > /dev/ttyS0
done

しかし、bash スクリプトと c プログラムの両方が連続ループで実行されているにもかかわらず、PC 側では何も受信されません。

理由は何でしょう?

注記: VM 上で SSH を使用して RPI にアクセスしているため、VM から USB 経由で RPI にアクセスできます。つまり、VM はすでに USB ポートにアクセスするように構成されているはずです。

編集: 関数 read() を実装したコードを次のように変更してみましたが、まだ変更は見られません。

    #include <stdio.h>   /* Standard input/output definitions */    
    #include <string.h>  /* String function definitions */    
    #include <unistd.h>  /* UNIX standard function definitions */    
    #include <fcntl.h>   /* File control definitions */    
    #include <errno.h>   /* Error number definitions */    
    #include <termios.h> /* POSIX terminal control definitions */    

    /*     * 'open_port()' − Open serial port 1.     *     
    * Returns the file descriptor on success or −1 on error.     */    

   int fd; /* File descriptor for the port */
   unsigned char bufptr;
   int reader;

   int open_port(void)    
   {            
     fd = open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NDELAY);   

     if(fd == -1) 
     {       
       /*        * Could not open the port.        */        
       perror("open_port: Unable to open /dev/ttyS0 − ");      
     }      
     else
     {        
      fcntl(fd, F_SETFL, FNDELAY);
      reader = read(fd, &bufptr, 1);
        if (reader > 0)
        {
          write(STDOUT_FILENO, &bufptr, 1);  
        }
     }

    return (fd);    
  }

  int close_port(void)
  {
    close(fd);
    return (fd);
  }


  int main()
  {
    printf("Serial reader has started...\n\n");
    while(1)
    {
      open_port();
      close_port();
    }

    return 0;
  }

答え1

編集では、ポートから読み取るコードを関数に追加しましたopen_port()。 うまく機能するように見えますが、これは不適切なスタイルです。open_port()関数はこのプログラムのニーズに固有のものとなり、将来のプロジェクトで変更せずに簡単に選択して再利用できなくなりました。 また、関数の名前は関数の機能を正確に表さなくなりました。

シリアル接続の設定が正しいかどうか、私には納得できません。VM を使用しており、USB が関係しているとおっしゃっていますが、/dev/ttyS0両端で使用しているようです。これは、USB ベースのシリアル ポートではなく、物理シリアル ポートを指しています。

仮想化ソフトウェアを、実際の物理シリアルポートまたはホストのUSBシリアルコンバータドライバによって生成されたシリアルポートをVMに接続するように構成している可能性があります/dev/ttyS0。それが本当であれば、PC側で機能する可能性があります。しかし、それはデフォルトではない: 仮想化ソフトウェアで必ずこれを設定する必要があります。そうしないと機能しません。

より一般的な構成は、仮想化ソフトウェアを構成して、VM が USB シリアル コンバーターの USB 側全体にアクセスできるようにすることです。すると、VM では次のように表示されます/dev/ttyUSB0(シリアル コンバーターの正確なタイプによって異なります)。

RasPi側では、/dev/ttyS0 存在しないPi Zero W のデフォルト構成では、一般的なシリアル ポートは です/dev/ttyAMA0が、デフォルト構成では Bluetooth 機能によって使用されます。USB シリアル コンバーターの USB 側を RasPi に接続した場合、/dev/ttyUSB0ここでも として表示されます。

RasPi 側のスクリプトはデバイスの存在を確認しないため、 という名前のファイルが作成され/dev/ttyS0、その中に数字が 1 行含まれている可能性があります。RasPi で次のコマンドを実行して、有効なシリアル デバイスである1かどうかを確認します。/dev/ttyS0

 test -c /dev/ttyS0 && echo "Maybe valid" || echo "Definitely not correct"

RasPi 側で物理的なシリアル接続 (/dev/ttyS0または/dev/ttyAMA0) を使用している場合は、私の理解では、RasPi Zero W の 40 ピン コネクタをはんだ付けし、そのコネクタのピン 8 と 10 に何かを差し込む必要があります。raspi-configシリアル ポート アクセスを有効にするには、 も使用する必要がありました。

SSHでRasPiにアクセスできる場合は、通信網接続:接続の状態については全く何も伝えませんシリアル繋がり。

関連情報