2

我正在尝试使用中断来查看 UART 16550D 中是否存在错误以及何时可以读取字符。

UART配置如下:

#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。

我想知道的是,这个设置有问题吗?测试时,我可以毫无问题地阅读和处理我正在阅读的内容。事情是,处理程序永远不会被调用。

request_irq() 的返回值为 -22。编译过程中没有问题。

4

4 回答 4

0

改变

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
于 2013-06-05T20:17:06.293 回答
0

我对为什么不触发中断处理程序的分析:

(1) 确保传递给 request_irq(virq,...) 的第一个参数是硬件 irq 号或虚拟 irq 号。在某些平台上,硬件 irq 和 request_irq(...) 使用的数字之间存在映射。如果您的盒子上有映射,那么您将处理程序错误地连接到其他中断源;

(2) 确保16550D上的中断屏蔽寄存器设置正确。我认为 16550D 上应该有一个中断屏蔽寄存器,可以屏蔽/取消屏蔽中断事件;

(3) 检查request_irq(...)的返回值,确保中断连接成功。

希望以上对你有所帮助。

于 2013-05-17T02:34:19.930 回答
0

-22 是EINVAL,我认为这是因为 NULL 最后一个参数。此页面: http: //www.makelinux.net/books/lkd2/ch06lev1sec3说:

第五个参数 dev_id 主要用于共享中断线。当一个中断处理程序被释放(稍后讨论)时,dev_id 提供一个唯一的 cookie 以允许从中断行中只删除所需的中断处理程序。如果没有这个参数,内核就不可能知道在给定的中断线上删除哪个处理程序。如果线路未共享,您可以在此处传递 NULL,但如果您的中断线路是共享的,则必须传递唯一的 cookie

所以请求一个带 NULL 的 dev_id 的共享 irq 是行不通的。

于 2016-02-21T12:49:48.723 回答
0

我知道这是一个旧帖子,但我想我会抛出一个答案。使用gpio_to_irq获取中断号。第三个参数决定中断发生的时间。

irqNumber = gpio_to_irq(gpioUART);

// This next call requests an interrupt line
result = request_irq(irqNumber,       // The interrupt number requested
    (irq_handler_t) short_interrupt, // The pointer to handler function below
    IRQF_TRIGGER_FALLING,            // Interrupt on FALL edge ()
    "seri",                          // For /proc/interrupts identity
    NULL);                           // The *dev_id for shared interrupt
于 2018-06-27T14:02:11.147 回答