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

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
上一节里,我们将在上一节的基础上修改驱动,将其修改为有异步通知功能的按键驱动,目标是,按下按键时,驱动主动去通知应用程序。是不是感觉驱动已经比较完善了,好像已经是完美无缺了?是不是这样呢?好像不是呢,有没有这么一种情况,多个进程想同时使用驱动的设备节点?在多线的环境下,分分钟可能会发生这种情况。( g! _8 ?; a4 Q8 I  f7 Z

4 P7 Q* ~& g( o2 M上一节文章:linux字符驱动之异步通知按键驱动
. p* A$ y" l: @# P
$ `* Q  _& I$ k+ p3 u/ J在这一节里,我们在上一节的基础上,实现同一时刻只能有一个进程使用同一个设备,例如:只能有一个进程,在同一时刻里使用/dev/buttons这个设备。& P8 m$ u( H7 _. ^! N% m0 x, s
% n8 ?! M! j$ F. _: }/ Z& K
问:如何实现同一时刻只能有一个进程使用某个设备?: H) }! y7 T# }0 ^

7 c6 I' Q# `* z/ Q答:使用linux互斥机制
  v9 Y6 r' T5 g2 J: ^  C- o# F3 S
9 X5 k* W! {, C. _! P* T7 U' U* y8 K问:linux互斥机制有哪些?
6 f% X( s! H* c9 y+ D0 I( {: d% r3 X9 s3 d
答:有很多种,如:原子变量、互斥锁、信号量、自旋锁、读写锁等等' A- Y0 q% r2 B: F

- a( y( Y2 b; c4 G% {7 F$ U问:在这一节里,我们使用什么互斥机制?4 i5 [3 ^- x( l! R% `

) R/ @1 k2 K. v) T. c答:原子变量/信号量,举二个例子来示范linux的互斥机制
9 ]( S# F( B9 W# o- E6 `4 H2 r$ z9 v- f( ]
问:如何使用原子变量的互斥机制?+ ], A) A1 h* R7 o$ M) g

4 O% \" i$ y# q% _) G4 L7 g% O* _& }* ]% `答:先定义一个原子变量,然后再初始化它。具体如下:& \/ L' ^& d7 E: ^+ Z7 K
- I; J1 a$ o0 L6 p; B6 z
! Q% ~, f9 }; v! Y
/* 定义原子变量canopen并初始化为1 */, }8 [: m* e7 W$ N: j/ `# M
static>( H- V7 k) ^2 T/ D5 d$ w8 H5 `
问:与原子变量相关的函数有哪些?# J2 v8 W: C) T& K' U
答:原子操作指的是在执行过程中不会被别的代码路径所中断的操作,常用原子操作函数举例:
' j+ B* a* H/ W! e! l1 X
+ ^, V. p4 ]9 D2 e4 l6 L8 _5 N$ f- H& g) F, E1 N2 q7 s) W
atomic_t>/ u, W) r* i5 |7 ^+ W  K" i( A  ~; z
问:原子变量相关的函数在此驱动里,在哪来会被调用?
8 m* X) Q  }, U/ a答:既然是防止多个进程打开同一个设备,那自然是在open函数就调用,在close函数也会被调用,示例如下:' m) n/ _; n6 @8 Y) X+ D

0 o9 W9 i: ?" v5 C  M% J0 ^
' e6 I* d6 `3 z- n* e2 F3 C& l/ Rstatic>$ ?; @. e$ c! x6 I$ G- g
/ ^) V8 u7 f, r$ w' D
3 c$ {% T  e; ^/ o
原子变量互斥方式应用测试程序源码:
' `" `9 W0 f& ~0 t& Q# |+ C# j/ H8 g# B. h6 T

/ A+ p! W1 C$ U( v' H0 _! d( ^#include <stdio.h>! u7 P' m- ]$ |# r8 R" e
#include <sys/types.h>
8 F2 W& {" \2 S( B  v#include <sys/stat.h>* ]" ?: Q" g0 R. b/ D3 y
#include <fcntl.h>
9 R8 Z: u3 b7 e#include <unistd.h>
, a$ ]; [  B% j; W& e4 e+ L9 n#include <poll.h>! h$ ~8 G. [( R7 G2 N/ b

* k2 u* b3 H' R0 `* G: z+ t/*>
4 u( y0 p2 |! P; u) J8 \& I4 ]
% d; p; I1 f, }) X( r/ P% m$ |原子变量互斥方式测试步骤:, W8 a, U) Y6 W7 J$ _
& d7 |8 v& O1 Q& |6 i
[WJ2440]#>' s, T% H5 f$ i  \) A' H0 p8 ^

5 u$ i" ~4 E9 \' k+ @) ]* S4 |6 F5 k0 V: q5 Q
信号量互斥方式应用测试程序源码:* y  n8 |1 a$ V; |7 }
#include <stdio.h>
2 t) P! J7 T: F' D#include <sys/types.h>& d' z3 ?- A( C6 g- n
#include <sys/stat.h>$ n+ Y5 B& C/ W2 b; u# Y# s
#include <fcntl.h>. w/ }' u- k% g
#include <unistd.h>        //sleep* l% U9 O' m( f  k( I( o
#include <poll.h>1 g1 O2 O* E+ h7 a+ k
#include <signal.h>
# T! N# J3 m" Q! B#include <fcntl.h>) g# q1 _0 e- p! X/ P$ N
+ X) H6 I! O- O- t( I1 g! v; O
int>
. H" O( h' u' K' a0 u' p7 T3 _, w9 ~! d3 v! L
信号量互斥方式测试步骤:0 `, O& b$ P; d; U

. L, @) v9 v/ U( O+ S[WJ2440]# ls5 B0 U, f- O+ }, X; U4 z! S# K* x  Z
Qt             fifth_drv.ko   lib            sddisk         third_test3 d! o" S- F* E/ B
TQLedtest      fifth_test     linuxrc        second_drv.ko  tmp0 G# Y+ u1 O3 c) Z; X
app_test       first_drv.ko   mnt            second_test    udisk& U3 L) A: E  h6 V- F! Y2 E
bin            first_test     opt            sixth_drv.ko   usr; z1 m; s( W0 ^) {5 t4 p0 I2 W
dev            fourth_drv.ko  proc           sixth_test     var" D% W7 ]. T8 S
driver_test    fourth_test    root           sys            web* C0 [# W. q. `( E- L
etc            home           sbin           third_drv.ko8 |; |7 X' h9 k
[WJ2440]# insmod sixth_drv.ko
$ C0 x+ G& E5 R/ i8 h- U$ k[WJ2440]# lsmod              
$ A! `! [$ `( X- f" h4 \sixth_drv 3472 0 - Live 0xbf000000  p( K: E, f1 ]( A
[WJ2440]# ls /dev/buttons -l
/ j9 d" B3 _3 a9 ^) Kcrw-rw----    1 root     root      252,   0 Jan  2 04:47 /dev/buttons
( O: H) u; `+ Z* K; g[WJ2440]# ./sixth_test &9 S; y& s* Y8 H( _: Y% r
[WJ2440]# ./sixth_test &" v7 f+ ]6 X. T4 P' ^0 i8 z, I$ q5 J$ Q
[WJ2440]# ps. m' |2 ]; c) i! c
  PID USER       VSZ STAT COMMAND
1 R; b- T1 c) ^+ e% j/ M1 _  x5 E    1 root      2088 S    init8 b3 J& ~1 B) ?
    2 root         0 SW<  [kthreadd]* W0 H. [& M8 W1 G- H/ |& J7 r, ?. r
    3 root         0 SW<  [ksoftirqd/0]
0 G% R+ {- @0 a4 y, A5 I    4 root         0 SW<  [events/0]
% x, B* z  R  @. Y, [+ u    5 root         0 SW<  [khelper]
0 I7 U6 o: T* f. E1 z0 l/ c: }; p' x   11 root         0 SW<  [async/mgr]
+ V% b# {; \6 p' r: @  237 root         0 SW<  [kblockd/0]0 E/ v' t1 X( F
  247 root         0 SW<  [khubd]
& F# j" ~7 d* J/ B  254 root         0 SW<  [kmmcd]
& L+ F) R/ o! G6 n: c- l  278 root         0 SW   [pdflush]# g# q6 i2 B8 H. @3 R4 y
  279 root         0 SW   [pdflush]) _  ?8 y! {: F4 t2 c
  280 root         0 SW<  [kswapd0]
/ m. C& V) P  D3 }9 s8 q  325 root         0 SW<  [aio/0]* d- C( M9 g. a# @
  329 root         0 SW<  [nfsiod]& T9 _( s- `/ c" a
  333 root         0 SW<  [crypto/0]
0 s; H8 p  {7 Z5 J# O  443 root         0 SW<  [mtdblockd]: W/ g9 f8 ]; U
  557 root         0 SW<  [usbhid_resumer]# ^* d8 ?% C/ b" o8 Q
  573 root         0 SW<  [rpciod/0]
3 L5 k6 @$ e: h' Z" M, ?  587 root      1508 S    EmbedSky_wdg
1 s+ }6 s8 W6 H  589 root      2092 S    -/bin/sh
5 p) m/ e+ n" I8 i& z1 r1 Y  590 root      2088 S    /usr/sbin/telnetd -l /bin/login
( R. y- U! a7 M6 e5 e4 `* ^  E  602 root      1428 S    ./sixth_test
; u9 g9 {! n. p) i! s( u: x  603 root      1428 D    ./sixth_test
- O. \; L3 ^  `3 S  604 root      2092 R    ps
" M/ `# ]  j% ]% Q2 {8 R  ]# F3 w
由上面的测试结果可知:当多次执行./sixth_test &时,可发现进程602的状态为S即睡眠状态,而进程603的状态为D即僵死状态,只有当我们杀死602进程时,603的状态才能变为S正常状态,这也就达到了互斥的目的。
* j. T. I# {$ G, j, o& B$ `& H1 Y' c9 M: L, G+ E

/ \! c! G+ ?' A' o' r
0 L1 s5 t* u. y- |0 N/ W% t
. n9 m+ o/ g' y
7 z: G" p& b  }6 c) O: e
  • 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-9-14 13:31 , Processed in 0.109375 second(s), 23 queries , Gzip On.

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

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

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