找回密码
 注册
关于网站域名变更的通知
查看: 308|回复: 1
打印 上一主题 下一主题

linux字符驱动之同步互斥按键驱动

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2020-6-16 15:04 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

EDA365欢迎您登录!

您需要 登录 才可以下载或查看,没有帐号?注册

x
上一节里,我们将在上一节的基础上修改驱动,将其修改为有异步通知功能的按键驱动,目标是,按下按键时,驱动主动去通知应用程序。是不是感觉驱动已经比较完善了,好像已经是完美无缺了?是不是这样呢?好像不是呢,有没有这么一种情况,多个进程想同时使用驱动的设备节点?在多线的环境下,分分钟可能会发生这种情况。( W" i' P% d! ]$ j1 H9 }/ v
9 G% V! Q3 e3 s- _9 S
上一节文章:linux字符驱动之异步通知按键驱动1 f3 S2 Z, Q0 H* _
* Q* B/ S- N3 q
在这一节里,我们在上一节的基础上,实现同一时刻只能有一个进程使用同一个设备,例如:只能有一个进程,在同一时刻里使用/dev/buttons这个设备。
) p  Z9 a7 J! E' X( a
! R  D, h' i; B3 I7 ?8 A问:如何实现同一时刻只能有一个进程使用某个设备?; c4 e: f& U; H7 O9 [

: ~% Z" Q+ r; t8 G# x9 n2 J答:使用linux互斥机制# }' \7 e  z; H# e
7 c/ _; j' \6 J: S; {4 [8 D
问:linux互斥机制有哪些?! F- V  Y+ f- [

- o- G& s: J$ Q3 S4 E. N1 E答:有很多种,如:原子变量、互斥锁、信号量、自旋锁、读写锁等等
; r& f: E1 v; _, X% l  m2 P2 M) s& ~- f/ v3 ?9 p$ q( F
问:在这一节里,我们使用什么互斥机制?
3 c; a: u# O* J6 R1 u$ d1 a# ^. I/ ^
/ G& @% g! F' Y3 s+ u/ {答:原子变量/信号量,举二个例子来示范linux的互斥机制
/ b! e9 `% X) y- ?" V$ y& s- J! q
问:如何使用原子变量的互斥机制?
# |6 ~. i' ?$ }2 j$ E  @0 u' `, A4 i  |
答:先定义一个原子变量,然后再初始化它。具体如下:
, m! l7 r4 {  S* G# X' k
4 h, @& q) p# b8 P9 o& Z, i( `4 ^& P3 @! ~6 Q3 [1 Y- U
/* 定义原子变量canopen并初始化为1 */
* f- X1 q2 _" I2 ~; \2 K+ ?static>9 e. ^/ B6 ?- S
问:与原子变量相关的函数有哪些?
* l: Y. ?) h) b& y. {答:原子操作指的是在执行过程中不会被别的代码路径所中断的操作,常用原子操作函数举例:
8 K  S- B/ x4 p6 K6 B+ O6 h) |9 i/ _, @

" _  l% @) t7 {: latomic_t>% {- Q2 B+ {; f; N: S% e
问:原子变量相关的函数在此驱动里,在哪来会被调用?
4 u1 M# j; I: o9 }  }4 c6 o' |8 q答:既然是防止多个进程打开同一个设备,那自然是在open函数就调用,在close函数也会被调用,示例如下:9 r' m" A, f" R4 Z: i+ }! |
2 {! R2 t9 s+ H
8 b8 r4 a# S$ A$ z/ ?
static>
  {$ L- b) V$ V: m4 J* v3 @! w5 |3 f& Z/ E0 s
# j/ O" O1 W1 h3 T
原子变量互斥方式应用测试程序源码:
& c) l' h' G) t0 h! J
2 u0 S0 k- v* o" ]' }# v9 W/ S2 K6 h
( u+ w1 N3 N) N, ^% P+ B6 d$ [#include <stdio.h>
2 [0 j  h8 @! [#include <sys/types.h>" x1 j) {0 }+ v# J$ r
#include <sys/stat.h>* x' {5 f- ]9 A3 |
#include <fcntl.h>$ M. a- V' O4 j8 M0 |' J' V
#include <unistd.h># G# B; h- s$ q3 w$ e7 u3 q3 L* g
#include <poll.h>3 S9 H8 L; b5 q) _+ m

" j% y1 a( h$ y9 o, E& d/*>
. Q. [1 j7 [: n3 z( j( j# ]- W% k) {( P) H6 h
原子变量互斥方式测试步骤:! P" [0 r5 ]- x, n; X) J
, b8 U$ |* l; x+ n; c
[WJ2440]#>
* `$ I9 m# |  s/ p8 R  S. K8 [, N! \, g1 n7 O

: X  ]  J* |' x3 c信号量互斥方式应用测试程序源码:
& B$ o" w- u/ V) K8 n2 v; X#include <stdio.h>2 q  s; x/ c3 J. O0 z( R" X* J
#include <sys/types.h>9 R' ]6 a' }5 y% `7 Z" {/ E: D7 i
#include <sys/stat.h>
+ W- s& ^* o/ ^& H1 O3 b: K4 r#include <fcntl.h>
/ m" V7 w/ k9 S- o#include <unistd.h>        //sleep$ n  ~  L, J+ \% z4 y' `* ^
#include <poll.h>
- t- e5 W7 ]" N: S, H3 Y; ?" u7 _#include <signal.h>) }: r2 _( \- c5 \
#include <fcntl.h>
4 a! [4 \; a9 m" g4 i) ?' y) z4 W9 G9 A2 V
int>
; V' G2 d: M8 w0 K: V  a9 _. U$ W# |1 f' a
0 t1 }, b7 ]  w" }; q0 V7 {信号量互斥方式测试步骤:
: Z% W; {! P$ e) y: o( G7 W; o- }7 L* O& x
[WJ2440]# ls% w( p% j) @# L. j: X& z' }
Qt             fifth_drv.ko   lib            sddisk         third_test* }  s  L% J  m6 A6 b' k
TQLedtest      fifth_test     linuxrc        second_drv.ko  tmp
/ [1 `; D5 S) q1 mapp_test       first_drv.ko   mnt            second_test    udisk( z: |) n/ e6 w& Q" o
bin            first_test     opt            sixth_drv.ko   usr( {- D, `7 I1 d$ ~) z, n# {
dev            fourth_drv.ko  proc           sixth_test     var
6 R  u* g) _3 Y9 {: Ydriver_test    fourth_test    root           sys            web/ z  B9 L) @' ~- b
etc            home           sbin           third_drv.ko1 b9 Y2 [5 n3 m1 _# X
[WJ2440]# insmod sixth_drv.ko # Y. J, r. e1 D0 B7 z& C$ F
[WJ2440]# lsmod              
- P6 l1 C0 r# U- k! _; h' w( Xsixth_drv 3472 0 - Live 0xbf000000
) J) b6 j. s+ j) ~) U$ o+ \[WJ2440]# ls /dev/buttons -l/ w- B, Z+ h  \6 m1 b+ B  q; ]$ a. v, c
crw-rw----    1 root     root      252,   0 Jan  2 04:47 /dev/buttons  @4 }  ~6 J0 F8 `
[WJ2440]# ./sixth_test &
6 h- ^# B2 a# [[WJ2440]# ./sixth_test &
8 }5 J6 V1 r+ B( S5 t& J4 L4 }[WJ2440]# ps
2 d; j1 z. l+ M, h  PID USER       VSZ STAT COMMAND# Y, l' j1 ^0 I2 h# a' D, c; q
    1 root      2088 S    init
" U- k, C) ^) _    2 root         0 SW<  [kthreadd], h- Z' }0 L# F3 d
    3 root         0 SW<  [ksoftirqd/0]% M# Q/ S9 x, S
    4 root         0 SW<  [events/0]8 Z6 y- M/ ~1 K6 X7 N
    5 root         0 SW<  [khelper]( ?- }! ^. ?5 {, |2 A. k* _- d  r
   11 root         0 SW<  [async/mgr]& d/ m0 v5 q) ]% D$ b
  237 root         0 SW<  [kblockd/0]: m6 @/ N* m- D+ ~& Y
  247 root         0 SW<  [khubd]
& m. o& g: z. Z$ v. f0 [) Z2 @% P  254 root         0 SW<  [kmmcd]
8 d. O- j' S7 l* w9 R; @. |  278 root         0 SW   [pdflush]
7 V3 Q4 D; E" |: i( f, e7 t  279 root         0 SW   [pdflush]
+ R1 P) z# S, n  z" T' P: p  280 root         0 SW<  [kswapd0]
5 S; _7 l* L' w0 W9 G9 h/ t. W0 P  325 root         0 SW<  [aio/0]9 m6 m, o  t8 q7 j3 b* U9 |- ]- P
  329 root         0 SW<  [nfsiod]5 u. h* O+ Z, \+ {
  333 root         0 SW<  [crypto/0]+ l; D1 v. s: l& M
  443 root         0 SW<  [mtdblockd]
' e) H  S) {0 I* \+ Z, L# H4 x  557 root         0 SW<  [usbhid_resumer]4 f! ^: W- t1 K9 Y+ h) o; M
  573 root         0 SW<  [rpciod/0]3 ~$ o' Q8 z7 |7 ^; \
  587 root      1508 S    EmbedSky_wdg
  A: v1 [" ?7 L( h  589 root      2092 S    -/bin/sh
7 o7 ?% w5 P; X5 x  590 root      2088 S    /usr/sbin/telnetd -l /bin/login
  |9 l! l6 E: h  602 root      1428 S    ./sixth_test' @# K. v2 l& A+ n# r+ e0 U4 L
  603 root      1428 D    ./sixth_test( W# Z& E8 v7 K& }5 v
  604 root      2092 R    ps4 }3 y4 x, V: ]3 c

$ ?6 @! t# X4 U6 z+ ]由上面的测试结果可知:当多次执行./sixth_test &时,可发现进程602的状态为S即睡眠状态,而进程603的状态为D即僵死状态,只有当我们杀死602进程时,603的状态才能变为S正常状态,这也就达到了互斥的目的。! A  O* @, N+ O" g3 S
1 P5 e7 L2 O. S: D
& E& F+ F" T# }

3 P+ P, a$ G( P; u
  v2 m" F. ]$ X  w, d' v' b
5 X# p. a- j- G$ Q: ?! z
  • TA的每日心情

    2019-11-29 15:37
  • 签到天数: 1 天

    [LV.1]初来乍到

    2#
    发表于 2020-6-16 16:27 | 只看该作者
    linux字符驱动之同步互斥按键驱动
    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    关闭

    推荐内容上一条 /1 下一条

    EDA365公众号

    关于我们|手机版|EDA365电子论坛网 ( 粤ICP备18020198号-1 )

    GMT+8, 2025-11-25 17:37 , Processed in 0.156250 second(s), 23 queries , Gzip On.

    深圳市墨知创新科技有限公司

    地址:深圳市南山区科技生态园2栋A座805 电话:19926409050

    快速回复 返回顶部 返回列表