Linux内核编程与调试
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
12
Linux内核定时器(2)
使用范例
13
Linux中断底半部机制
两个半部的理念:
解决既要中断执行快,又要做的事情多的矛盾。
下半部机制
➢ 软中断
➢ Tasklet
• 1 /*定义tasklet和底半部函数并关联*/
• 2 void xxx_do_tasklet(unsigned long);
• 13 {
...
• 15 tasklet_schedule(&xxx_tasklet);
• 16 ...}
➢ 工作队列
14
最新加入的一个底半部机制——threaded irq
int request_threaded_irq ( unsigned int
irq,
irq_handler_t
handler,
Linux内核编程与调试
宋宝华
版权
华清远见嵌入式培训中心版权所有; 未经华清远见明确许可,不能为任何目的以任何形式复制
或传播此文档的任何部分; 本文档包含的信息如有更改,恕不另行通知; 保留所有权利。
2ቤተ መጻሕፍቲ ባይዱ
www.hqyj.com
Linux进程状态:等待队列
➢等待队列:代表一些睡眠进程的集合
11
Linux内核定时器(1)
接口 在Linux内核中,timer_list结构体的一个实例对应一个定时器: 1 struct timer_list { 2 struct list_head entry; //定时器列表 3 unsigned long expires; //定时器到期时间 4 void (*function)(unsigned long); //定时器处理函数 5 unsigned long data; //作为参数被传入定时器处理函数 6 struct timer_base_s *base; 7 }; 当定时器期满后,其中第5行的function()成员将被执行,而第4行的data成员则是
• 3 DECLARE_TASKLET(xxx_tasklet, xxx_do_tasklet, 0); • 5 /*中断处理底半部*/
• 6 void xxx_do_tasklet(unsigned long)
• 7 {...
• 9} • 11 /*中断处理顶半部*/
• 12 irqreturn_t xxx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
29 goto out;
30 }
31 }
32 }while (avail < 0);
33 34 /* 写设备缓冲区 */
35 device_write(...)
36 out: 37 remove_wait_queue(&xxx_wait, &wait);//将等待队列移出等待队列头 38 set_current_state(TASK_RUNNING);//设置进程状态为TASK_RUNNING
11 {
12 avail = device_writable(...);
13 if (avail < 0) 14 __set_current_state(TASK_INTERRUPTIBLE);//改变进程状态
15
16 if (avail < 0)
17 { 18 if (file->f_flags &O_NONBLOCK) //非阻塞
2 loff_t *ppos)
3{
4 ... 5 DECLARE_WAITQUEUE(wait, current); //定义等待队列 6 add_wait_queue(&xxx_wait, &wait); //添加等待队列
7
8 ret = count; 9 /* 等待设备缓冲区可写 */
10 do
irq_handler_t
thread_fn,
unsigned long
irqflags,
const char *
devname,
void * dev_id);
15
Q&A
24
www.hqyj.com
25
www.hqyj.com
39 return ret;
40 }
www.hqyj.com.cn
Linux内核延时
忙等待 void ndelay(unsigned long nsecs); void udelay(unsigned long usecs); void mdelay(unsigned long msecs);
1 /*延迟100个jiffies*/ 2 unsigned long delay = jiffies + 100; 3 while (time_before(jiffies, delay)); 4 5 /*再延迟2秒*/ 6 unsigned long delay = jiffies + 2*HZ; 7 while (time_before(jiffies, delay)); 睡着延时 void msleep(unsigned int millisecs); unsigned long msleep_interruptible(unsigned int millisecs); void ssleep(unsigned int seconds); sleep_on_timeout(wait_queue_head_t *q, unsigned long timeout); interruptible_sleep_on_timeout(wait_queue_head_t*q, unsigned long timeout);
struct _ _wait_queue_head { spinlock_t lock; struct list_head task_list;
}; typedef struct _ _wait_queue_head wait_queue_head_t;
struct _ _wait_queue { unsigned int flags; struct task_struct * task; wait_queue_func_t func; struct list_head task_list;
}; typedef struct _ _wait_queue wait_queue_t;
DECLARE_WAIT_QUEUE_HEAD(name)
DEFINE_WAIT(wait)
void sleep_on(wait_queue_head_t *wq)
long sleep_on_timeout(wait_queue_head_t *q, signed long timeout);
wait_event_interruptible_timeout(wq, condition, timeout)
wake_up_interruptible(x)
www.hqyj.com.cn
Linux进程状态:等待队列的用法
阻塞与非阻塞使用模板
1 static ssize_t xxx_write(struct file *file, const char *buffer, size_t count,
传入其中的参数, 第3行的expires则是定时器到期的时间(jiffies)。 void init_timer(struct timer_list * timer); void add_timer(struct timer_list * timer); int del_timer(struct timer_list * timer); int mod_timer(struct timer_list *timer, unsigned long expires);
void interruptible_sleep_on(wait_queue_head_t *q);
long interruptible_sleep_on_timeout(wait_queue_head_t *q, signed long timeout);
wait_event(wq,condition)
19 {
20 if (!ret)
21
ret = - EAGAIN;
22 goto out;
23 } 24 schedule(); //调度其他进程执行 25 if (signal_pending(current))//如果是因为信号唤醒
26 {
27 if (!ret)
28
ret = - ERESTARTSYS;
Linux内核定时器(2)
使用范例
13
Linux中断底半部机制
两个半部的理念:
解决既要中断执行快,又要做的事情多的矛盾。
下半部机制
➢ 软中断
➢ Tasklet
• 1 /*定义tasklet和底半部函数并关联*/
• 2 void xxx_do_tasklet(unsigned long);
• 13 {
...
• 15 tasklet_schedule(&xxx_tasklet);
• 16 ...}
➢ 工作队列
14
最新加入的一个底半部机制——threaded irq
int request_threaded_irq ( unsigned int
irq,
irq_handler_t
handler,
Linux内核编程与调试
宋宝华
版权
华清远见嵌入式培训中心版权所有; 未经华清远见明确许可,不能为任何目的以任何形式复制
或传播此文档的任何部分; 本文档包含的信息如有更改,恕不另行通知; 保留所有权利。
2ቤተ መጻሕፍቲ ባይዱ
www.hqyj.com
Linux进程状态:等待队列
➢等待队列:代表一些睡眠进程的集合
11
Linux内核定时器(1)
接口 在Linux内核中,timer_list结构体的一个实例对应一个定时器: 1 struct timer_list { 2 struct list_head entry; //定时器列表 3 unsigned long expires; //定时器到期时间 4 void (*function)(unsigned long); //定时器处理函数 5 unsigned long data; //作为参数被传入定时器处理函数 6 struct timer_base_s *base; 7 }; 当定时器期满后,其中第5行的function()成员将被执行,而第4行的data成员则是
• 3 DECLARE_TASKLET(xxx_tasklet, xxx_do_tasklet, 0); • 5 /*中断处理底半部*/
• 6 void xxx_do_tasklet(unsigned long)
• 7 {...
• 9} • 11 /*中断处理顶半部*/
• 12 irqreturn_t xxx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
29 goto out;
30 }
31 }
32 }while (avail < 0);
33 34 /* 写设备缓冲区 */
35 device_write(...)
36 out: 37 remove_wait_queue(&xxx_wait, &wait);//将等待队列移出等待队列头 38 set_current_state(TASK_RUNNING);//设置进程状态为TASK_RUNNING
11 {
12 avail = device_writable(...);
13 if (avail < 0) 14 __set_current_state(TASK_INTERRUPTIBLE);//改变进程状态
15
16 if (avail < 0)
17 { 18 if (file->f_flags &O_NONBLOCK) //非阻塞
2 loff_t *ppos)
3{
4 ... 5 DECLARE_WAITQUEUE(wait, current); //定义等待队列 6 add_wait_queue(&xxx_wait, &wait); //添加等待队列
7
8 ret = count; 9 /* 等待设备缓冲区可写 */
10 do
irq_handler_t
thread_fn,
unsigned long
irqflags,
const char *
devname,
void * dev_id);
15
Q&A
24
www.hqyj.com
25
www.hqyj.com
39 return ret;
40 }
www.hqyj.com.cn
Linux内核延时
忙等待 void ndelay(unsigned long nsecs); void udelay(unsigned long usecs); void mdelay(unsigned long msecs);
1 /*延迟100个jiffies*/ 2 unsigned long delay = jiffies + 100; 3 while (time_before(jiffies, delay)); 4 5 /*再延迟2秒*/ 6 unsigned long delay = jiffies + 2*HZ; 7 while (time_before(jiffies, delay)); 睡着延时 void msleep(unsigned int millisecs); unsigned long msleep_interruptible(unsigned int millisecs); void ssleep(unsigned int seconds); sleep_on_timeout(wait_queue_head_t *q, unsigned long timeout); interruptible_sleep_on_timeout(wait_queue_head_t*q, unsigned long timeout);
struct _ _wait_queue_head { spinlock_t lock; struct list_head task_list;
}; typedef struct _ _wait_queue_head wait_queue_head_t;
struct _ _wait_queue { unsigned int flags; struct task_struct * task; wait_queue_func_t func; struct list_head task_list;
}; typedef struct _ _wait_queue wait_queue_t;
DECLARE_WAIT_QUEUE_HEAD(name)
DEFINE_WAIT(wait)
void sleep_on(wait_queue_head_t *wq)
long sleep_on_timeout(wait_queue_head_t *q, signed long timeout);
wait_event_interruptible_timeout(wq, condition, timeout)
wake_up_interruptible(x)
www.hqyj.com.cn
Linux进程状态:等待队列的用法
阻塞与非阻塞使用模板
1 static ssize_t xxx_write(struct file *file, const char *buffer, size_t count,
传入其中的参数, 第3行的expires则是定时器到期的时间(jiffies)。 void init_timer(struct timer_list * timer); void add_timer(struct timer_list * timer); int del_timer(struct timer_list * timer); int mod_timer(struct timer_list *timer, unsigned long expires);
void interruptible_sleep_on(wait_queue_head_t *q);
long interruptible_sleep_on_timeout(wait_queue_head_t *q, signed long timeout);
wait_event(wq,condition)
19 {
20 if (!ret)
21
ret = - EAGAIN;
22 goto out;
23 } 24 schedule(); //调度其他进程执行 25 if (signal_pending(current))//如果是因为信号唤醒
26 {
27 if (!ret)
28
ret = - ERESTARTSYS;