기존 이솝 임베디드 포럼의 지식인 서비스가 게시판 형태로 변경되었습니다.
리눅스에서 UART RX 수신에 관한 질문이 있습니다.
poll 이라는 함수를 써서 진행을 하고 있는데요
예제 코드입니다.
<meta http-equiv="content-type" content="text/html; charset=utf-8">
while(1)
{
poll_state=poll((struct pollfd *)&poll_events, 1, 1000);
//event 등록변수, 체크할 pollfd 개수, time out 시간
if(0<poll_state)
{
if(poll_events.revents & POLLIN)
{
cnt=read(fd,&buf[,50);
printf("cnt = %d \n",cnt)
for(i=0; i < cnt; i++)
{
printf("buf[%d] = 0x%x\n",i,buf[i]);
}
}
이런식으로 사용을 하고 있는데 여기서 문제가 발생이 됩니다.
어떤 모듈에서 UART 로 쓰기를 시도하는데 있어서
한번에 27 바이트 정도를 쓰는데
저 프로그램을 켜놓고 출력 상황으로 보게 되면
cnt = 8
buf[0] = 0x2f
buf[1] = 0x30
buf[2] = 0x32
buf[3] = 0x30
buf[4] = 0x39
buf[5] = 0x31
buf[6] = 0x32
buf[7] = 0x33
cnt = 12
buf[0] = 0x34
buf[1] = 0x35
buf[2] = 0x36
buf[3] = 0x37
buf[4] = 0x38
buf[5] = 0x30
buf[6] = 0x30
buf[7] = 0x30
buf[8] = 0x30
buf[9] = 0x30
buf[10] = 0x30
buf[11] = 0x31
cnt = 7
buf[0] = 0x32
buf[1] = 0x30
buf[2] = 0x31
buf[3] = 0x30
buf[4] = 0x31
buf[5] = 0x30
buf[6] = 0x33
이와 같이 출력이 됩니다.
원래 애초 예상 했던것은 cnt = 27
이 나오고 buf[27] 까지 다 출력이 되어야 하는데
도중에 poll 함수에 특성때문이지 모듈에서 UART 로 뿌려주는 속도의 차이때문인지
출력 자체가 저런식으로 나오고 있습니다.
혹시 이런 상황에 대해 해결법이나 팁 같은거 조언해주실수 있으신가요?
ps : select 함수로 써서 진행해도 똑같이 저런식으로 나오게 됩니다.
첫 댓글에 달았듯이 read()함수가 50byte다 읽을 거라고 생각하신게 실수이세요.
read()함수는 읽을 수 있는 만큼 읽고 리턴 합니다. 50byte읽으라고 했다고 무조건 읽진 않습니다. 네트웍 소켓 통신이나 시리얼 통신이나 마찬가지인데 시리얼 통신이 느려서 잘 나타난거구요..
read함수로 buf[1]을 먼저 받아서 length정보를 얻고 루프 돌면서 read해서 리턴값의 합이 length가 될때까지 읽으셔야 합니다.
좀 더 좋은 코드가 되려면 블럭모드라면은 read전에 select로 timeout을 체크하면 더 좋겠죠.. 먄약 length가 잘못된 값이 들어오면 계속 읽으려서고 해서 블럭 될 수도 있거든요.
read() 함수가 한번에 다 읽을 것이라고 생각하는게 잘못 되었네요..
네트웍 소켓통신에서도 마찬가지인데 예를들어 1024 바이트를 읽으려고 할때 다 read 할수도 있고 못할수도 있습니다.
시리얼 통신에선 속도가 더 느리기 때문에 잘 나타나는 것 뿐이구요.
특정 바이트 만큼 읽으려면 특정 바이트만큼 루프 돌면서 읽으셔야 하고요..
특정 문자열까지 읽는다면 특정 문자열 나올때까지 읽으셔야 합니다.
저도 readn()이라고 함수 따로 만들어서 자주 사용하는데 google.에서 readn source 로 검색하니 소스가 있네요.