2013-05-12 3 views
0

FIFO 레지스터를 사용하여 UART_read 함수를 만들려고하는데 어떻게 작동하는지 이해하는 데 문제가 있습니다. 읽기마다 더 많은 문자를 얻을 수 있다는 것을 이해합니다. 따라서 읽기가 프로세서를 방해하지는 않지만 시간을 절약 할 수 있습니다. 그렇다면 사용 후 어떻게 사용합니까? 나는 어디에서도 예를 찾을 수 없다.16550D UART FIFO 사용

unsigned char UART_read(void){ 
unsigned int buf; 
while(((inb(UART_LSR + UART)) & UART_LSR_DR) == 0){ 
     schedule(); 
} 
buf = inb(UART); 
return (char)buf; 
} 
+0

* "while ((inb (UART_LSR_DR)) == 0)"* 다른 질문에 댓글을 달았 기 때문에 * 작동하지 않습니다. 이 코드는 UART 레지스터가없는 I/O 주소 0x0001에서 가비지를 테스트하고 있습니다 (UART_LSR_DR은 아마도 0x01이지만 비트 마스크이며 레지스터 오프셋이나 포트 주소가 아닙니다). – sawdust

+0

코드를 편집했는데 잘 작동하는 것 같습니다. – user2170647

+0

FIFO가 아닌 while 명령문과 관련이 있습니다. – user2170647

답변

0

그것은 당신의 등록 설명서에 따라,

하는 것은 일반적으로는 FIFO 레지스터는 32 비트 길이이지만, 낮은 비트의 숫자를 사용할 수 없거나 의미가있다 : 나의 현재 기능입니다.

그래서 32 비트 길이의 FIFO에서 사용할 수 있거나 의미있는 비트 수를 설정하여 더 많은 문자를 얻을 수 있습니다. 이것을 설정하기위한 장소가 있어야합니다.

+0

내가 알기 론, 적절한 레지스터에 쓰고 읽어야하는 코드는 무엇입니까? 또는 FIFO 레지스터가 내가 읽고 자하는 문자를 잡는 방법은 무엇입니까? – user2170647

+0

* "일반적으로 FIFO 레지스터는 32 비트 길이입니다."* * "32 비트 long FIFO"*가있는 UART의 예를 제공해주십시오. 그렇지 않으면 "답변"을 수정하거나이 잘못된 게시물을 삭제하십시오. – sawdust

2

나는 두 가지 정보원을 안내 할 수 있습니다. UART 데이터 시트 및 Linux 직렬 드라이버 (Linux 커널 소스 트리 내의 드라이버/tty/serial/8250/디렉토리 및 주로 8250.c 소스 파일 내).

그러한 UART 데이터 시트는 9 장에서 http://www.ti.com/lit/gpn/ns16c552

에서 텍사스 인스트루먼트에서 제공 그것을 가지고, 내 의견, FIFO 모드 동작의 꽤 좋은 설명한다. 기본적으로 수신 된 데이터에는 두 가지 유형의 인터럽트가 있습니다. 하나는 수신 FIFO에있는 읽지 않은 데이터의 양이 설정된 임계 값에 도달했을 때 (더 많은 데이터가 도착하기 전에 OS가 수신 된 문자를 읽는 데 약간의 시간을 허용하기 위해 일반적으로 FIFO 크기보다 작아야 함) 어떤 데이터가 있지만 FIFO에 "버퍼 가득 참"경보를 올리기에는 충분하지 않습니다. 후자는 합리적인 시간에받은 단일 문자를 OS가 받도록하는 것입니다.

OS가 이러한 인터럽트를 수신하면 일반적으로 FIFO에서 가능한 한 많은 문자를 읽어야합니다 (상태 레지스터 비트를 사용하여 더 많은 데이터를 읽을 수 있는지 여부를 나타냄).

마찬가지로 전송할 때 OS는 FIFO가 가득 찼다는 표시를 수신 할 때까지 전송 FIFO에 쓸 수 있습니다. UART는 나중에 전송 FIFO가 사용할 수있는 여유 공간 (다시 구성 가능)을 가지고 있음을 알리기 위해 인터럽트를 생성합니다.

Linux에서 코드를 Linux (즉, 일반 응용 프로그램)로 작성하는 경우 인터럽트를 수신 할 수 없습니다. 반면에, 자신의 드라이버를 작성하는 경우에는 기본 8250.c UART 드라이버 대신 상호 작용하는 UART를 요구하는 드라이버인지 확인해야합니다.

+0

데이터 시트를 읽은 후, 폴링 연산에서 비트가 무엇을하는지 알고 있습니다. 이것은 현재 원하는 것입니다.하지만 여전히 FIFO가 얼마나 정확하게 작동 하는지를 볼 수 없습니다. 그들을 액세스하십시오. – user2170647

+1

FIFO는 비 FIFO 작업으로 읽는 것처럼 읽습니다. RX 데이터 inb 포트 주소를 계속 읽으십시오. FIFO가 없으면 한 문자를 읽었을 때 일반적으로 인터럽트 서비스 루틴을 종료하고 다음 RX 인터럽트가 발생할 때만 더 읽습니다. FIFO를 사용하면 상태가 FIFO가 비어 있다고 표시 될 때까지 계속 반복됩니다. 리눅스는 인터럽트 당 256 문자의 읽기를 추가로 제한하는 것처럼 보입니다. 인터럽트 서비스 루틴이 한 번에 너무 오랫동안 실행되지 않는 것 같습니다. –

+0

좋아, 내가 원하는 것에 더 가까워 졌는지 보자. 인터럽트를 사용하지 않고 현재 10자를 읽고 싶다고 가정 해 봅시다. 위의 루틴이 올 Y 르면 FIFO를 사용 가능하게하고 루프 당 하나씩 10자를 읽습니다. 나는 모든 inb (UART + UART_RX)가 배열에서 유지 될 필요가 있다고 가정하고있다. 예를 들어 나중에 사용하기 위해 읽기가 FIFO와 같은 방식으로 수행된다는 것을 알 수있다. 독서를 중단 할시기를 알기 위해 FIFO의 상태를 확인해야합니까, 아니면 자동으로 완료합니까? – user2170647