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

linux字符驱动之自动创建设备节点

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
上一节中,我们是手工创建设备节点,大家肯定也会觉得这样做太麻烦了。
) c+ q, X* {+ ~. L$ f6 r
  C: y6 }' k( v$ o, p上一节文章:
( H3 D. p0 `- Y
问:能不能让系统自动创建设备节点?
' Y( T3 ^' X3 @/ E0 R3 v- t0 \5 u' S5 A" p1 G6 b  b
答:可以,linux有udev、mdev的机制,而我们的ARM开发板上移植的busybox有mdev机制,那么就使用mdev机制来自动创建设备节点。+ I; M1 Z2 ]5 c; ]

- y4 o' K7 o3 [" C. y问:文件系统里,在哪里设置了mdev机制?
, a' e, p! c9 p5 O5 ]  }8 k: B8 g& P7 H# s. D% l% A9 F
答:在etc/init.d/rcS文件里有一句:: L" G; A: B& L

1 W5 \: `8 U2 d: {, Hecho /sbin/mdev > /proc/sys/kernel/hotplug9 \  e5 ?; r8 q4 X$ a5 R
. R4 q/ N" F7 e+ c7 n1 Z
问:在驱动程序里面如何编写程序,让系统自动创建设备节点?
5 [" k, Z' r6 U' {. s1 R
+ O4 j' ?' v! ^! G1 [# Z- |/ u答:首先创建一个class类,然后在class类下,创建一个class_device,即类下面创建类的设备。
& W: D$ m' X, S( S8 K/ X1 \: \1 O
' {, ]% G. R1 B3 T* X& C: F3 P
, E; x! D3 g! H1 f/ b1 r1 M: Y8 D* F" m& z
详细请参考驱动源码:
/ K' ]) ]$ ~+ x0 g% X- b* v
" w/ c2 t' N, u+ [& Y, b0 |5 ~! c8 o8 m2 N% L3 j, V
#include <linux/kernel.h>0 d+ q9 v6 W( e" ~7 m' y( m5 d5 X! R
#include <linux/fs.h>
2 f# \& ^0 _$ M- x#include <linux/init.h>
6 n8 X& K& O1 F4 V2 Q, I! O* p#include <linux/delay.h>% ~8 N. ^) `& A# ^. d9 q, K: J
#include <asm/uaccess.h>
4 |0 J. W6 A3 B6 _. V/ q" a#include <asm/irq.h>3 T2 H! E# r! E; D" q2 b5 y
#include <asm/io.h>' F. r7 U. U* u1 _- x( @/ ]
#include <linux/module.h>
& Y" z- g$ _: R: r1 j& k+ q8 l#include <linux/device.h>         //class_create
/ e$ b6 V9 n& p0 r3 `" s* V
3 M  e% Y5 R( H9 j. u' |static struct class *firstdrv_class;& I  t& J0 H& j% i# I& G
static struct device *firstdrv_device;3 ?8 g: ^& [3 Y

8 x# A1 V0 y5 R8 @3 t0 }int major;
' ]' B0 a& n' nstatic int first_drv_open(struct inode * inode, struct file * filp)+ M. n7 E* _/ V( L8 H3 m0 {  `
{8 s0 k3 ]. _& q! Z7 Q0 K
        printk("first_drv_open\n");! B6 W) P( M: D; H
        return 0;
, }  V9 O/ I# \6 p6 K) H# T9 H}8 L7 n8 c" e  E1 b: R
static int first_drv_write(struct file * file, const char __user * buffer, size_t count, loff_t * ppos)
9 B9 u. o1 b: i2 B! k( z{' r5 O, U( ]- {, h( }5 U+ f; ^9 ^
        printk("first_drv_write\n");% R. g# U; v  d5 C
        return 0;
3 F" j$ _& O! L# D6 v}7 h4 V7 Q  R1 {1 l! n. i/ _% @
7 c% j5 q% \# S) x
/* File operations struct for character device */; n4 @% o/ g6 m! d$ M1 j8 S* N. s
static const struct file_operations first_drv_fops = {
+ m  l' |9 N+ A        .owner                = THIS_MODULE,
7 o0 C+ @$ X( z% y( c        .open                = first_drv_open,
4 ~! ]( M8 A( r) P+ A7 s5 N        .write      = first_drv_write,, N, a' j% V! |* w( q2 @) Q. s
};* n- H4 y4 D$ Y0 S4 L- F" \

! L3 n- c: \  T/* 驱动入口函数 */
9 X) r: t1 f. \3 Y0 ^2 |- u/ }static int first_drv_init(void)
+ m3 J: o- r$ V/ `; q+ g) s{- g0 ^$ i/ ]* w. S
        /* 主设备号设置为0表示由系统自动分配主设备号 */, L7 s+ u$ n: v/ l
        major = register_chrdev(0, "first_drv", &first_drv_fops);6 W: Y( b7 ?7 [, @6 Z+ R" m

7 Q4 o% |" f* `% x        /* 创建firstdrv类 */
  x  V- C/ N! Q, h7 B, G6 x) {        firstdrv_class = class_create(THIS_MODULE, "firstdrv");
% I2 S+ W: ?0 i
% ^, u5 h! |( a0 h- j$ m        /* 在firstdrv类下创建xxx设备,供应用程序打开设备*/: {. I: H/ l5 g4 v
        firstdrv_device = device_create(firstdrv_class, NULL, MKDEV(major, 0), NULL, "xxx");
) J. g$ ^; I1 e1 h& ]/ {4 `        return 0;
* e  n- y; ?, `7 D8 s3 @" X& g}
9 w5 j6 _* M6 T9 m/ e3 W. S1 K+ O6 }3 i7 y" v
/* 驱动出口函数 *// W9 i' V! J! S4 |3 F3 w/ w$ O
static void first_drv_exit(void)
2 ]& C* o8 p8 L$ h' t: {( o* x" i  M6 W{
# k- X6 U/ I- m5 H( W* z        unregister_chrdev(major, "first_drv");
6 v( W) s/ T' P: V. o6 h( h        device_unregister(firstdrv_device);  //卸载类下的设备# l8 v3 x+ s, e+ ^
        class_destroy(firstdrv_class);                //卸载类) G: X: i& L' O$ ^( y) f
}3 `! j3 k. M# N( i
( _( W' {- I( u8 a1 Q; F) G
module_init(first_drv_init);  //用于修饰入口函数
( x6 D7 y6 O; e1 [module_exit(first_drv_exit);  //用于修饰出口函数        
7 G4 ]" _! n% X  w3 u# P+ k( m5 n  B" z' s% B
MODULE_AUTHOR("LWJ");
- ^# P: C! @2 PMODULE_DESCRIPTION("Just for Demon");# f( V4 P7 n8 z# q
MODULE_LICENSE("GPL");  //遵循GPL协议+ @" S! H" F% \# L0 \% l: R: l! O

  i9 U0 k1 J9 R- C: H6 |5 u! D5 ?$ C0 b7 P6 @
注意事项:
6 _* e. y# J3 F4 g% K9 [# \% ?3 q$ N1.因韦老师使用的linux版本跟我使用的linux版本不一致,头文件路径可能有所变动。1 @1 C/ T1 c0 F& S8 m5 _% X

  d' ]1 V- H8 S8 N1 N  ^2.使用的函数名可能也不一样,例如:
& N3 K7 I) h9 Y. A9 e- _8 K6 X$ W0 A$ ~# M- `9 @2 b  H" W" Z
韦老师是这样子创建类和创建类的设备:) ^7 b0 a" w6 N3 S- K. ~3 t* r

/ v/ f% L, {7 g8 {一、定义; a2 Z/ o) o4 n0 T1 \" _8 w
2 E  H- x$ w/ t
static struct class *firstdrv_class;
; K" a2 R$ G* u' [static struct class_device *firstdrv_class_dev;) C/ c0 ^6 g! g: Z0 _1 h. L
) w3 J2 c5 F8 ~: F8 G3 m2 G* v
二、入口函数里. o+ F. ?) S0 s# q0 U3 w2 R) s$ O5 z

3 i% o( a. U  Ffirstdrv_class = class_create(THIS_MODULE, "firstdrv");' L2 D5 J8 l/ z
firstdrv_class_dev = class_device_create(firstdrv_class, NULL, MKDEV(major, 0), NULL, "xyz"); /* /dev/xyz */
, H' R; @7 H9 O( P/ a0 y' g0 [; E
三、出口函数里
) ~/ J6 L/ o3 }2 N6 f0 B; M# [- s' l& C1 {& C6 m8 _
class_device_unregister(firstdrv_class_dev);
! O! m8 ]. Y" ~+ X6 Nclass_destroy(firstdrv_class);
9 i# v: N/ g# H' |/ D7 I3 U' J* B+ P8 j4 m7 X" v
; r8 Q/ u: t6 f

  N7 I* {: Y: d' R( M而在linux2.6.30.4里,并没有class_device_create和class_device_unregister函数0 X: R' \/ t& I( T( F& o' u

! Q1 Y3 z& |2 j+ t+ j我是这样子创建类和创建类的设备:$ Z: B+ T! P( t4 l6 L7 O! x

% J! D% d0 H- `! k一、定义
* p1 s$ C/ G  Z* L" r3 P. V0 s1 v
+ V  L# J7 |, B9 O0 nstatic struct class *firstdrv_class;$ Q$ D1 U. T2 N7 }5 W
static struct device *firstdrv_device;* Z7 K' R# F. ?0 R2 s7 T& r2 A* e

- T' Y, U! _1 m8 W二、入口函数里6 `$ L3 _; i3 O% [
4 e& G- J. v' l9 U3 @* Q* U
/* 创建firstdrv类 */! b& X6 Q, E, Q/ y' s

4 F- h6 G. `  l# u0 Vfirstdrv_class = class_create(THIS_MODULE, "firstdrv");
6 e' ^' Y$ r6 |6 ~0 r. }  r' q6 H, Q: \& K. A
  A! }" `$ r$ P. E5 Q
/* 在firstdrv类下创建xxx设备,供应用程序打开设备*/& }3 v, r- k$ n2 I
firstdrv_device = device_create(firstdrv_class, NULL, MKDEV(major, 0), NULL, "xxx");; j+ Z: C! K7 G! q  C8 q

4 }1 X% |4 x1 _: ]三、出口函数里7 I0 X3 {- A/ i# y+ Z7 p9 q

. u2 _+ U1 r: i8 {% k7 Q3 v7 [4 rdevice_unregister(firstdrv_device);  //卸载类下的设备4 s  u/ s% z' I. P; V5 g$ d
class_destroy(firstdrv_class); //卸载类! x4 p* I' {2 _% ]9 p! p* s! B. t

/ p/ _/ ?6 A# E; h8 c
) o7 D) {9 T! z% J# }
/ r# X0 @' D; Xlinux2.6.30.4使用device_create函数替代class_device_create函数;
: [9 {6 I  c3 G- x) }# V: A# q, m7 v7 ^* t
使用device_unregister函数替代class_device_unregister函数。
) d, G* k: U/ m" r1 L' Q
. ^5 t/ C8 J) k/ i5 Q' W% ~3 `9 E/ p7 o+ S- A7 ^! z
4 t' W9 V/ J: l) w! G) F; O+ F+ }7 d
测试程序和Makefile没有修改,故再不贴。
) e5 y) U7 t: w# u! w2 ~
/ K- u4 ^; s% N* p4 c; ]测试步骤:8 y- V4 G* ~& D/ Z

% K5 s8 g; T5 h; x8 F
3 R& \! j: P  q9 B' n  P# F[WJ2440]# ls: S, J6 q2 @8 K7 A. z6 y
Qt            driver_test   lib           root          udisk
* Z% ^$ k3 v6 G) l, z* n, {TQLedtest     etc           linuxrc       sbin          usr
% U6 Y/ y3 n' e2 |app_test      first_drv.ko  mnt           sddisk        var, j2 i' q! c! X3 l# }
bin           first_test    opt           sys           web
! S+ U4 G  Q! |: ~# O& Rdev           home          proc          tmp
, A! |0 O( e- H. I# Q% K[WJ2440]# ls -l /dev/xxx5 |( C1 @6 f8 k% v$ T' v$ I! B
ls: /dev/xxx: No such file or directory/ C& a" s# ]4 f8 d
[WJ2440]# insmod first_drv.ko . Q& b& b) [2 t6 A& {  e
[WJ2440]# lsmod
2 J8 k( D1 }8 L7 n( j$ R: Efirst_drv 1912 0 - Live 0xbf000000& ]0 a+ `9 j$ F0 h/ d. F2 r
[WJ2440]# ls -l /dev/xxx8 Z4 o' M/ M, D2 D: N
crw-rw----    1 root     root      252,   0 Jan  1 23:17 /dev/xxx8 C* L4 M" [1 `2 o
[WJ2440]# cat proc/devices
" y* Y) G( ?9 x5 P2 ~Character devices:2 F% f( A9 n5 r( |5 H, ?5 |& r8 _5 B
  1 mem
$ E* O0 F0 l6 z- o/ K! w. S  4 /dev/vc/0
5 R- e' y# d/ j0 y  4 tty
; @: ]! @! ]* C6 b: J  5 /dev/tty7 S9 X" x$ }  L
  5 /dev/console* ?' L6 {/ g! n, p7 m% ^0 H! E
  5 /dev/ptmx
2 v5 \1 ?6 W- _% V  7 vcs
' a+ q/ M5 H& p& y 10 misc1 K4 R- f6 a: t. P" y
13 input1 o9 N1 r' u. L3 G3 F
14 sound8 t% O& L  s( w) @
29 fb! R/ h7 r! k8 _
81 video4linux
; T1 d1 B" i, `, ?8 R 89 i2c
, N" A1 w0 Q: i+ L 90 mtd( n. x4 ~, Z# C! M) s# {
116 alsa
$ K3 o1 ~2 ?/ b) x; R2 a128 ptm/ @! K" K+ k. W; Q8 ?4 @
136 pts6 w2 V, x& k$ g( S4 B: i3 o( \
180 usb- K" u5 C' H! x  i3 j  T7 q
188 ttyUSB
$ R2 ~- P; Q( x! {189 usb_device2 [$ @. m, R; c% y* }  L3 r
204 tq2440_serial! `8 J# ~2 }1 N' [) U6 X
252 first_drv
3 _$ C7 M5 S+ W0 }253 usb_endpoint
, e7 I9 ^) g7 j/ R254 rtc/ u2 R0 a: h: T# K+ b2 ^5 d

7 G7 G: f& L+ p% Z$ W; f8 L% V; t3 YBlock devices:
7 j, O% G6 T- m3 q) S259 blkext: t5 M9 Y' k' y9 Y2 I
  7 loop* T9 X  w' P# b& f) G
  8 sd
/ u) G3 s2 E  ], P0 e 31 mtdblock
/ T8 n4 S: @; w, u% O1 b3 A 65 sd
+ f$ \. t/ D' U1 o8 s 66 sd( C9 }( N6 {7 r
67 sd# V: r; i) ^) d2 L# I; o
68 sd0 Z) x" T2 {  z! u! @: g
69 sd* U* U. s2 A9 k2 d: G; _) }0 Q
70 sd/ J9 {6 X" h/ t. U, M  j& v
71 sd% N$ W2 Z; M' F! V$ C3 _
128 sd) G% |) n  J0 p+ J: w) N7 K
129 sd* D5 J  l' K' q$ A0 J; }( r
130 sd
* k$ U4 j5 ~* Y4 ~9 h" F131 sd
$ Y7 j) q" Z3 H. F- w132 sd
- G0 N/ J/ K. g2 t1 ?' s133 sd' P! |7 Q! b5 }4 I8 r
134 sd
! ?3 N$ l$ T; }1 G135 sd
# k0 }& y. C- Y4 }$ l5 K: k179 mmc
* A! J! H% t3 y5 ][WJ2440]# cd /sys/class/9 H+ T, t4 G: c, Z3 j
[WJ2440]# ls
# W" n5 P! u2 m5 j. s6 qbdi           i2c-adapter   misc          scsi_device   usb_endpoint
0 U8 F- n1 ?' Pblock         i2c-dev       mmc_host      scsi_disk     usb_host
, H/ |; [3 n8 Z( b( o3 Y7 Lfirmware      ieee80211     mtd           scsi_host     vc- m5 n0 w( \- \
firstdrv      input         net           sound         video4linux
9 M" Y. q8 ?) p9 U8 }0 h1 rgraphics      mem           rtc           tty           vtconsole
# s* F. C4 U8 `' c0 v4 _' R6 ^3 ~[WJ2440]# cd firstdrv/
* B4 M8 K2 h8 x5 p3 b! X& [[WJ2440]# ls& J  ^  ]4 @0 j, L5 [
xxx
1 C0 d2 T' e5 [4 h7 C[WJ2440]# cd xxx/1 k  l7 O! s, T3 L/ N
[WJ2440]# ls ; U! ]) h# q1 ]/ v/ ?
dev        subsystem  uevent% d* s& @3 P4 ]3 j( ^. o
[WJ2440]# cat dev
6 d6 D; V7 ], [& \8 [+ W, C8 X. E9 K252:0
- b; O2 T* o* z" R  Y4 ~[WJ2440]# cat uevent
: J: N& {# A0 n8 N- PMAJOR=252, s6 v0 v$ }: M( U1 G6 e. H3 O9 p- n
MINOR=0
- L$ E" v5 |! `" K[WJ2440]# cd /   5 l# F4 L  J) a2 E
[WJ2440]# ./first_test , \1 Z6 a/ `! d* w) c
first_drv_open
) a% v# h/ c1 s( O' i) Mfirst_drv_write
2 P( D/ ~9 G7 y. o' Z$ _[WJ2440]#
( T4 P, q' N+ N$ B" t
0 z/ D' F) ~+ g# D8 f
/ x3 B+ W! D: y* z4 `
, Y: z$ H. b3 |1 \: _  t$ p

该用户从未签到

2#
发表于 2020-4-27 13:21 | 只看该作者
linux字符驱动之自动创建设备节点
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

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

EDA365公众号

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

GMT+8, 2025-11-26 00:28 , Processed in 0.156250 second(s), 23 queries , Gzip On.

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

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

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