내 드라이버의 작은 버퍼에 지속적으로 데이터를 밀어 넣는 외부 장치가 있다고 가정합니다. 인터럽트 처리기가 대기중인 사용자 프로세스를 깨우는 대기열을 사용하고 있습니다 (LDD (3rd edition)과 유사 함 - 처리기 구현).리눅스 장치 드라이버 버퍼링 전략
irq_handler_t irq_handler(int irq, void *dev_id, struct pt_regs *regs)
{
flag = 1;
wake_up_interruptible(&wq);
return IRQ_HANDLED;
}
ssize_t my_read(struct file *dev, char __user *buf, size_t count, loff_t *f_pos)
{
wait_event_interruptible(wq, flag != 0);
flag = 0;
copy_to_user(usr_buf, drv_buf, count);
}
/***********************User program***********************/
while(1)
{
read(fid, buffer, size);
//do stuff with data
}
사용자 프로그램은 읽기를 호출하고 인터럽트가 외부 장치에서 새 데이터를 가져올 때까지 대기합니다. 외부 장치는이 코드가 실행할 수있는 것보다 더 빨리 데이터를 푸시 할 수 있으므로 사용자 프로그램이 데이터를 복사하기 전에 데이터를 덮어 쓰지 않도록 어떤 메커니즘을 사용할 수 있습니까? 구조와 같은 링 버퍼가 여기에서 작동합니까? 그것을 구현하는 방법이 명확하지 않습니다.
감사합니다.
drv_buf가 데이터를 가져 오는 방법은 무엇입니까? copy_to_user (usr_buf, drv_buf, count)는 copy_to_user (buf, drv_buf, count) 여야합니다. –
* "사용자 프로그램에서 데이터를 복사하기 전에 데이터를 덮어 쓰지 않도록 어떤 메커니즘을 사용할 수 있습니까?"* 기본적으로 드라이버는 버퍼 오버런이 발생할 때까지 가능한 한 많이 버퍼링 할 수 있습니다. 응답에 제안 된대로 (정적으로 할당 된) 링 버퍼는 (링) 버퍼의 크기가 작을 때만 오버런을 연기 할 수 있습니다. 잘 작성된 운전자는 그러한 상태를 감지하고보고 할 수 있습니다. 동적으로 할당 된 버퍼조차도 "느린"독자에 대처할 수 없을 수도 있습니다. IOW를 사용하면 사용자 공간이 적어도 평균 속도로 도달하는 데이터를 따라 잡을 수 있어야합니다. – sawdust