본문 바로가기
코스웨어/12년 내장형하드웨어

9.21일 수업내용 select함수 / RS232

by 알 수 없는 사용자 2012. 9. 21.
728x90
반응형

... 뭔가 부족한게 있어 죄송

빠진 부분이나 추가 자세한 설명 댓글 달아주심 감솨... ( __ )

 

Select()

- select() 시스템 호출은 동기식 다중 입출력 메커니즘을 제공한다.

- select원형 = int select(int n,

    fd_set *readfds,

          fd_set *writefds,

          fd_set *exceptfds,

          struct timeval *timeout);

- FD_SET(int fd, fd_set *set);

- FD_ZERO(fd_set *set);


그림1) struct timeval

구조체 timeval로 include 헤더파일 어딘가 정의 되어 있다.

저장 된 위치 : include/bits/time.h 파일에 보면 있다.

2개의 시간 단위를 가지며, tv_sec = 1초 / tv_usec = 1/100만 초 단위로 계산된다.


저장된 위치 : include/bits/types.h 파일에 보면 있다.

1초단위의 sec은 long int (8 or 4)byte형이고, 1/100만초 단위의 usec은 unsigned int형

4byte를 초(sec)로 저장할 수 있는 기간은 100년 조금 넘는다.

※ (1분 = 60초) * (1시간 = 60분) * (1일 = 24시간) * 365일 * 100년 = BBF8 1E00h


컴퓨터 오른쪽 하단의 시간이 흐르는 것처럼 보이는 것은 timeval에 들어가는 숫자가 ++ 되는것이다. 즉, 약 1970년 0월 0일 00시 기준으로 부터 정의되어 있는 timeval이 ++ 되어 현재 시간이

표시 되는 것이다.

우리가 시간을 바꾸게 되면 timeval의 값이 바뀌게 되는 것이 된다.


위의  첫번째 그림 12번째 LINE의 변수 fd_set readfds의 의미

bit가 준비되어 있다.

open 가능 수만큼 준비되어 있다(readfds)

표1) open가능 수만큼 준비된 bit

ㆍ 준비된 bit는 앞에서 부터 0, 1, 2, ... 으로 배열이라고 생각하자. 

 stdin(0)

stdout(1) 

stderr(2) 

...(3) 

...(4) 

...(5) 

... 

 

그림2) 위의 표1을 채우는 소스

select를 위해 존해 한다.

FD_ZERO(&readfs)는 0을 호출한다. 즉, readfds만큼 준비된 bit를 0으로 채운다.

 0

 

FD_SET(STDIN_FILENO, &readfds)는 첫번째 인자에 해당되는 곳을 1로 바꾼다. 

1

 

주석된 소스는 책의 소스 STDIN_FILENO는 STDIN 표준입력(0번)이란 의미

그러므로 첫번째 인자를 그냥 0이라고 써도 같은 소스가 된다. ( 첫번째 인자는 정수 이기때문 )

해당되는 1에서 입력이 들어오는지 모니터링 하므로, select는 블럭킹함수이다.

단, time을 줘서 일정 시간이 지나면 종료 시킬 수 있다. 다음 소스에서 분석 해보자.


그림3) select함수

2번째 인자는 읽기용으로 받아온다.

5번째가 처음 선언한 구조체 timeval의 변수 tv이다. 이것이 시간 설정을 위한것이다.

위의 그림1에 timeval은 이미 define되어 있으며, tv_sec이 1초단위를 나타낸다고 하였다.

그 1초 단위를 5초로(TIMEOUT은 5로 define되어 있다) 설정 하였으며, 그 값을 select함수에서

블럭킹 되어 있는 시간을 5초로 한다라고 말하는 소스이다.(실제로 6초 0부터 시작)

입력받기전까진 무한 블럭킹을 하고 싶을시 5번째 인자를 NULL로 설정 하면 된다.



그림4) 실행 부분

25번 LINE의 if문은 에러시 종료코드이며, else if 부분은 시간초과(5초오버)를 대비한 소스

36번 LINE은 0이 아니면... 입력이 정상적으로 이루어지면 일어나는 부분이다

    중괄호 안의 변수선언가능(단, 중괄호 끝날시 변수 사용못함... 좋지 못한 방법이다)

    첫번째 if문은 에러처리 부분이며, 두번째 if문이 입력받은 글자를 출력 해주는 부분이다.


RS232

시리얼 통신... 아랫 글(CM님이 올리신 파일) pdf를 참조

ㆍ 6Page의 Serial port 번호와 장치명

- /dev 디렉토리에 통신하는 장치들이 있으며, /dev/ttyS0가 COM1, S1이 COM2 ~ 등등까지 있다.

ㆍ 7Page의 struct termios(term:터미널 io:입출력 s:struct)

- 입출력외에 3가지 모드가 더 있다.

ㆍ 18Page의 Canonical

- 터미널의 기본 처리방법이며, 우리가 잘 알고 있는 도스에서 명령해서 엔터치는 것이다.

즉, 엔터를 쳐서 입력하는 방법이다.

ㆍ 19Page의 Non-Canonical

- 엔터의 제한 없이 몇글자 까지만 쓰면 명령으로 인식한다.

ㆍ 22Page의 #define SPEED B19200 (115200사용) / 속도설정

                  #define SPORT "/dev/ttyS1" // COM2로 설정 (S0는 COM1 S2는 COM3)

ㆍ 24Page의 tcgetattr(tc에서 get가져온다) (iDev, &stOldState);

- iDev는 포트정보를 가져와서 &stOldState에 저장한다.

이유는 25Page에 보면 close(iDev)가 보일것이다.. 받아온것을 돌려주기 위해서이다.

- bzero함수... 0으로 초기화 하는 함수이다(&stNewState구조체를 그 크기만큼 초기화)

ㆍ 25Page

- Canonical통신 방법을 사용

- bzero 앞에서 초기화 하였기 때문에 별 의미는 없다.

- 최소 1글자가 입력 되기전까진 무한대기

- 수신되기전 전달하고자 하지 않는 다른 것들을 초기화(fflush 비슷)

- 새로운 포트 적용

- 데이터 수신

- NULL 넣기

- 출력

- 원래 포트 적용 (어셈블리의 push다음 pop과 같음)

- 닫기...

728x90