내장형 하드웨어/TCP/IP

네트워크 - 시리얼 통신(멀티플렉스)

동화다아아 2011. 10. 27. 16:10
- 시리얼 통신(리눅스)
 → 두개의 창에서 시리얼 통신을 하기 위해 포트 설정을 확인한다.

 → Virtual Serial Port Driver 프로그램을 확인해 보면 COM10과 COM11이 pair로 설정되어 있다. 이것을 사용하기 위해 VMware_player에서 Settings에 들어가면 아래와 같이 두개의 Serial Port 장치를 확인할 수 있다.

 → 여기서 Device Status의 Connected와 Connect at power on의 체크 상태를 확인한다.
 → 첫번째 체크는 시리얼 포트의 연결을, 두번체 체크는 실행되었을 때 마다 자동으로 연결해 준다.
 → Serial Port와 Serial Port2는 각각 앞에 확인한 포트와 같이 COM10과 COM11로 맞추어 준다.

 →  설정이 끝났으면 지난 주 멀티플렉싱 수업시 사용했던 소스를 수정한다. 아래의 소스를 두개로 만들되 각 포트의 define값만을 다르게 한다.(#define COMPORT1 "/dev/ttyS0" 부분을 #define COMPORT1 "/dev/ttyS1"으로 바꾸어 준다.)

 → 아래는 작성된 소스이다.

#include<stdio.h>
#include<fcntl.h>

#include<sys/types.h>
#include<sys/stat.h>
#include<termios.h>
#include<sys/signal.h>
#include<unistd.h>

#define SPEED B19200
#define COMPORT1 "/dev/ttyS0" //리눅스는 1번
void Input_Incomming(int);void my_signal(int arg); // 시그널 처리 함수

char cBuff[255]; // 수신용 버퍼
volatile int iBreak = 0;
int iRet;
struct termios stOldSt1; // 기존 Serial Port1 상태 정보

int main()
{
  int iMaxFD = 0;
  int iCom1 = 0;

  struct termios stNewSt1; // 새로운 Serial Port1 상태 정보
  struct sigaction act; // sigaction 구조체 변수 선언
  fd_set stRFd; // file descriptor set
  
  iCom1 = open(COMPORT1, O_RDWR|O_NOCTTY); // 시리얼 포트 오픈
    
  if(0 > iCom1) // 시리얼 포트1 오픈 에러
  {
    perror(COMPORT1);
    exit(-1);
  }
    
  bzero(&act, sizeof(act));
  act.sa_handler = my_signal; // 시그널 처리 함수
  act.sa_flags = 0;
  sigaction(SIGINT, &act, 0); // 
  
  tcgetattr(iCom1, &stOldSt1);
  // 시리얼 포트 설정 전에 시그널 핸들러 등록
  bzero(&stNewSt1, sizeof(stNewSt1));
  
  stNewSt1.c_cflag = SPEED|CRTSCTS|CS8|CLOCAL|CREAD;
  stNewSt1.c_iflag = IGNPAR|ICRNL;
  stNewSt1.c_oflag = 0;
  stNewSt1.c_cc[VMIN] = 1// read시 리턴되기 위한 최소 문자 개수 지정
  
  tcflush(iCom1, TCIFLUSH); // 시리얼 포트 수신 큐 초기화
  tcsetattr(iCom1, TCSANOW, &stNewSt1); // 시리얼 포트에 새 속성 적용

  iMaxFD = iCom1 + 1;
  
  while(1)
  {
    // Set Descriptor
    FD_ZERO(&stRFd);
    FD_SET(iCom1, &stRFd);
    FD_SET(0&stRFd);
    // block until input
    select(iMaxFD, &stRFd, NULL, NULL, NULL);

    if(iBreak == 1)
    {
      break;
    }
    // 입력을 받는다.
    if(FD_ISSET(iCom1, &stRFd))
    {
      Input_Incomming(iCom1);
    }
    // 키보드 입력을 보낸다.
    if(FD_ISSET(0&stRFd))
    {
      memset(cBuff, 0255);
      iRet = read(0, cBuff, sizeof(cBuff));
      cBuff[iRet] = 0;
      write(iCom1, cBuff, iRet);
    }
  }
  tcsetattr(iCom1, TCSANOW, &stOldSt1); // 시리얼 포트의 원래 속성 복귀
  close(iCom1); // 시리얼 포트 닫음
  printf("End program\n");      // End main()
  return 0;
}
void Input_Incomming(int iCom1)
{
  int iCnt=0;
  iRet = read(iCom1, cBuff, 255); // 시리얼 포트로 부터 데이터 수신
  while(iRet>iCnt)
  {
    printf(" %02X ", *(cBuff+iCnt)); // hex 값으로 표시. 
    ++iCnt;
    if(0 == (iCnt%16)) // 16개마다 개행.
    {
      putchar('\n');    
    }
  }
  putchar('\n');    
  putchar('\n');    
  return ;
}
void my_signal(int arg)
{
  iBreak = 1;
  printf("\nCtrl-C pressed\n");
  return ;
}


- 통신 결과 확인
 → 송신


 → 수신