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

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
上一节里,我们将在上一节的基础上修改驱动,将其修改为有异步通知功能的按键驱动,目标是,按下按键时,驱动主动去通知应用程序。是不是感觉驱动已经比较完善了,好像已经是完美无缺了?是不是这样呢?好像不是呢,有没有这么一种情况,多个进程想同时使用驱动的设备节点?在多线的环境下,分分钟可能会发生这种情况。
5 E$ B6 i5 e; g* H( b
- J2 u7 }& h/ F8 j' n, M' k上一节文章:linux字符驱动之异步通知按键驱动) t: @- v& C" ^( r$ h% |0 N! J
5 Q8 t" b9 {: h$ {8 F; J  ^( I
在这一节里,我们在上一节的基础上,实现同一时刻只能有一个进程使用同一个设备,例如:只能有一个进程,在同一时刻里使用/dev/buttons这个设备。
; a2 i/ S8 ^, Y
" }  {2 @6 w- k. W# z/ S3 G. i问:如何实现同一时刻只能有一个进程使用某个设备?& D5 i* n8 d2 k2 l. l6 `9 S# V
; S% @7 v) v7 ]. R' w, ^1 @
答:使用linux互斥机制) F" U" b0 P. j& f+ f+ |
. ]0 T  I1 Z- M8 f
问:linux互斥机制有哪些?7 t" i! f5 k0 Y/ K- E4 o
; N2 c" }0 R6 L
答:有很多种,如:原子变量、互斥锁、信号量、自旋锁、读写锁等等
# X( q  N7 s( `2 n7 |  V( x
* i" @# y2 b0 E9 _6 X! r问:在这一节里,我们使用什么互斥机制?4 H) z& Q  R5 I" i  d$ s

* O( l& Y8 ]! E- I2 ^0 s, d" l5 C答:原子变量/信号量,举二个例子来示范linux的互斥机制
* _6 ^0 |  R$ O0 S7 i' P
' M! o: d" v$ O5 c1 L) c问:如何使用原子变量的互斥机制?* p3 X, F) ?8 |+ d

# i2 ]/ ~# m; ^: ~( g答:先定义一个原子变量,然后再初始化它。具体如下:/ l. W0 r0 _$ \  @; x6 H
' I! Z) Y. p! U) P

* |3 B; ~9 K% O$ }/* 定义原子变量canopen并初始化为1 */% C/ q; ~$ P0 ~+ U7 e
static>; ?9 t5 k; i9 f) {. H8 b1 J/ N
问:与原子变量相关的函数有哪些?
9 A/ I' D  z4 U/ c  b) ~答:原子操作指的是在执行过程中不会被别的代码路径所中断的操作,常用原子操作函数举例:
3 ^; B6 B1 a, _: ~4 F6 j6 c) i4 @3 h. u: m5 U* t# B
4 v9 e' |! Y  n4 a  I
atomic_t>$ t  Q. n0 m" r# W
问:原子变量相关的函数在此驱动里,在哪来会被调用?
+ k( G# L7 Z; Y: ^答:既然是防止多个进程打开同一个设备,那自然是在open函数就调用,在close函数也会被调用,示例如下:
# \5 X: m/ V; E  o& k8 R1 b4 i* o9 G( {$ T$ M  o
+ l3 I' t; w4 M! p
static>
; u* K- Z, [' f3 E+ l- ]/ x  t6 w8 ^+ ~

' F6 {2 \- u5 z# B+ K1 u原子变量互斥方式应用测试程序源码:$ V8 K# b+ c1 J( H) B
; E% v% e6 h" ]. V4 _

/ \0 z  _* d; @& h& k#include <stdio.h>
" c2 |+ C  `, Y1 {# a# O7 h#include <sys/types.h>
! H% L0 c5 q3 p( b& }& B#include <sys/stat.h>
2 V$ j0 j" d, W#include <fcntl.h>
2 I/ o7 J3 O4 X% N* O#include <unistd.h>
( B/ V3 E, A4 u* v2 T#include <poll.h>' I( S' S7 {* k7 Q& C+ B# \

6 d3 ]- T# M  G- A/*>. L$ ?  c( I) T- y% U' R9 c

5 Q: O3 `$ J% m3 E原子变量互斥方式测试步骤:
2 p+ S& t2 B3 b" z/ ^& K
" o- R% V3 Y3 n# e: [# ][WJ2440]#>+ q7 n6 o! `/ F" _, e' {9 T# J. k

6 b) i1 X8 |& W0 h% W: G4 v; l7 w5 \' A
信号量互斥方式应用测试程序源码:
* C+ A* J# S: K8 F#include <stdio.h>
, N3 k, L" g% Y" K  p0 W7 b#include <sys/types.h>7 Z1 s1 U2 C" ^& Z$ b$ Z+ R6 v# m
#include <sys/stat.h>! o( l1 E& r/ A! ~4 U, V
#include <fcntl.h>
; J4 f" i' `! I) e" g: l#include <unistd.h>        //sleep
4 ]2 `. X5 v( t7 I/ c+ G1 T; V#include <poll.h>2 O$ _4 C  x  J! G* I4 I  W1 B6 Q
#include <signal.h>
7 r, s& D- ]: ~; R$ n# K#include <fcntl.h>" J9 R2 A7 X) F' @$ h* `

% ^% v2 B$ p1 \6 g& Pint>  |7 X( P9 p: ?* y5 I
6 m0 h4 \3 N5 f0 y
信号量互斥方式测试步骤:1 V2 L5 v& v1 O7 C) Y; [, d: p; H) O

) A+ z6 D0 D: n  i+ t0 {[WJ2440]# ls
9 U6 R, E: q2 MQt             fifth_drv.ko   lib            sddisk         third_test
) M) }# ~9 W# L- ~: w: pTQLedtest      fifth_test     linuxrc        second_drv.ko  tmp
8 E6 J# P0 a* D8 h/ Vapp_test       first_drv.ko   mnt            second_test    udisk, p) j' s5 w4 g+ T3 H8 O' ?/ p
bin            first_test     opt            sixth_drv.ko   usr' I! I! ]% s, z. r0 x" S6 A/ ]* A" r
dev            fourth_drv.ko  proc           sixth_test     var
5 }* w6 W7 B. W* s. K6 b5 A. ?driver_test    fourth_test    root           sys            web
9 K5 v* n2 K% r; a; Cetc            home           sbin           third_drv.ko; N+ U9 L$ _; g% m) x3 Z/ r/ Y
[WJ2440]# insmod sixth_drv.ko
! L+ J+ o" `) l. \) v  L8 F8 _1 E[WJ2440]# lsmod              + Z' ?5 r8 ^0 d
sixth_drv 3472 0 - Live 0xbf000000
3 u" x9 f5 \8 m7 |4 s$ N[WJ2440]# ls /dev/buttons -l
/ r6 l9 Y( ^7 i  _1 T" Zcrw-rw----    1 root     root      252,   0 Jan  2 04:47 /dev/buttons8 v& X5 y- n' K% i
[WJ2440]# ./sixth_test &9 V+ s& s4 G% c9 Y0 H
[WJ2440]# ./sixth_test &( U* \. M2 o& D( k( M* a9 I  r" M
[WJ2440]# ps1 _. D8 M; k; [$ V4 \, z
  PID USER       VSZ STAT COMMAND
/ U+ j# q. u8 k" \. h) [    1 root      2088 S    init8 S* U0 R7 J8 {& R7 E
    2 root         0 SW<  [kthreadd]  Q: ^5 q  _$ M; n3 S
    3 root         0 SW<  [ksoftirqd/0]% v" p3 k& ?; C: I6 ]% O, S/ r
    4 root         0 SW<  [events/0]/ h" K6 z& w. J! N
    5 root         0 SW<  [khelper]7 r  q. y+ e6 m- Y/ E
   11 root         0 SW<  [async/mgr]
3 o. H) c: m( G: G  237 root         0 SW<  [kblockd/0]
4 w! R& c' F/ w% P# Y# M  247 root         0 SW<  [khubd]
3 Q" o+ t' h" |' B; E3 T! P  254 root         0 SW<  [kmmcd]
  k4 j% O/ C, d, p: l  278 root         0 SW   [pdflush]
  D7 E$ ^3 [4 c, F( J8 b" D8 s' C  279 root         0 SW   [pdflush]
- z: B. p) d, N8 N  280 root         0 SW<  [kswapd0]
% V" j: v2 v' p: E( c  325 root         0 SW<  [aio/0]9 c% `4 z/ Y1 U& k* R- s
  329 root         0 SW<  [nfsiod]
/ X1 r% _) m! W0 q! L  333 root         0 SW<  [crypto/0]5 |" m" {8 @, P
  443 root         0 SW<  [mtdblockd]4 ?8 n3 C' J  t6 K6 z" C
  557 root         0 SW<  [usbhid_resumer]  u7 g; v/ D% Z# i0 T% B- Z% w
  573 root         0 SW<  [rpciod/0]4 O9 T5 y7 u5 U2 _/ ]4 Y
  587 root      1508 S    EmbedSky_wdg
- D( j3 X9 O; w& A! l* i  589 root      2092 S    -/bin/sh; y- q* l$ ?( }0 A
  590 root      2088 S    /usr/sbin/telnetd -l /bin/login* k6 i5 j1 K! {4 N$ \: D) J* C
  602 root      1428 S    ./sixth_test7 X- e+ A5 e: l3 X, \0 C/ E
  603 root      1428 D    ./sixth_test+ B% d  W# K1 S8 G. H; `, D
  604 root      2092 R    ps3 x* J7 L" d' i
2 _* U$ E, m$ G( i( ^' H7 H
由上面的测试结果可知:当多次执行./sixth_test &时,可发现进程602的状态为S即睡眠状态,而进程603的状态为D即僵死状态,只有当我们杀死602进程时,603的状态才能变为S正常状态,这也就达到了互斥的目的。
9 M0 e) N& m4 e- q+ {
3 I/ h! A1 z5 {. H5 N. |5 D: o5 |- x. ~
' B( Z2 i) X6 U$ [6 s1 f  C

7 I5 R2 F$ w0 a; b! H* S  x, l
5 J; I* K2 [( o$ l9 J
  • 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 22:22 , Processed in 0.140625 second(s), 24 queries , Gzip On.

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

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

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