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

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

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

& F- U1 ]0 h% Y- [9 D5 Q& L" q- u上一节文章:linux字符驱动之异步通知按键驱动
7 y+ }  q4 Y) I. X. G- J0 I: S6 R# M
( `: a' U3 ?; T2 E! j! ~8 d! I在这一节里,我们在上一节的基础上,实现同一时刻只能有一个进程使用同一个设备,例如:只能有一个进程,在同一时刻里使用/dev/buttons这个设备。% p/ S7 c. j5 T4 T
6 r1 L3 O& [2 @
问:如何实现同一时刻只能有一个进程使用某个设备?5 H! R# [! ?! V, L' g

  ]/ {5 L, P! ^1 {答:使用linux互斥机制5 L" r: L- F9 i0 K: ~

- \) k$ z/ n/ i3 C5 W问:linux互斥机制有哪些?5 b/ J# t) J0 f$ N, _
) ]  }% m8 G( F& f3 e
答:有很多种,如:原子变量、互斥锁、信号量、自旋锁、读写锁等等
& C1 G2 [6 z! R. j
% S3 R; [6 I* q+ \7 t问:在这一节里,我们使用什么互斥机制?
5 R3 x: e) d+ E0 S" G1 \7 y8 J, R9 A% m4 ]1 P9 V) ]
答:原子变量/信号量,举二个例子来示范linux的互斥机制! ?1 C& I+ ?% r5 d7 T: h

0 O% J2 w( \: o+ Q7 @, P' W- M问:如何使用原子变量的互斥机制?1 ]3 M0 L* s, z! u$ I
. ?$ \/ }5 u( A8 p5 k7 K# y* \
答:先定义一个原子变量,然后再初始化它。具体如下:
( v" ?" t) Z8 t+ E0 [
! _4 U! N; f/ [' u2 M
: ?7 `: g" W5 m2 @/* 定义原子变量canopen并初始化为1 */
" {! \% C% d. Y! D8 N9 Tstatic>& Y) @+ C& Q' p
问:与原子变量相关的函数有哪些?
# d' J) e7 H1 L  j答:原子操作指的是在执行过程中不会被别的代码路径所中断的操作,常用原子操作函数举例:
: J8 w8 T* A0 i9 C+ P& d5 I
+ M. {: E; O, v3 O, p; E" y" A: [6 d) k4 s' f+ j0 M! p+ n3 ]' T
atomic_t>
4 b$ e# x2 p2 v7 T问:原子变量相关的函数在此驱动里,在哪来会被调用?' j6 d: w& v8 r  K: N
答:既然是防止多个进程打开同一个设备,那自然是在open函数就调用,在close函数也会被调用,示例如下:
/ j" j5 J5 m$ X, a" W5 Q& {* k
  r1 ~6 V$ s9 ^5 S& _
4 T+ z; r" X- g, W! Y* Z3 Astatic>
* z/ A- l' o% B6 d# J) t0 o1 C8 T* M, f

6 S. `) Z6 g5 k2 U' W6 @3 |原子变量互斥方式应用测试程序源码:
, r  Y& o; _. G8 T
* i" X' s$ y( ^2 n
. M5 [: @, l- S4 U8 v#include <stdio.h>
; l- `% g+ L' g#include <sys/types.h>* h; b* P% V7 f' z9 h
#include <sys/stat.h>, k" \2 }% V8 v% N. `
#include <fcntl.h>1 t9 ^8 w% |6 l" `( s" a5 p( O
#include <unistd.h>
. K' T2 u+ d0 J9 V" r0 V#include <poll.h>
: F& w9 a; o3 E* ?. [
5 D* a4 N( l+ j5 t/*>7 ?* y; C$ u6 y- L3 p( c
. V( ^" M5 o0 A2 w& b- d' h
原子变量互斥方式测试步骤:
- S; ~) h$ X  y
7 N0 y) k9 j* G& E0 H; X[WJ2440]#>
, v% u5 U, u& s4 p6 ^- t9 Z  g3 l- }1 q; C/ Q$ Z( L$ H
/ w; S* `; `9 O( P1 G0 ?7 i' U6 T$ M
信号量互斥方式应用测试程序源码:
6 H$ J. U. o$ j6 }* s$ s#include <stdio.h>9 C& e  n2 E  l5 K2 q+ v6 A+ @- |
#include <sys/types.h>
# L9 A2 H  e1 B* Y, W#include <sys/stat.h>
. x3 W5 A' U8 J6 D#include <fcntl.h>
2 A2 d' ?. [" ?* H! o#include <unistd.h>        //sleep
; u, L2 `2 ?6 A% a7 P7 F' d#include <poll.h># x/ Y3 ~& R* `) X% A8 m2 W9 l
#include <signal.h>  `2 ^8 X" \+ G
#include <fcntl.h>
, m# i! p( g3 }1 w, ?% M, ^* C- s( m& N' S  L
int>
2 @& v, r& E. d# ^. X2 G* g2 b. a4 d4 p# P- u
信号量互斥方式测试步骤:
- L' ?( T! B* G: C+ a- ?* F  o+ E# x. ^
[WJ2440]# ls9 F) |- y5 ~& L6 h6 w3 L
Qt             fifth_drv.ko   lib            sddisk         third_test
( a8 H7 v8 H7 a/ x' {5 ]1 E9 v% \% ZTQLedtest      fifth_test     linuxrc        second_drv.ko  tmp" g  G: Y1 T; I# [6 Q7 {! s0 [
app_test       first_drv.ko   mnt            second_test    udisk; H! u1 }& G" m  W! B% }# `
bin            first_test     opt            sixth_drv.ko   usr5 _# p. b' a$ B8 @. P
dev            fourth_drv.ko  proc           sixth_test     var
. m& m2 j0 B8 V& d! gdriver_test    fourth_test    root           sys            web
* n: f* m6 Z8 h0 ~, Z+ X' Z- Yetc            home           sbin           third_drv.ko* W& v/ A* W5 R* x0 Z3 U, k4 K
[WJ2440]# insmod sixth_drv.ko 1 d! {+ W$ e" q( b
[WJ2440]# lsmod              : f( z/ l! H" u. ]$ t$ f
sixth_drv 3472 0 - Live 0xbf000000
9 C2 @0 W' O: K% l5 ~[WJ2440]# ls /dev/buttons -l/ k9 C  d/ x+ x9 X! ^& c% L, E8 }
crw-rw----    1 root     root      252,   0 Jan  2 04:47 /dev/buttons
( f0 y$ x, f5 r4 \2 A+ s[WJ2440]# ./sixth_test &' B) }+ v9 q* p* R
[WJ2440]# ./sixth_test &; O. D% c' a- B( R4 r8 P. f
[WJ2440]# ps; s& F7 t- S3 w
  PID USER       VSZ STAT COMMAND
; y* N" u" P" ]0 ~% X9 i. ]6 w    1 root      2088 S    init
* f0 W! m2 p3 {) M    2 root         0 SW<  [kthreadd]# u+ d* `) A3 t3 ]2 X2 I  Z
    3 root         0 SW<  [ksoftirqd/0]# J8 t+ ~! W- f- M. g
    4 root         0 SW<  [events/0]( W. Q& R0 \* s7 w( |
    5 root         0 SW<  [khelper]5 v. d- s2 T8 u0 d& m
   11 root         0 SW<  [async/mgr]
( i1 |4 u( }2 L) R: S  237 root         0 SW<  [kblockd/0]
0 Q9 I: L. S; G) ~  247 root         0 SW<  [khubd]! w. _# F! _; J7 I0 V9 f
  254 root         0 SW<  [kmmcd], o& g- o8 @' p. ~3 J
  278 root         0 SW   [pdflush]
6 B4 u& y- x1 h  279 root         0 SW   [pdflush]
) H  P% n# _+ s, @* x* ?$ @* s  280 root         0 SW<  [kswapd0]) I0 Z# D5 N# _8 b& S
  325 root         0 SW<  [aio/0]
. y8 z5 {, t( N  G  329 root         0 SW<  [nfsiod]
- p3 U8 |4 J1 n( r  333 root         0 SW<  [crypto/0]; c4 ^2 m$ P9 \6 Y& Q5 \
  443 root         0 SW<  [mtdblockd]! U* v, N& [! ^' w* C
  557 root         0 SW<  [usbhid_resumer]8 l1 p0 a& o* x- m
  573 root         0 SW<  [rpciod/0]" D. U; {, j2 h: w3 `+ j6 Q
  587 root      1508 S    EmbedSky_wdg" F7 y" ^3 I  s" q7 _6 b6 ]
  589 root      2092 S    -/bin/sh; E" h: z  X! g% Y) @  F
  590 root      2088 S    /usr/sbin/telnetd -l /bin/login6 y. ~, k1 _" E; V, t
  602 root      1428 S    ./sixth_test
% Z. \; ?: m" H* I) ~  603 root      1428 D    ./sixth_test$ c5 X- g9 Z) ~; o: p: X
  604 root      2092 R    ps
/ m  Y# W$ x0 f0 ^1 F+ w0 j7 f/ L% x/ I
由上面的测试结果可知:当多次执行./sixth_test &时,可发现进程602的状态为S即睡眠状态,而进程603的状态为D即僵死状态,只有当我们杀死602进程时,603的状态才能变为S正常状态,这也就达到了互斥的目的。0 G. H( O( U0 o9 @$ d& d

! q, m) e# d" B( C8 O5 O$ L" }* h0 D
9 t5 o  Z7 i5 O# O$ |) W5 e

6 n- l; b8 i7 \  R/ l( d/ s7 w6 \$ s
  • 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-10-27 00:29 , Processed in 0.156250 second(s), 24 queries , Gzip On.

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

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

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