본문 바로가기
프로그래밍/OS

Linux 시리얼 통신 자동 체크 예제 프로그램 소스 코드

by 남생 namsaeng 2022. 5. 25.
반응형

준비물

  • COM port 사용 가능한 Linux Server
  • USB Serial Port 사용 가능한 Windows Client
  • USB to RS232 converter

 

1. hercules_3-2-8.exe 실행파일을 다운로드한다.

 

https://www.hw-group.com/software/hercules-setup-utility

 

Hercules SETUP utility | HW-group.com

 

www.hw-group.com

 

 

2. hercules_3-2-8.exe를 실행하고 '[Serial] > [Name]' 부분에 '[Windows Key] > [장치 관리자] > [포트(COM & LPT)] 포트번호'를 입력한다. Baud Rate는 리눅스 서버 프로그램 상에서 9600으로 설정할 것이기 때문에 9600으로 맞춰준다.

 

 

 

3. Linux에서 현재 몇 개의 시리얼 통신이 가능한지 확인한다.

[root@localhost ~]# ls /dev/ttyS*
/dev/ttyS0	/dev/ttyS1	/dev/ttyS2	/dev/ttyS3

 

 

4. 각 시리얼 통신 별로 바인딩해 줄 프로그램을 각각 작성한다.

  • SerialComm1.cpp : /dev/ttyS0
  • SerialComm2.cpp : /dev/ttyS1
  • SerialComm3.cpp : /dev/ttyS2
  • SerialComm4.cpp : /dev/ttyS3

 

<SerialComm1.cpp>

#include <stdio.h>
#include <string.h>

#include <fcntl.h>
#include <errno.h>
#include <termios.h>
#include <unistd.h>

int main() {

 int serial_port1 = open("/dev/ttyS0", O_RDWR);

 struct termios tty;

 if(tcgetattr(serial_port1, &tty) != 0) {
        printf("Error %i from tcgetattr: %s\n", errno, strerror(errno));
        return 1;
 }

 tty.c_cflag &= ~PARENB;
 tty.c_cflag &= ~CSTOPB;
 tty.c_cflag &= ~CSIZE;
 tty.c_cflag |= CS8;
 tty.c_cflag &= ~CRTSCTS;
 tty.c_cflag |= CREAD | CLOCAL;

 tty.c_lflag &= ~ICANON;
 tty.c_lflag &= ~ECHO;
 tty.c_lflag &= ~ECHOE;
 tty.c_lflag &= ~ECHONL;
 tty.c_lflag &= ~ISIG;
 tty.c_iflag &= ~(IXON | IXOFF | IXANY);
 tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL);

 tty.c_oflag &= ~OPOST;
 tty.c_oflag &= ~ONLCR;

 tty.c_cc[VTIME] = 10;
 tty.c_cc[VMIN] = 0;

 cfsetispeed(&tty, B9600);
 cfsetospeed(&tty, B9600);


 if (tcsetattr(serial_port1, TCSANOW, &tty) != 0) {
        printf("Error %i from tcsetattr: %s\n", errno, strerror(errno));
        return 1;
 }



 unsigned char msg[] =  { 't', 't', 'y', 'S', '0', '\r' };

 char read_buf1 [256];

 while(1){

   write(serial_port1, msg, sizeof(msg));

   memset(&read_buf1, '\0', sizeof(read_buf1));


   int num_bytes1 = read(serial_port1, &read_buf1, sizeof(read_buf1));


   if (num_bytes1 < 0) {
          printf("Error reading: %s", strerror(errno));
//          return 1;
   }


   printf("Read %i bytes. Received message: %s", num_bytes1, read_buf1);

 }

 close(serial_port1);

 return 0;

}

 

 

5. SerialComm1.cpp부터 SerialComm4.cpp 까지 컴파일하고 동시에 실행한다.

 

1) 4개의 소스코드 컴파일

[root@localhost ~]# g++ SerialComm1.cpp -o SerialComm1 && g++ SerialComm2.cpp -o SerialComm2 && g++ SerialComm3.cpp -o SerialComm3 && g++ SerialComm4.cpp -o SerialComm4

 

 

2) 4개의 소스코드를 실행하는 쉘 스크립트 작성

 

<init.sh>

#!/bin/sh

fork1() {(ps axf | awk '{print "./SerialComm1" }' | sh);}
fork1 &
fork2() {(ps axf | awk '{print "./SerialComm2" }' | sh);}
fork2 &
fork3() {(ps axf | awk '{print "./SerialComm3" }' | sh);}
fork3 &
fork4() {(ps axf | awk '{print "./SerialComm4" }' | sh);}
fork4 &

 

3) 쉘 스크립트 실행

[root@localhost ~]# ./init.sh

 

 

* 만약 cpp 소스코드가 작성하기 귀찮다면, 아래 내용으로 init2.sh를 구성하여 바로 실행시킨다.

 

<init2.sh>

#!/bin/sh

fork1() {(ps axf | awk '{print "cat /dev/ttyS3" }' | sh);}
fork1 &
fork2() {(ps axf | awk '{print "cat /dev/ttyS2" }' | sh);}
fork2 &
fork3() {(ps axf | awk '{print "cat /dev/ttyS1" }' | sh);}
fork3 &
fork4() {(ps axf | awk '{print "cat /dev/ttyS0" }' | sh);}
fork4 &
fork5() {(ps axf | awk '{print "sleep 5; echo ttyS3 > /dev/ttyS3" }' | sh);}
fork5 &
fork6() {(ps axf | awk '{print "sleep 5; echo ttyS2 > /dev/ttyS2" }' | sh);}
fork6 &
fork7() {(ps axf | awk '{print "sleep 5; echo ttyS1 > /dev/ttyS1" }' | sh);}
fork7 &
fork8() {(ps axf | awk '{print "sleep 5; echo ttyS0 > /dev/ttyS0" }' | sh);}
fork8 &

 

 

6. init.sh 실행결과

 

hercules serial communication
hercules serial communication

 

반응형

댓글