中断与时钟

0、序言
    中断服务程序的执行并不存在于进程上下问中,要求中断服务程序的时间要尽量短。因此,Linux中断处理中引入上半部和下半部分离的机制。另外,内核对时钟的处理也是采用中断方式,而内核软件定时器最终依赖于时钟中断。
1、中断与定时器
    基本概念……
2、Linux中断处理程序架构
    中断会打断内核进程的正常调度和运行,为了提高系统的吞吐率势必要求中断服务程序尽量短小精悍。大多是真实的系统中,中断需要处理的工作并不会是短小,他可能需要进行大量耗时的处理。
    为了平衡执行时间尽量短和中断处理需要处理较大工作量,Linux将中断处理程序分解为两个半部:顶半部(Top Half)和底半部(Bottom Half)。
3、Linux中断编程
    1)申请中断(/include/linux/interrupt.h)
        static inline int __must_check
        request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags,
                    const char *name, void *dev){
            ...
        }
        static inline int __must_check
        devm_request_irq(struct device *dev, unsigned int irq, irq_handler_t handler,
                         unsigned long irqflags, const char *devname, void *dev_id){
            ...
        }
    2)释放中断(/include/linux/interrupt.h)
        extern void free_irq(unsigned int, void *);
        extern void devm_free_irq(struct device *dev, unsigned int irq, void *dev_id);
    3)使能中断(/include/linux/interrupt.h)
        extern void enable_irq(unsigned int irq);
    4)屏蔽中断(/include/linux/interrupt.h)
        extern void disable_irq_nosync(unsigned int irq);
        extern void disable_irq(unsigned int irq);
4、linux底半部机制
    1)tasklist(/include/linux/interrupt.h)
        执行上下文是软中断,执行时机通常是顶半部返回。
        extern void tasklet_init(struct tasklet_struct *t,
                    void (*func)(unsigned long), unsigned long data);
        static inline void tasklet_schedule(struct tasklet_struct *t){
            ...
        }
    2)工作队列(/include/linux/workqueue.h)
        执行上下文是线程,可以调度和休眠。
        extern void __init_work(struct work_struct *work, int onstack);
        static inline bool schedule_work(struct work_struct *work){
            ...
        }
    3)软中断(/include/linux/interrupt.h)
        不可打断,执行时机通常是顶半部返回。
        extern void open_softirq(int nr, void (*action)(struct softirq_action *));
        extern void raise_softirq(unsigned int nr);
    4)线程化(/include/linux/interrupt.h)
        申请中断和工作队列的封装。
        extern int __must_check
        request_threaded_irq(unsigned int irq, irq_handler_t handler,
                             irq_handler_t thread_fn,
                             unsigned long flags, const char *name, void *dev);
        static inline int __must_check
        request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags,
                    const char *name, void *dev){
            ...
        }
5、中断共享
    多个设备共享一根硬件中断线的硬件系统广泛存在,Linux支持这种中断共享。申请中断时,只需要属性标志加上IRQF_SHARED即可。
6、内核定时器
    软件意义上的定时器,最终依赖硬件定时器来实现。内部时钟发生中断,检测各定时器是否到期,到期的定时器处理函数将作为软中断于底半部执行。
    0)数据结构
    struct timer_list {
        /*
         * All fields that change during normal runtime grouped to the
         * same cacheline
         */
        struct list_head entry;
        unsigned long expires;
        struct tvec_base *base;

        void (*function)(unsigned long);
        unsigned long data;

        int slack;

    #ifdef CONFIG_TIMER_STATS
        int start_pid;
        void *start_site;
        char start_comm[16];
    #endif
    #ifdef CONFIG_LOCKDEP
        struct lockdep_map lockdep_map;
    #endif
    };
    
    1)初始化定时器(/include/linux/timer.h)
        void init_timer_key(struct timer_list *timer, unsigned int flags,
                            const char *name, struct lock_class_key *key){
            ...
        }
    2)增加定时器(/include/linux/timer.h)
        extern void add_timer(struct timer_list *timer);
    3)删除定时器(/include/linux/timer.h)
        extern int del_timer(struct timer_list * timer);    
    4)修改定时器(/include/linux/timer.h)
        extern int mod_timer(struct timer_list *timer, unsigned long expires);    
7、内核中延时工作
    1)周期性延时(include/linux/workqueue.h)
    delay_work封装了工作队列和定时器。
    static inline bool schedule_delayed_work(struct delayed_work *dwork,
                                             unsigned long delay){
        ...
    }
    extern bool cancel_delayed_work(struct delayed_work *dwork);
    extern bool cancel_delayed_work_sync(struct delayed_work *dwork);
    2)非周期性延时(/include/linux/sched.h)
    schedule_timeout当前任务休眠
    extern long schedule_timeout(long timeout);
    extern long schedule_timeout_interruptible(long timeout);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值