• linux-3.4.6内核中断流程分析


    每个内核版本的代码都会有小部分不同,但是大体流程基本相同,只是调用关系和函数名称有些变化,下面来分析中断流程

    1:在 arch/arm/kernel/ 下有个traps.c 文件中的 void __init early_trap_init(void *vectors_base) 函数 进行重定位中断向量列表

    搜索 __vectors_start 可以知道 在arch/arm/kernel/entry_armv.S 中有宏定义 在这个文件中找到 vector_stub irq, IRQ_MODE, 4 以这个为例分析一下游程

    vector_stub 是一个宏。

    下面以 __irq_usr 用户模式的中断来找流程 搜索 __irq_usr

    有个 irq_handler 这也是一个宏,继续搜索 还是在这个 entry_armv.S 中

    搜索 arch_irq_handler_default  后里面会调用 asm_do_IRQ

    到这里 前面都是用汇编写的,asm_do_IRQ 后面都用C函数实现的

      调用关系如下:

      early_trap_init  //内核用的是虚拟地址,这里只是把原来的中断向量复制到新的虚拟地址去 在内核配置文件有 0xffff0000 或 0x00000000都可以

        vector_stub irq  //以这用户模式中断为倒分析

          __irq_usr

            irq_handler

              arch_irq_handler_default

                asm_do_IRQ

    下面来分析一下 asm_do_IRQ 了解中断是如何进行的 

    2:先列出调用关系图

      asm_do_IRQ

        handle_IRQ

          generic_handle_irq

            struct irq_desc *desc = irq_to_desc(irq);

            generic_handle_irq_desc

              desc->handle_irq(irq, desc);  //desc是一个结构体  这个函数实现了 1:分辨是那一个中断 2:调用处理函数 3:清中断

    =================================================分割线=====================================================

      desc->handle_irq(irq, desc); 分析它 handle_irq指向那个函数?搜索它 在 kernel/irq/chip.c 中找到 __irq_set_handler 这个函里调用了 desc->handle_irq = handle;

      再搜索 __irq_set_handler 这个函数,看谁调用 include/linux/ irq.h 中 irq_set_chained_handler 里调用了 再搜这个函数在那调用 得到 在 arch/arm/plat-s3c24xx 里

      s3c24xx_init_irq 这个函数调用 在这个函数里构造了 irq_desc 结构体 即初始化中断里的设置这个函数里调用  这只是例子,不同的中断初始化函数都可以调用这__irq_set_handler

      handle_edge_irq

        handle_irq_event(desc);    //这个函数就是处理中断

      层次就是这样的,我们还需要分析一下 irq_desc 结构体 这个结构体在 include/linux/irqdesc.h 中定义 下面只列出一部分

    以上这些都是内核中断体系架构都做好的,这就是中断框架,我们如果要用我们自已的中断,我们怎么告诉内核呢?用 request_irq 注册,下面再来分析

    irq_desc 是一个以中断号为下标的数组,里面有各种处理函数,链表等内容,我们要使用自已的中断驱动,就需要构造 填充 然后 注册到这个链表里。

    request_irq

      request_threaded_irq

        action = kzalloc(sizeof(struct irqaction), GFP_KERNEL);    //分配一个irqaction结构体

        action->handler = handler;                //填充 把传入的参数填充到结构体
        action->thread_fn = thread_fn;
        action->flags = irqflags;
        action->name = devname;
        action->dev_id = dev_id;

        retval = __setup_irq(irq, desc, action);          //设置中断

           __irq_set_trigger

            ret = chip->irq_set_type(&desc->irq_data, flags);  //设置中断类型

        __enable_irq(desc, irq, false);              //使能中断

    到此基本分析完毕,下一节 写一个基本中断的按键驱动程序

    钻木取火!拼的是体力?耐心?智慧?
  • 相关阅读:
    JS 跨域问题。。
    LInq 中使用正则表达试
    CreateXMl
    DeleteXMl
    SameNameFile 比较两个文件夹是否同名
    UpdateXML
    AddXML
    AsDataView Dataview ,DataTable 跟linq的相互转化
    AttributeToElement
    WoreTime 计算单词出现的次数
  • 原文地址:https://www.cnblogs.com/x2i0e19linux/p/11718602.html
Copyright © 2020-2023  润新知