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 측에서는 아무 것도 수신되지 않습니다.

이유가 무엇일까요?

메모: RPI에 액세스하기 위해 VM에서 SSH를 사용하고 있으므로 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에서 다음 명령을 실행하여 /dev/ttyS0유효한 직렬 장치인지 확인하세요.

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

RasPi 측에서 물리적 직렬 연결( /dev/ttyS0또는 ) 을 사용하는 경우 RasPi Zero W에 40핀 커넥터가 납땜되어 있고 해당 커넥터의 핀 8과 10에 무언가가 연결되어 있어야 합니다. 또한 직렬 포트 액세스를 활성화하려면 을 /dev/ttyAMA0사용해야 했습니다 .raspi-config

SSH를 통해 RasPi에 액세스할 수 있다면회로망연결: 연결의 상태에 대해 전혀 알려주지 않습니다.연속물연결.

관련 정보