1

Linuxカーネルでの割り込み処理を学んでおり、以下のコードスニペットを試して、IRQ2にダミーのirqハンドラーを登録しました。しかし、実行しようとしているクリーンアップ関数から生じる負の戻り値と以下のようなメッセージがカーネルに表示されているため、登録されていないようですfree_irq():

[ 2203.989585] Trying to free already-free IRQ 2

以下は、カーネル ログからの printk であり、登録されていないことを示しています。

Here with registering IRQ handler on IRQ2 for flowTest...retval_irqreg= -22

以下は、4つの機能を持つ私のコードの関連部分です

1 the bottom half 
2. handler 
3. init function 
4. cleanup function

下半分はまだ予定していませんが、下にあります。私はカーネル 3.5.0-17 に取り組んでいます。

//Bottom half for the irq handler
static void bh_flowTest()
    {
        printk(KERN_INFO "Inside bottom half for flowTest.\n");
    }
// IRQ handler function
static irqreturn_t flow_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
                {
                printk(KERN_INFO "This is flowTest IRQ handler.\n");

        //static struct tq_struct task = {NULL, 0, bh_flowTest, NULL};
                /* Schedule bottom half to run */
        //queue_task(&task, &tq_immediate);

        // mark_bh(IMMEDIATE_BH);
    return IRQ_HANDLED;             
        }

static int flow_init(void)
    {
    printk(KERN_ALERT "Here with flowTest module ... loading...\n");
 int result=0;
 dev_t dev=0;
result = alloc_chrdev_region(&dev, minor_num,
num_devices,"mod_flowtest");                              // allocate major number dynamically.

i=MAJOR(dev);
printk(KERN_ALERT "Major allocated = %d",i);

cdev_init(&ms_flow_cd,&flow_fops);
cdev_add(&ms_flow_cd,dev,1);

//Registering interrupt handler on IRQ2 since IRQ2 is free as per /proc/interrupts
int retval_irqreg;
retval_irqreg=request_irq(2,(irq_handler_t)flow_irq_handler, /* our handler. It has been typecasted to remove warnings of incompatible pointer type , and enum irqreturn_t. Try removing the cast and see the warnings */
              IRQF_SHARED, 
              "test_flow_irq_handler", NULL);
printk(KERN_ALERT "Here with registering IRQ handler on IRQ2 for flowTest...retval_irqreg= %d\n",retval_irqreg);

return 0;
    }

static void flow_terminate(void)
    {
    dev_t devno=MKDEV(i,0);         // wrap major/minor numbers in a dev_t structure , to pass for deassigning.
    printk(KERN_ALERT "Going out... exiting...\n");
    unregister_chrdev_region(devno,num_devices);        //remove entry from the /proc/devices

    free_irq(2, NULL);
    }

基本的な間違いがあると思いますが、誰かが私にそれを指摘してくれたら..!

4

1 に答える 1

2

IRQ 2ハードウェアにはまだ存在しないようです。つまり、Linux カーネルは、IRQ 番号 " 2request_irq() "のトリガーとして処理する必要がある周辺ハードウェアの物理回線のどの割り込みをまだ認識していません。これは、実際の物理割り込みにはまだ関連付けられていない番号であるためです。 )。

基本的に、その IRQ 番号の ISR を登録しようとする前に、まず特定の IRQ 番号を実際の物理ハードウェア割り込みに関連付ける必要があります。これは一般に、Linux カーネルで を使用して行われますirq_domain_add_linear()

以前は、IRQ 番号を選択して、ハードウェア IRQ ラインをルート割り込みコントローラー (つまり、実際に割り込みラインを CPU に送信するコンポーネント) に一致させることができました。現在、この番号は単なる数字です。

irq_alloc_desc*()およびAPI は irq 番号のirq_free_desc*()割り当てを提供しますが、コントローラーローカル IRQ (hwirq) 番号の Linux IRQ 番号空間への逆マッピングのサポートは提供しません。

Linux カーネルの現在の設計では、個別の IRQ ソースごとに異なる番号が割り当てられる単一の大きな番号空間を使用します。これは、割り込みコントローラーが 1 つしかない場合は簡単ですが、複数の割り込みコントローラーを備えたシステムでは、カーネルはそれぞれに Linux IRQ 番号の重複しない割り当てが割り当てられるようにする必要があります。

詳細については、Linux-kernel Documentation/IRQ-domain.txtを参照してください。

また、既存の割り込み (キーボードの IRQ など) に ISR を登録することに興味があるかもしれません。単一の IRQ に複数の ISR が登録されている場合、Linux カーネルは、共有 irq を登録する各ドライバーの各 ISR を呼び出します。

于 2013-08-09T06:55:44.757 に答える