当前位置:
文档之家› linux中断底半部机制对比(任务队列,工作队列,软中断)--由linux RS485引出的血案-ispsubb-ChinaUnix博客
linux中断底半部机制对比(任务队列,工作队列,软中断)--由linux RS485引出的血案-ispsubb-ChinaUnix博客
1 / 7
b l o g . c h i n a u n i x . n e t / u i d 2 0 7 6 8 9 2 8 i d 5 0 7 7 4 0 1 . h t ml
1 5 6 1 6l i n u x
-l i n u x R S 4 8 5
i s p s u b b C h i n a U n i x
lwfbibi
D2002
chunhui_
2 / 7
b l o g . c h i n a u n i x . n e t / u i d 2 0 7 6 8 9 2 8 i d 5 0 7 7 4 0 1 . h t ml
1 5 6 1 6l i n u x
-l i n u x R S 4 8 5
i s p s u b b C h i n a U n i x
考/angle_birds/article/details/8448070
yzj_1988
64492407
紫易幼南
点击(此处)折叠或打开 1 . 2 . 3 . 4 . 5 . 6 . 7 . 8 . 9 . 1 0 . 1 1 . 1 2 . 1 3 . 1 4 . D E C L A R E _ W O R K ( s t r u c tw o r k _ s t r u c t,w o r k _ f u n c _ tf u n c ) ; I N I T _ W O R K ( s t r u c tw o r k _ s t r u c t* w o r k ,w o r k _ f u n c _ tf u n c ) ; I N I T _ D E L A Y E D _ W O R K ( s t r u c td e l a y e d _ w o r k* w o r k ,w o r k _ f u n c _ tf u n c ) ; i n ts c h e d u l e _ w o r k ( s t r u c tw o r k _ s t r u c t* w o r k ) ; i n ts c h e d u l e _ d e l a y e d _ w o r k ( s t r u c td e l a y e d _ w o r k* w o r k ,u n s i g n e dl o n gd e l a y ) ; i n ts c h e d u l e _ d e l a y e d _ w o r k _ o n ( s t r u c td e l a y e d _ w o r k* w o r k ,u n s i g n e dl o n gd e l a y ) ; s t r u c tw o r k q u e u e _ s t r u c t* c r e a t e _ w o r k q u e u e ( c o n s tc h a r* n a m e ) ; i n tq u e u e _ w o r k ( s t r u c tw o r k q u e u e _ s t r u c t* w q ,s t r u c tw o r k _ s t r u c t* w o r k ) ; i n tq u e u e _ d e l a y e d _ w o r k ( s t r u c tw o r k q u e u e _ s t r u c t* w q ,s t r u c td e l a y e d _ w o r k* w o r k , u n s i g n e dl o n gd e l a y ) ; v o i df l u s h _ s c h e d u l e d _ w o r k ( v o i d ) ; v o i df l u s h _ w o r k q u e u e ( s t r u c tw o r k q u e u e _ s t r u c t* w q ) ; i n tc a n c e l _ d e l a y e d _ w o r k ( s t r u c td e l a y e d _ w o r k* w o r k ) ; v o i dd e s t r o y _ w o r k q u e u e ( s t r u c tw o r k q u e u e _ s t r u c t* w q ) ;
文章存档 2015年 (4) 2014年 (4) 2012年 (7)
我的朋友
最近访客
liuyingj
yadunhah
headstro
工作队列,任务队列,软中断
工作队列 :Linux kernel中将工作推后执行的一种机制。这种机制和BH或Tasklets不同之处在于工作队 列是把推后的工作交由一个内核线程去执行,因此工作队列的优势就在于它允许重新调度甚至睡眠。工作 队列是2.6内核开始引入的机制,在2.6.20之后,工作队列的数据结构发生了一些变化。可以参
1 5 6 1 6l i n u x
-l i n u x R S 4 8 5
i s p s u b b C h i n a U n i x
Chinaunix首页 | 论坛 | 认证专区 | 博客
登录 | 注册
博文
ispsubb的ChinaUnix博客
After all ,tomorrow is another day !
在LINUX RS485的使用过程中,由于各种原因,最后不得不使用中断底半部机制的方法来进行实现此 功能。先讲两个小故事来描述一下,遇到的问题。也是因为自己对底半部机制理解得不透彻。这些故事的 前提都是在串口中断中,一定条件后去完成某件事情,但时间上不能超过5ms。 故事一,最开始想到的是用workqueue 。印象中workqueue 就是用来做这种事的,并且还记得可以延时 一段时间再来做。
点击(此处)折叠或打开 1 . 2 . 3 . I N I T _ W O R K ( & m y _ w q , ( v o i d( * )( v o i d * ) ) m y _ w q _ f u n c ) ; s c h e d u l e _ w o r k ( & m y _ w q ) ; / / s c h e d u l e _ d e l a y e d _ w o r k ( & m y _ w q , d e l a y ) ;
故事二,工作队列不行后,感觉底半部机制就实现不了,满足不了我们的要求。上网翻了一些资料,觉 得任务队列时效性应该比工作队列更好。就像买药的做广告一样,抱着试一试的态度尝试了一下。
最终这种方法实现了。但过程也是相当曲折。tasklet_schedule时效性可以达到,hi_schedule 更是完 美,感觉会牺牲系统性能。那么过程曲折在哪呢?刚开始以为搞好了,回家睡大觉,等我九点半到家,同 事打电话说不行,出问题了。单个串口没有问题,多个串口同时用的时候,前面打开的串口对应 的rs485 都不能正常使用。GPIO拉高后,就不低。而my_wq_func就是实现GPIO拉低的动作。最后的原因 是my_wq_func被多次调用,而其只响应最后一次。这个地方还得感谢这位老兄, /goodluckwhh/article/details/9003353 。tasklet 是一个特殊的函数, 它在软 中断上下文被调度。它可能被调度运行多次,但是tasklet调度不累积,也就是即使在tasklet被执行之前 请求了多次来执行该tasklet,它也只运行一次。不会有同一个tasklet的多个实例同时运行。但 是tasklet可以与SMP系统上的其他tasklet并行运行。因此, 如果多个tasklet会使用相同的资源, 它们必 须采取某类加锁来避免彼此冲突。除非tasklet重新激活自己,否则每次tasklet激活只会运行一次。最后 的解决方法就是将my_wq_func一个函数可以实现的内容,复制成了四个函数,问题就解决了。 故事讲完了,这时候该来分析分析理论上的底半部机制。前面的曲折,主要是因为自己对底半部机制的 一知半解。这里来着重分析一下任务队列,工作队列的区别,同时也COPY一些别人对软中断的理解,以备 后续查看
情况,我们要求小于5ms。
文章分类 全部博文 (15) translate (0) job and life (0) bootloader (0) android (0) C ASM …… (0) linux (15) arm (0) 未分配的博文 (0) 点击(此处)折叠或打开 1 . 2 . 3 . t a s k l e t _ i n i t ( & m y _ t a s k 0 , m y _ w q _ f u n c , ( u n s i g n e dl o n g )m y _ w q _ a r g ) ; t a s k l e t _ s c h e d u l e ( & m y _ t a s k 0 ) ; t a s k l e t _ h i _ s c h e d u l e ( & m y _ t a s k 0 ) ;
点击(此处)折叠或打开 1 . 2 . 3 . 4 . 5 . 6 . 7 . 8 . D E C L A R E _ T A S K L E T ( n a m e ,f u n c ,d a t a ) ; v o i dt a s k l e t _ i n i t ( s t r u c tt a s k l e t _ s t r u c t* t , v o i d( * f u n c ) ( u n s i g n e dl o n g ) ,u n s i g n e dl o n gd a t a ) ; v o i dt a s k l e t _ s c h e d u l e ( s t r u c tt a s k l e t _ s t r u c t* t ) ; v o i dt a s k l e t _ h i _ s c h e d u l e ( s t r u c tt a s k l e t _ s t r u c t* t ) ; v o i dt a s k l e t _ d i s a b l e ( s t r u c tt a s k l e t _ s t r u c t* t ) ; v o i dt a s k l e t _ d i s a b l e _ n o s y n c ( s t r u c tt a s k l e t _ s t r u c t* t ) ; v o i dt a s k l e t _ e n a b l e ( s t r u c tt a s k l e t _ s t r u c t* t ) ; v o i dt a s k l e t _ k i l l ( s t r u c tt a s k l e t _ s t r u c t* t ) ;