我正尝试使用中断来查看UART 16550D中是否有错误,以及何时可以读取字符。
UARTconfiguration如下:
#define UART 0x03f8 // Endereço da Porta Serial - I (com1) #define UART_IER 1 #define UART_LCR 3 #define UART_LSR 5 #define UART_DLL 0 /* Out: Divisor Latch Low */ #define UART_DLM 1 /* Out: Divisor Latch High */ #define UART_LSR_THRE 0x20 /* Transmit-hold-register empty */ #define UART_LSR_DR 0x01 /* Receiver data ready */ #define UART_RX 0 /* In: Receive buffer */ #define UART_TX 0 /* Out: Transmit buffer */ void UART_init(void){ outb( 0x80 , UART + UART_LCR ); outb( 0x00 , UART + UART_DLM ); outb( 0x60 , UART + UART_DLL ); outb( 0x1f , UART + UART_LCR ); outb( 0x07 , UART + UART_IER ); return; }
和中断
irqreturn_t short_interrupt(int irq, void *dev_id){ printk("INTERRUPT HAPPENED. WILL NOW RETURN\n"); return 0; } static int seri_init(void){ int result, i; UART_init(); request_irq(4, short_interrupt, SA_SHIRQ, "seri", NULL); ....
所以现在我只想看看处理程序是否被调用。 4被定义为我正在使用的虚拟框设置中的IRQ。
我想知道的是,这个设置有什么问题吗? 在testing时,阅读和处理我正在阅读的内容没有问题。 事情是,处理程序是从来没有被称为。
request_irq()的返回值是-22。 编译时没有问题。
我的分析为什么中断处理程序没有触发:
(1)确保传递给request_irq(virq,…)的第一个参数是硬件irq号或虚拟irq号。 在某些平台上,硬件irq和request_irq(…)使用的数字之间有一个映射。 如果在你的盒子上有一个映射,那么你错误地把你的处理程序连接到其他中断源;
(2)确保16550D上的中断屏蔽寄存器设置正确。 我认为16550D应该有一个中断屏蔽寄存器,它可以屏蔽/取消屏蔽中断事件;
(3)检查request_irq(…)的返回值,确保中断连接成功。
希望以上帮助你。
更改
outb( 0x80 , UART + UART_LCR ); outb( 0x00 , UART + UART_DLM ); outb( 0x60 , UART + UART_DLL ); outb( 0x1f , UART + UART_LCR ); outb( 0x07 , UART + UART_IER );
至
outb( 0x80 , UART + UART_LCR ); outb( 0x00 , UART + UART_DLM ); outb( 0x60 , UART + UART_DLL ); outb( 0x07 , UART + UART_IER ); // Set IER before clearing DLAB bit in LCR outb( 0x1f , UART + UART_LCR ); // You may also need outb( 8 , UART + 4 ); // Some systems use this as a master interrupt enable
-22是EINVAL
,我认为这是因为NULL最后一个参数。 本页: http : //www.makelinux.net/books/lkd2/ch06lev1sec3说:
第五个参数dev_id主要用于共享中断线。 当一个中断处理程序被释放(稍后讨论)时,dev_id提供了一个唯一的cookie来允许从中断线中仅去除期望的中断处理程序。 没有这个参数,内核就不可能知道在给定的中断线上删除哪个处理程序。 如果该行不共享,则可以在这里传递NULL,但是如果中断线路是共享的,则必须传递一个唯一的cookie
所以请求与NULLed dev_id共享irq将无法工作。