我们从2011年坚守至今,只想做存粹的技术论坛。  由于网站在外面,点击附件后要很长世间才弹出下载,请耐心等待,勿重复点击不要用Edge和IE浏览器下载,否则提示不安全下载不了

 找回密码
 立即注册
搜索
查看: 1380|回复: 3

[其他] Linux芯片级移植与底层驱动(基于3.7.4内核)

[复制链接]

该用户从未签到

3

主题

49

回帖

0

积分

禁止发言

积分
0

终身成就奖

发表于 2019-9-3 11:15:29 | 显示全部楼层 |阅读模式
与local_irq_disable()和local_irq_enable()不同,disable_irq()、enable_irq()针对的则是外部的中断控制器。在内核中,透过irq_chip结构体来描述中断控制器。该结构体内部封装了中断mask、unmask、ack等成员函数,其定义于include/linux/irq.h:

[cpp] view plain copy



    [li]303structirq_chip {  [/li][li]  [/li][li] 304       const char      *name;  [/li][li]  [/li][li] 305       unsigned int    (*irq_startup)(structirq_data *data);  [/li][li]  [/li][li] 306       void           (*irq_shutdown)(struct irq_data *data);  [/li][li]  [/li][li] 307       void           (*irq_enable)(struct irq_data *data);  [/li][li]  [/li][li] 308       void           (*irq_disable)(struct irq_data *data);  [/li][li]  [/li][li] 309  [/li][li]  [/li][li] 310       void            (*irq_ack)(struct irq_data *data);  [/li][li]  [/li][li] 311       void            (*irq_mask)(structirq_data *data);  [/li][li]  [/li][li] 312       void           (*irq_mask_ack)(struct irq_data *data);  [/li][li]  [/li][li] 313       void           (*irq_unmask)(struct irq_data *data);  [/li][li]  [/li][li] 314       void            (*irq_eoi)(struct irq_data *data);  [/li][li]  [/li][li] 315  [/li][li]  [/li][li] 316       int            (*irq_set_affinity)(struct irq_data *data, const struct cpumask *dest,bool force);  [/li][li]  [/li][li] 317       int            (*irq_retrigger)(struct irq_data *data);  [/li][li]  [/li][li] 318       int             (*irq_set_type)(struct irq_data *data,unsigned int flow_type);  [/li][li]  [/li][li] 319       int            (*irq_set_wake)(struct irq_data *data, unsigned int on);  [/li][li]  [/li][li] 334};  [/li]
各个芯片公司会将芯片内部的中断控制器实现为irq_chip驱动的形式。受限于中断控制器硬件的能力,这些成员函数并不一定需要全部实现,有时候只需要实现其中的部分函数即可。譬如drivers/pinctrl/pinctrl-sirf.c驱动中的

[cpp] view plain copy



    [li]1438staticstruct irq_chip sirfsoc_irq_chip = {  [/li][li]  [/li][li]1439        .name = "sirf-gpio-irq",  [/li][li]  [/li][li]1440        .irq_ack = sirfsoc_gpio_irq_ack,  [/li][li]  [/li][li]1441       .irq_mask = sirfsoc_gpio_irq_mask,  [/li][li]  [/li][li]1442        .irq_unmask = sirfsoc_gpio_irq_unmask,  [/li][li]  [/li][li]1443        .irq_set_type = sirfsoc_gpio_irq_type,  [/li][li]  [/li][li]1444};  [/li]
我们只实现了其中的ack、mask、unmask和set_type成员函数,ack函数用于清中断,mask、unmask用于中断屏蔽和取消中断屏蔽、set_type则用于配置中断的触发方式,如高电平、低电平、上升沿、下降沿等。至于enable_irq()的时候,虽然没有实现irq_enable成员函数,但是内核会间接调用到irq_unmask成员函数,这点从kernel/irq/chip.c可以看出:

[cpp] view plain copy



    [li]192voidirq_enable(struct irq_desc *desc)  [/li][li]  [/li][li] 193{  [/li][li]  [/li][li] 194       irq_state_clr_disabled(desc);  [/li][li]  [/li][li] 195       if (desc->irq_data.chip->irq_enable)  [/li][li]  [/li][li] 196                desc->irq_data.chip->irq_enable(&desc->irq_data);  [/li][li]  [/li][li] 197       else  [/li][li]  [/li][li] 198               desc->irq_data.chip->irq_unmask(&desc->irq_data);  [/li][li]  [/li][li] 199       irq_state_clr_masked(desc);  [/li][li]  [/li][li] 200}  [/li]
在芯片内部,中断控制器可能不止1个,多个中断控制器之间还很可能是级联的。举个例子,假设芯片内部有一个中断控制器,支持32个中断源,其中有4个来源于GPIO控制器外围的4组GPIO,每组GPIO上又有32个中断(许多芯片的GPIO控制器也同时是一个中断控制器),其关系如下图:



那么,一般来讲,在实际操作中,gpio0_0——gpio0_31这些引脚本身在第1级会使用中断号28,而这些引脚本身的中断号在实现GPIO控制器对应的irq_chip驱动时,我们又会把它映射到Linux系统的32——63号中断。同理,gpio1_0——gpio1_31这些引脚本身在第1级会使用中断号29,而这些引脚本身的中断号在实现GPIO控制器对应的irq_chip驱动时,我们又会把它映射到Linux系统的64——95号中断,以此类推。对于中断号的使用者而言,无需看到这种2级映射关系。如果某设备想申请gpio1_0这个引脚对应的中断,它只需要申请64号中断即可。这个关系图看起来如下:

回复

使用道具 举报

  • TA的每日心情
    慵懒
    2024-6-14 16:03
  • 签到天数: 16 天

    [LV.4]偶尔看看III

    0

    主题

    1万

    回帖

    7618

    积分

    二级逆天

    积分
    7618

    终身成就奖特殊贡献奖原创先锋奖优秀斑竹奖

    QQ
    发表于 2019-9-3 11:50:54 | 显示全部楼层
    回复

    使用道具 举报

    该用户从未签到

    1

    主题

    6218

    回帖

    8730

    积分

    二级逆天

    积分
    8730

    终身成就奖特殊贡献奖原创先锋奖优秀斑竹奖

    QQ
    发表于 2019-9-4 07:42:31 | 显示全部楼层
    回复

    使用道具 举报

  • TA的每日心情
    开心
    半小时前
  • 签到天数: 128 天

    [LV.7]常住居民III

    7

    主题

    9469

    回帖

    8447

    积分

    二级逆天

    积分
    8447

    社区居民终身成就奖特殊贡献奖原创先锋奖优秀斑竹奖

    QQ
    发表于 2019-9-10 08:26:07 | 显示全部楼层
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    论坛开启做任务可以
    额外奖励金币快速赚
    积分升级了


    Copyright ©2011-2024 NTpcb.com All Right Reserved.  Powered by Discuz! (NTpcb)

    本站信息均由会员发表,不代表NTpcb立场,如侵犯了您的权利请发帖投诉

    平平安安
    TOP
    快速回复 返回顶部 返回列表