当前时区为 UTC + 8 小时



发表新帖 回复这个主题  [ 5 篇帖子 ] 
作者 内容
1 楼 
 文章标题 : 软中断实现下半部
帖子发表于 : 2009-08-22 11:57 
头像

注册: 2008-03-31 16:12
帖子: 94
送出感谢: 0 次
接收感谢: 0 次
内核版本2.5以后用于实现下半部的方式有三种:软中断、tasklet、工作队列。
个人在试验软中断的时候碰到一个编译问题,而明明知道这个问题是为什么,却不知道如何解决,所以请大家指点。

以下代码中是想通过软中断的使用步骤(分配索引、注册处理程序、触发软中断)触发并执行一个软中断。
(当然了,这只是一个试验,正常的软中断的使用场合多是在中断程序返回前)。

代码:
 1 #include <linux/module.h>
 2 #include <linux/kernel.h>
 3 #include <linux/interrupt.h>
 4
 5 void softirq_func(struct softirq_action *sa)
 6 {
 7     printk("%s, %d\n", __FUNCTION__, __LINE__);
 8 }
 9
 10 static int mod_init(void)
 11 {
 12     unsigned long flags;
 13
 14     printk("%s ...\n", __FUNCTION__);
 15     //MY_OWN_SOFTIRQ定义,我已在<linux/interrupt.h>的enum位置添加。 -----分配索引
 16     //open_softirq(MY_OWN_SOFTIRQ, softirq_func, NULL);                -----注册处理程序
 17     //softirq_vec[MY_OWN_SOFTIRQ].action = softirq_func;//open_softirq没有导出,直接将open_softirq实现在这里。
 18     //softirq_vec[MY_OWN_SOFTIRQ].data = NULL;
 19     
 20     //raise_softirq(MY_OWN_SOFTIRQ);                                              -----触发软中断
 21     local_irq_save(flags);//raise_softirq函数没有导出,改用raise_softirq_irqoff的方式
 22     printk("flags is %d\n", flags);
 23     //raise_softirq_irqoff(MY_OWN_SOFTIRQ);
 24     local_irq_restore(flags);
 25         
 26     return 0;
 27 }   
 28 static void mod_exit(void)
 29 {   
 30     printk("%s ...\n", __FUNCTION__);
 31 }   
 32 module_init(mod_init);
 33 module_exit(mod_exit);


结果出现了以下编译错误。
代码:
make -C /lib/modules/2.6.23.1ubuntu810/build M=/root/Bottom_half modules
make[1]: 正在进入目录 `/usr/src/linux-2.6.23.1'
  CC [M]  /root/Bottom_half/mod.o
/root/Bottom_half/mod.c: 在函数‘mod_init’中:
/root/Bottom_half/mod.c:30: 错误: ‘softirq_vec’未声明(在此函数内第一次使用)
/root/Bottom_half/mod.c:30: 错误: (即使在一个函数内多次出现,每个未声明的标识符在其
/root/Bottom_half/mod.c:30: 错误: 所在的函数内也只报告一次。)
/root/Bottom_half/mod.c:35: 警告: 格式‘%d’需要类型‘int’,但实参 2 的类型为‘long unsigned int’
make[2]: *** [/root/Bottom_half/mod.o] 错误 1
make[1]: *** [_module_/root/Bottom_half] 错误 2
make[1]:正在离开目录 `/usr/src/linux-2.6.23.1'
make: *** [all] 错误 2

也就是说softirq_vec没有找到声明,实际上它的声明在<源码目录>/kernel/softirq.c文件中声明。
该如何是好?


页首
 用户资料  
 
2 楼 
 文章标题 : Re: 软中断实现下半部
帖子发表于 : 2009-08-23 13:05 

注册: 2009-06-27 23:33
帖子: 37
送出感谢: 0 次
接收感谢: 0 次
我是新手,下面是从linux kernel development里翻来的.
1:raise_softirq()这个函数,已经把local_irq_save()和local_irq_restore()都包办了。书里原话是:
this function disables interrupts prior to actually raising the softirq,and then restores them to their previous state.
如果在raise_softirq()之前已经关闭了中断,就用raise_softirq_irqoff();
2:向linux/interrupt.h中的enum里添加新的softirq后,好像需要重新编译内核。(自己理解的,不知大对不对。)
Sottirqs are statically allocated at compile-time.Unlike tasklet,you cannot dynamically register and destroy softirqs.


页首
 用户资料  
 
3 楼 
 文章标题 : Re: 软中断实现下半部
帖子发表于 : 2009-08-25 10:12 
头像

注册: 2008-03-31 16:12
帖子: 94
送出感谢: 0 次
接收感谢: 0 次
谢谢,虽然没有解决问题。
你说的1,是正确的,我看过raise_softirq的源码,在kernel/softirq.c文件中,如下
代码:
337 void fastcall raise_softirq(unsigned int nr)
338 {
339     unsigned long flags;
340
341     local_irq_save(flags);
342     raise_softirq_irqoff(nr);
343     local_irq_restore(flags);
344 }
确实,是你说的那样,“raise_softirq()这个函数,已经把local_irq_save()和local_irq_restore()都包办了”

第2点,我也觉得,是这样,如果添加了新的软中断号。
但我总觉得,内核软中断机制是会提供对外编程接口的,要不然驱动程序怎么写,是吧?


页首
 用户资料  
 
4 楼 
 文章标题 : Re: 软中断实现下半部
帖子发表于 : 2009-08-25 17:53 

注册: 2009-06-27 23:33
帖子: 37
送出感谢: 0 次
接收感谢: 0 次
我又重新看了bottom half那一部分,确实softirq是要静态编译进内核的。
深入理解第三版里:
软中断的分配是静态的(即在编译时定义),而tasklet的分配和初始化可以在运行时进行(例如:安装一个内核模块)。
用tasklet或者work queue吧。


页首
 用户资料  
 
5 楼 
 文章标题 : Re: 软中断实现下半部
帖子发表于 : 2009-09-11 17:20 
头像

注册: 2008-03-31 16:12
帖子: 94
送出感谢: 0 次
接收感谢: 0 次
如果是静态的,不可用的,那网卡驱动中处理数据报的下半部是怎么实现的呢??


页首
 用户资料  
 
显示帖子 :  排序  
发表新帖 回复这个主题  [ 5 篇帖子 ] 

当前时区为 UTC + 8 小时


在线用户

正在浏览此版面的用户:没有注册用户 和 2 位游客


不能 在这个版面发表主题
不能 在这个版面回复主题
不能 在这个版面编辑帖子
不能 在这个版面删除帖子
不能 在这个版面提交附件

前往 :  
本站点为公益性站点,用于推广开源自由软件,由 DiaHosting VPSBudgetVM VPS 提供服务。
我们认为:软件应可免费取得,软件工具在各种语言环境下皆可使用,且不会有任何功能上的差异;
人们应有定制和修改软件的自由,且方式不受限制,只要他们自认为合适。

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
简体中文语系由 王笑宇 翻译