2013-08-09 4 views
0

리눅스 커널에서 인터럽트 처리를 배우고 있고 IRQ2에서 더미 irq 처리기를 등록하기 위해 아래 코드를 시도했습니다. 아래 IRQ 처리기가 등록되지 않았습니다.

[ 2203.989585] Trying to free already-free IRQ 2 

커널 로그에서의 printk이다 : 나는 음의 반환 값과 free_irq()을 위해 노력하고 정리 기능에서 발생하는 다음과 같이 커널의 메시지를보고 있어요 그러나 등록하기되지 않는 것 같다

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

이 네 가지 기능

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

나는 schedulin 아니에요을 가지고 내 코드의 관련 부분입니다 : 어떤은 등록있어되지 않았 음을 시사한다 g 아래쪽에 있지만 아직 아래쪽에 있습니다. 나는 커널 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); 
    } 

몇 가지 기본적인 실수가 있다고 생각하지만 누군가 제게 그것을 가르쳐 줄 수 있다면 ..!

+0

어떤 하드웨어를 사용하려고합니까? ** 2 ** ** 유효한 IRQ 번호는 무엇입니까? ... – TheCodeArtist

+0

현재 하드웨어 (장치)를 특정하지 않습니다. 처리기 등록을 보려고합니다.아래의 메시지는 "이미 무료 IRQ 2를 시도하는 중입니다"라고 제안했기 때문에 x86 하드웨어 32 비트에 대해서는 IRQ2가있는 것 같습니다. 나는 바보 같은 짓을하지 않는 것이 좋겠다. –

+0

"이미 free-free IRQ 2를 시도하고있다"는 메시지는 현재 드라이버가 irq 번호 2에 등록한 인터럽트 핸들러가 없다는 것을 의미합니다. 유효한 IRQ가 존재 함을 의미하지는 않습니다. – TheCodeArtist

답변

1

하드웨어에 IRQ 2이 아직없는 것 같습니다. 예를 들어, request_irq()으로 전화를 걸면 리눅스 커널은 어떤 주변기기 하드웨어가 IRQ 번호 ""에 대한 트리거로 취급되어야하는지에 대한 어떤 인터럽트가 실제 실제와 관련이없는 번호인지 알지 못합니다 물리적 인 인터럽트는 아직 없음).

기본적으로 특정 IRQ 번호를 실제 하드웨어 하드웨어 인터럽트와 연결해야 해당 IRQ 번호에 대한 ISR을 등록하려고합니다. thsi는 일반적으로 irq_domain_add_linear()을 사용하여 Linux 커널에서 수행됩니다. 이들은 루트 인터럽트 컨트롤러에 하드웨어 IRQ 라인과 일치하도록 과거

는 IRQ 번호 (실제로는 CPU에 대한 인터럽트 라인 소성 성분, 즉) 요즘이 수가 단지 숫자 선택 될 수있다.

irq_alloc_desc*()irq_free_desc*() API는 IRQ 번호의 할당을 제공하지만 리눅스 IRQ 번호 공간으로 컨트롤러 지역 IRQ (hwirq) 숫자의 역 매핑을위한 모든 지원을 제공하지 않습니다.

현재 리눅스 커널의 디자인은 각각의 IRQ 소스마다 다른 번호가 할당 된 하나의 큰 숫자 공간을 사용합니다. 이것은 하나의 인터럽트 컨트롤러 만있는 경우는 간단하지만 여러 인터럽트 컨트롤러가있는 시스템에서는 커널이 각 인터럽트 컨트롤러가 중복되지 않는 Linux IRQ 번호 할당을 얻도록해야합니다. 리눅스 커널 Documentation/IRQ-domain.txt에서

자세한 내용.

기존 인터럽트에 대한 ISR 등록 (키보드 IRQ?) 단일 IRQ에 여러 ISR이 등록되면 Linux 커널은 register a shared irq의 각 드라이버에서 ISR을 호출합니다.

+0

그렇다면 실제 IRQ 라인에 실제 하드웨어/장치가 할당 될 때까지는 IRQ 핸들러를 IRQ 번호에 등록 할 수 없습니까? –

+1

예. 호출 될 때,'request_irq()'는 처음에 [desc]를 찾아 내려고한다. (http://lxr.free-electrons.com/source/kernel/irq/manage.c?v=3.8#L1410) irq 번호는에 속한다. 하나라도 찾지 못하면,'request_irq()'의 반환 값으로 얻은'EINVAL' (-22)을 반환합니다. – TheCodeArtist

관련 문제