기존 이솝 임베디드 포럼의 지식인 서비스가 게시판 형태로 변경되었습니다.

리눅스에서 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 함수로 써서 진행해도 똑같이 저런식으로 나오게 됩니다.


새삶

2012.05.08 20:52:27
*.106.196.64

read() 함수가 한번에 다 읽을 것이라고 생각하는게 잘못 되었네요..

네트웍 소켓통신에서도 마찬가지인데 예를들어 1024 바이트를 읽으려고 할때 다 read 할수도 있고 못할수도 있습니다.

시리얼 통신에선 속도가 더 느리기 때문에 잘 나타나는 것 뿐이구요.

특정 바이트 만큼 읽으려면 특정 바이트만큼 루프 돌면서 읽으셔야 하고요..

특정 문자열까지 읽는다면 특정 문자열 나올때까지 읽으셔야 합니다.

저도 readn()이라고 함수 따로 만들어서 자주 사용하는데 google.에서 readn source 로 검색하니 소스가 있네요.

조현호

2012.05.08 23:29:08
*.131.182.195

흠... 네 댓글 잘 봤습니다.


일단 특정 바이트 만큼 읽는 구조에서 그만큼 루프 도는걸 못하게 되어있습니다.


패킷 크기가 몇가지 종류가 있기 때문이죠


거기다 특정 문자열까지 읽는 구조도 패킷 자체에 stx 와 etx 를 만들어 놓았지만


실제 payload 나 data 부분에 etx 가 포함될 가능성도 배제할수는 없기 때문입니다.


이 부분은 timeout 이랑 최소 문자 갯수 두개의 조합으로 해야될것 같은데


해결책이 도무지 보이지 않고 있습니다. ㅠ 

새삶

2012.05.08 23:41:22
*.106.196.64

패킷 크기가 가변적 이라면 데이터를 header와 body로 나누어서 header에서 body의 size를  얻고 다음에 body를 루프돌아 얻거나 그런 구조로 되어 있지 않을까요.?

패킷의 크기도 넘어오지 않는데 패킷은 가변적이라면은 어떤 프로그램에서도 처리 못할 것 같습니다. 프로토콜 설계 단계에서 당연히 고민되었을 거라고 생각되는데 처음 한,두 바이트 정도에 size 정보가 포함되어 있다거나 암튼 size정보를 알 수 있는 방법이 프로토콜에 포함되어 있거나, 혹시 없다면 포함되어야 할 것 같습니다.

조현호

2012.05.09 05:53:55
*.131.182.195

엄밀히 말하면 패킷 크기가 가변적인 사항은 아닙니다 저기 위에 read() 함수 안에 50이라고 쓰여져 있는데


패킷 크기가 50 미만입니다. 그렇기에 27byte 읽고 read 함수가 리턴이 되야 되는데 


도중에 리턴이 되는 현상이 발생되서 질문을 드린것입니다.


지금 제가 만든 패킷에 buf[1] 값에 패킷의 length 가 적혀 있습니다. 하지만 이 length 를 읽고


length  만큼 읽어라 하기전에 read() 함수가 제멋대로 리턴되는 현상이 발생되어 질문을 드린것입니다.

새삶

2012.05.09 18:07:48
*.106.196.64

첫 댓글에 달았듯이 read()함수가 50byte다 읽을 거라고 생각하신게 실수이세요. 

read()함수는 읽을 수 있는 만큼 읽고 리턴 합니다. 50byte읽으라고 했다고 무조건 읽진 않습니다. 네트웍 소켓 통신이나 시리얼 통신이나 마찬가지인데 시리얼 통신이 느려서 잘 나타난거구요..

read함수로 buf[1]을 먼저 받아서 length정보를 얻고 루프 돌면서 read해서 리턴값의 합이 length가 될때까지 읽으셔야 합니다.

좀 더 좋은 코드가 되려면 블럭모드라면은 read전에 select로 timeout을 체크하면 더 좋겠죠.. 먄약 length가 잘못된 값이 들어오면 계속 읽으려서고 해서 블럭 될 수도 있거든요.

조현호

2012.05.09 18:14:56
*.131.182.195

아 감사합니다. 


다시 차근 차근 진행해보겠습니다. 


그럼 시리얼 통신이 느려서 그런것일수도 있겠네요 


다시 진행해서 안되는 부분이 있다면 다시 질문 드리겠습니다.

문철민

2012.05.09 19:10:25
*.140.159.164

한번읽을때 타임아웃을 1ms를 주셨네요

1ms에 27바이트를 못읽는듯

보통은 아래와 같이 많이 사용합니다 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,1);

                                printf("buf[%d]\n",i,buf[0]);

                        }

조현호

2012.05.10 05:11:22
*.131.182.195

아 네 알겠습니다. 이 방법으로도 해보겠습니다.


감사합니다.

List of Articles
번호 제목 글쓴이 날짜 조회 수
5348 tv-out이 되지 않습니다. file [1] jclab 2012-05-13 1396
5347 WinCE 상에서 SoftAP(HostAP) [3] 신현호 2012-05-10 1505
» 리눅스 UART RX 수신 관련 문의 [8] 조현호 2012-05-08 1917
5345 LCD Flicker 현상에 대응법 [2] 훌러덩 2012-05-08 2094
5344 C110 Full HD 인코딩 [3] people2 2012-05-08 1917
5343 최종 signing 이 궁금합니다. 동전귀신 2012-05-06 909
5342 udev Arm cross compile 문의 드립니다. [6] Supsupi 2012-05-05 3084
5341 BUG: soft lockup detected on CPU#0! <== 이 오류 발생하는 ... [1] 문철민 2012-05-04 2280
5340 라이센스 문의(GPLv2) [1] 다콩 2012-05-03 1456
5339 제 u-boot의 config.mk파일의 시작은 TEXT_BASE = 0x23f00000 입... file [3] 혜민아빠 2012-05-03 1898
5338 u-boot가 동작하는 sdram영역 설정은 어디서 해야 하나요? 혜민아빠 2012-05-03 878
5337 S3C24XX USB OHCI Driver kingdomy 2012-05-03 1069
5336 S3C6410 Test Firmware 사용법 [1] jclab 2012-05-01 1759
5335 Open Source Media P layer에 대해서… [1] 김경식 2012-05-01 1364
5334 안드로이드 해상도 변경방법은?? [2] 블루스카이 2012-05-01 3653
5333 6410보드에서 cam 동영상 저장법 질문 [2] 53% 2012-04-30 1066
5332 임베디드 리눅스를 포팅도 잘 된거 같은데 사용하는 것도 잘되고요.... [4] 혜민아빠 2012-04-26 2485
5331 s3c6410보드에서 k9f2g08u0b로 낸드부트를 하는데 부팅모드관련문의 [2] 문철민 2012-04-26 1692
5330 qt 종료후 segmentation fault, Illegal instruction 오류. Supsupi 2012-04-26 1489
5329 uboot 1.3.40을 쓰고 있는데요..파일시스템 40MB정도를 tftp를 통해... [3] 혜민아빠 2012-04-26 1656

사용자 로그인