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

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
上一节里,我们将在上一节的基础上修改驱动,将其修改为有异步通知功能的按键驱动,目标是,按下按键时,驱动主动去通知应用程序。是不是感觉驱动已经比较完善了,好像已经是完美无缺了?是不是这样呢?好像不是呢,有没有这么一种情况,多个进程想同时使用驱动的设备节点?在多线的环境下,分分钟可能会发生这种情况。
" E! ^3 K; @. [8 K! u& j  ?# [8 i
, j4 d9 f5 J, n! U( I# A; i5 B上一节文章:linux字符驱动之异步通知按键驱动) r- t8 B4 M+ C. C) P! x+ Y
* j5 M0 Z2 r! v( ?" e6 ~0 i
在这一节里,我们在上一节的基础上,实现同一时刻只能有一个进程使用同一个设备,例如:只能有一个进程,在同一时刻里使用/dev/buttons这个设备。+ U# M  u  r. `9 }

& H4 j% G- U$ C% C% c# b. u问:如何实现同一时刻只能有一个进程使用某个设备?
; Q$ U$ B5 Q, H6 B3 }) P1 W- f5 A) V) v; l4 N/ I" [
答:使用linux互斥机制" f- h. I. [3 j# b0 O: S3 V
4 t# T' v: X4 T; O# }
问:linux互斥机制有哪些?1 r; [1 ?, C4 M8 z, R6 ~5 D
4 N* q+ s+ \0 G
答:有很多种,如:原子变量、互斥锁、信号量、自旋锁、读写锁等等% l1 L: M) c5 d) \1 y/ C0 B

  s6 z- x+ R( o/ [7 M" [问:在这一节里,我们使用什么互斥机制?
1 v. g7 d) C, _0 X. n' E/ i/ `2 K1 z" v' m
答:原子变量/信号量,举二个例子来示范linux的互斥机制
4 ]" A! x+ o; |9 D0 }' _- R6 ~# m+ H8 \+ f7 \9 X1 V
问:如何使用原子变量的互斥机制?4 f6 R. A" H  f* a2 e
' _* Y. s) D0 ]. _" P$ A7 h
答:先定义一个原子变量,然后再初始化它。具体如下:
) Q, B' D, E1 {, G9 v
' s5 {% D" N0 Y  Y. r
0 d' T  a1 Z0 z# ^# t' \+ k& o/* 定义原子变量canopen并初始化为1 */. E& [* b2 Q( Z' F# |+ A2 z
static>1 P. G4 I' P8 O8 U- q. ?
问:与原子变量相关的函数有哪些?
  C1 a* V1 E/ o( R8 i% N答:原子操作指的是在执行过程中不会被别的代码路径所中断的操作,常用原子操作函数举例:
# k/ q* }" L# V( K) }7 m5 k, K% W9 X) o# b0 n( P" j
0 A0 Q8 _% A) V# F& L
atomic_t>
: j# y) \. u9 w7 y! U. ^问:原子变量相关的函数在此驱动里,在哪来会被调用?7 V! ]% u4 V3 [7 I
答:既然是防止多个进程打开同一个设备,那自然是在open函数就调用,在close函数也会被调用,示例如下:
& O- Q' o9 A. ]+ {, h+ f4 u5 o1 f" m* U! [  O$ z6 e( J$ v
! M$ w3 L  `8 t
static>, C9 d* r+ G/ \8 g8 L8 M+ ^; `

9 w) T( m9 G  b7 j, R0 z' ~  ^7 S1 H$ {
原子变量互斥方式应用测试程序源码:
6 C* f% y. x$ R) k! e' k  ?2 _% {) C& W7 L5 @

/ q! b) w/ o7 s1 h$ ]8 Z. G#include <stdio.h>
9 C' w9 D" p8 B- h/ h, v#include <sys/types.h>
/ _" }% {( H2 I$ Y3 ]#include <sys/stat.h>
1 w  u' |7 H- L#include <fcntl.h>
' J+ `+ f$ C( P8 Q#include <unistd.h>4 f9 s; j* E  f, L
#include <poll.h>
* W- ]9 ]2 Z) a# q: H, j* h/ a
/ d' D# B9 I& p/ t6 g& S/*>
& S* f" i: x7 a) ^( X( p* j
$ m* B! n) ?: f2 p- ~2 L原子变量互斥方式测试步骤:. x' l6 J5 \1 j: Q2 P( z
% h3 d0 Z& F/ X3 S# M2 W4 {% A+ b
[WJ2440]#>9 J3 n! Z) Q, T, u: N' b0 ~9 j

( @, Y4 t. h: H9 B: ^1 F
) f3 `( C& a( u1 r' I# X信号量互斥方式应用测试程序源码:9 ^- j: j) e" M/ i
#include <stdio.h>7 s) d' e, O5 b  Z6 f  W
#include <sys/types.h>0 f& z+ W1 i8 P. Y+ T0 P: D
#include <sys/stat.h>4 N. a' T3 J% i% J3 c
#include <fcntl.h>! f8 \: P- V; v5 V; q
#include <unistd.h>        //sleep* E7 O/ U! W6 i9 N! K
#include <poll.h>' K6 q, L) k1 p' [  Q
#include <signal.h>
5 t5 E9 ~9 c% f" o  n#include <fcntl.h>6 T% @( x: `0 O$ }1 X

5 Z! ~- S  w, y$ ]7 k! Bint>
/ u4 K/ X$ [: P! x9 L' b2 i1 m
/ \# p- B8 m2 F% N! K8 v1 c8 |- P信号量互斥方式测试步骤:/ }8 H7 q$ j1 H. o& ~8 @) r
/ P8 S" A2 ]; o" F" F9 @- a
[WJ2440]# ls
" j  H% a% B& b) d' ?$ a! mQt             fifth_drv.ko   lib            sddisk         third_test/ T! T% v, i3 t9 Q& K4 m% E/ ^
TQLedtest      fifth_test     linuxrc        second_drv.ko  tmp+ ]* O1 E& e; k/ A7 x" o. G4 `2 p
app_test       first_drv.ko   mnt            second_test    udisk
) f1 E2 c, e8 ~/ G$ f4 j. ^6 Cbin            first_test     opt            sixth_drv.ko   usr- y8 r. U2 l4 Q
dev            fourth_drv.ko  proc           sixth_test     var
' ]% g# `  O" c, udriver_test    fourth_test    root           sys            web
0 B3 D' K- H$ d+ setc            home           sbin           third_drv.ko( s6 a# R( y8 F4 w6 H( _% U
[WJ2440]# insmod sixth_drv.ko 0 c: ?3 u. E, @  C; R8 v. p
[WJ2440]# lsmod              
8 I; o7 n. ?4 h/ {/ lsixth_drv 3472 0 - Live 0xbf000000
; W, r; t( d+ j* n( M9 z[WJ2440]# ls /dev/buttons -l: f( H5 s  |6 ?+ J7 S+ \: o& `
crw-rw----    1 root     root      252,   0 Jan  2 04:47 /dev/buttons
* O0 F: P- A/ `. h/ ?9 [1 G[WJ2440]# ./sixth_test &
1 d% \, _+ z) F- P[WJ2440]# ./sixth_test &
5 |8 w0 |! U- V3 W) t[WJ2440]# ps1 m# |2 A' l5 R
  PID USER       VSZ STAT COMMAND% q8 E: t8 _6 e5 M8 g6 T
    1 root      2088 S    init
6 c: U. d( Y" ?    2 root         0 SW<  [kthreadd]
  k( ?8 g: {: y2 T* [# y6 O    3 root         0 SW<  [ksoftirqd/0]
: o% ?# H7 U% Y    4 root         0 SW<  [events/0]8 H6 @' s- [5 X  C4 S6 K
    5 root         0 SW<  [khelper]7 m$ P) k3 l# y5 x# Y
   11 root         0 SW<  [async/mgr]
7 C+ i9 I) h5 r, i+ r! ~  237 root         0 SW<  [kblockd/0]
' U9 c: A2 a2 w" G  247 root         0 SW<  [khubd]
6 s# r" I7 A( X/ G" b  254 root         0 SW<  [kmmcd]
  t% N: d% n: J9 l& ~( d. K  278 root         0 SW   [pdflush]" l7 o. k* V- s' f" P' Z  I' ~
  279 root         0 SW   [pdflush]7 K3 c% R" M: z1 h7 j  A
  280 root         0 SW<  [kswapd0]
/ B; H; {* l% C8 s+ c) L  325 root         0 SW<  [aio/0]
0 o9 O% R9 O+ x  329 root         0 SW<  [nfsiod]
2 A6 N/ U2 d- W9 w8 N  333 root         0 SW<  [crypto/0]0 ^. ^+ m5 `% t
  443 root         0 SW<  [mtdblockd]3 o- ~) i5 L3 t" M- \
  557 root         0 SW<  [usbhid_resumer]
, {  k- `' R5 Q+ B/ c  573 root         0 SW<  [rpciod/0]
; ~( {6 d0 j2 e9 F$ @3 h  587 root      1508 S    EmbedSky_wdg
) ?* `6 y  n3 M9 \  589 root      2092 S    -/bin/sh
/ J/ q! R  [, s6 P" @* d1 {  590 root      2088 S    /usr/sbin/telnetd -l /bin/login
% L& v$ k1 d2 P  602 root      1428 S    ./sixth_test
. r" C( a" L2 ]' {  603 root      1428 D    ./sixth_test6 q1 H" Y' @: G; X
  604 root      2092 R    ps
2 _( V0 K$ i8 n& Z" r4 Q  E- W: u4 Z, l8 l4 g3 c) \
由上面的测试结果可知:当多次执行./sixth_test &时,可发现进程602的状态为S即睡眠状态,而进程603的状态为D即僵死状态,只有当我们杀死602进程时,603的状态才能变为S正常状态,这也就达到了互斥的目的。
- r! T3 w  J8 W/ l3 x. r+ x5 f
6 _; W# U4 ^3 ~- |. u8 ^% H2 l! v5 t4 v. f+ B+ ~  H. S

4 x2 k' S7 ?" a
, N3 Z! B9 S6 ?2 w0 n: B6 c7 N9 x5 f
9 }% x0 e1 p1 b5 p5 Z4 `& 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-11-26 07:53 , Processed in 0.156250 second(s), 23 queries , Gzip On.

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

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

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