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

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
问:能不能让系统自动创建设备节点?
5 p! A/ z" z/ T; O# M; ~' N8 z
! f# [: S- k2 G答:可以,linux有udev、mdev的机制,而我们的ARM开发板上移植的busybox有mdev机制,那么就使用mdev机制来自动创建设备节点。) [" W* D3 R; P; P/ ]7 b

4 v9 b1 w, `4 z5 G, e- T6 b问:文件系统里,在哪里设置了mdev机制?
* n  t$ I; m. x6 Y- t" B- r  N
. Z. Y; \# b/ \/ i& W& P- i3 g答:在etc/init.d/rcS文件里有一句:
8 O; {  Z* m. B0 V: s/ P2 p& f8 F; p( }3 C
echo /sbin/mdev > /proc/sys/kernel/hotplug
2 o& [$ i# Q; u4 ~- `- Q+ J' a; T( P) |; w; |2 b3 M" Q
问:在驱动程序里面如何编写程序,让系统自动创建设备节点?' W8 Y6 ?( N# f- _0 C" L5 C

. _  q+ `" w. M4 G1 R3 h+ u, E; W" f答:首先创建一个class类,然后在class类下,创建一个class_device,即类下面创建类的设备。
3 U" f& C: c6 w* E" R' D3 H- G
# u; T! P2 C% G' z0 h
3 `2 g) K/ A9 ~( b; E+ {
3 C4 p# t5 {; f详细请参考驱动源码:
* S* u- M( g) Y( h! D* p- j- h; l# J/ Q1 C
* B% R0 ~. M& y3 Z/ r% ], y4 z( ^
#include <linux/kernel.h>
! a: B- I; ~' L9 t. U. j# A. Q#include <linux/fs.h>! r2 W" C/ ?/ v2 O8 V5 u9 ~5 r
#include <linux/init.h>
+ g/ b& L8 l" d* V& O% z#include <linux/delay.h>
4 {4 A) y. T" ?2 i4 o( Z#include <asm/uaccess.h>& B0 I5 e. [' ]0 K$ H+ O" ?) v
#include <asm/irq.h>: T- F' [( M1 Q2 [( |
#include <asm/io.h>  P9 ?& w3 g6 C. u2 P( n/ X
#include <linux/module.h>
1 m& n, k" x  e' `" J, a" [#include <linux/device.h>         //class_create
5 y# K, ~* a( A# ?' H$ E9 M1 X
' H$ k4 f  g: x3 I# E8 {4 m: T+ Ostatic struct class *firstdrv_class;
! R: F9 R  g# f/ ^static struct device *firstdrv_device;! C* i& F! j) a0 n$ A

& C& j9 D5 |+ C+ Z- l' ?  s3 Fint major;8 ~4 I# o: @5 V  W. R' T( L
static int first_drv_open(struct inode * inode, struct file * filp)
0 p; l8 i: N; ^{
9 w- T# _5 g/ @        printk("first_drv_open\n");: m* G0 M) D1 d; ?6 g
        return 0;2 \2 l# L  R' t; J4 Q1 \7 h
}; ]9 G7 `6 ?2 C" ~
static int first_drv_write(struct file * file, const char __user * buffer, size_t count, loff_t * ppos)
7 @, O  D# V- N) e$ f( @{' s" o3 s  H5 n9 q  j
        printk("first_drv_write\n");! ]" J4 l. q# \8 {% a( ]
        return 0;" T: X# c  \$ `) N+ R
}
# k. J6 [- a# a6 S, I. y: a8 y) L$ j# i4 ~
/* File operations struct for character device */
0 f) X5 V" Q$ V6 N* Ostatic const struct file_operations first_drv_fops = {) W" s* @, c0 L8 f" H6 D9 e% I
        .owner                = THIS_MODULE,
8 d$ e* V+ D2 A8 ~        .open                = first_drv_open,4 m! T- m6 \$ n: M3 L: p
        .write      = first_drv_write,2 B3 l7 \9 s7 [8 t  z" l1 x' @
};( J6 t) _% O- h2 f" n1 b/ Z

& x# J! _% ^, m/* 驱动入口函数 */
$ t3 P* D2 U- M0 A: ^7 E1 Istatic int first_drv_init(void)3 x4 W+ I& X  @' Y" w! V3 x$ r+ k
{5 M/ s4 X. y3 e& u, P8 V; T, S
        /* 主设备号设置为0表示由系统自动分配主设备号 */# a" i1 U# U4 U8 t; D# p9 I
        major = register_chrdev(0, "first_drv", &first_drv_fops);
0 U+ C* m- y7 R! G/ Z% V. g3 l- Z& a+ d+ \* l
        /* 创建firstdrv类 */
4 z6 Q/ e4 g/ O9 R+ F; h$ V6 g: \        firstdrv_class = class_create(THIS_MODULE, "firstdrv");
) h4 ^$ x( B: f- p1 j9 l! H/ T. a2 u+ q- M6 _7 s' |. w; l
        /* 在firstdrv类下创建xxx设备,供应用程序打开设备*/
( e* X$ N" k% s2 h        firstdrv_device = device_create(firstdrv_class, NULL, MKDEV(major, 0), NULL, "xxx");9 q" A5 @4 u/ M
        return 0;
) J* L: n" Z, K0 c: z}8 c1 S: z5 a! ~+ i' k
9 S; N0 Y( d4 @: ^6 r
/* 驱动出口函数 */5 B; r* G/ F6 `
static void first_drv_exit(void)
  T: q! ~1 h% N, Z2 e{
' Q6 a! R/ F) l4 _% x/ \- ^2 ?        unregister_chrdev(major, "first_drv");
/ C. O' h1 ?3 W/ [" M        device_unregister(firstdrv_device);  //卸载类下的设备
" s9 O5 b* {6 k' H6 r& o' F& S9 [        class_destroy(firstdrv_class);                //卸载类
% h6 D& H6 n  d, s}& U% I6 Y7 B, Q
7 L9 `( c5 ~9 l1 {  m, ?* C4 R- L
module_init(first_drv_init);  //用于修饰入口函数3 E! v* b! }, {! L5 l6 C4 Q
module_exit(first_drv_exit);  //用于修饰出口函数        
8 j/ B3 T3 X) e0 |/ O8 \# c* \4 x- J; C
MODULE_AUTHOR("LWJ");  L, o) t  w  m3 m
MODULE_DESCRIPTION("Just for Demon");# ?4 N9 `1 |8 N+ {5 S6 w
MODULE_LICENSE("GPL");  //遵循GPL协议+ f9 }6 A0 V  u% `; X- s$ M
! U4 L# o# Y$ {' v
. ]0 Z8 e. D5 X
注意事项:  j0 P) y6 u3 I. m& _1 Z
1.因韦老师使用的linux版本跟我使用的linux版本不一致,头文件路径可能有所变动。
# d! S& G% S& H  h' _
  M# o- E, L( |' i2.使用的函数名可能也不一样,例如:
7 R( z+ t  N: x
6 Y& s# \- M3 l4 r; N& O) P9 T韦老师是这样子创建类和创建类的设备:
" F+ u  u" u# ?1 ]- m6 Y- P- x' }, e+ L5 w2 v2 y
一、定义( f: |: U$ c% z/ |) c6 K

) a2 a- A# i5 f1 e+ O5 g$ W3 @$ Ystatic struct class *firstdrv_class;; ]! T; J' U3 ?2 \+ M# R
static struct class_device *firstdrv_class_dev;
% i. p& u4 R- D+ W( X- q) n$ V5 S' a+ [  |# ~. `+ H! q
二、入口函数里
! O9 q: {) M9 K+ S- N& b( h: x. u: h% M& L/ S) g
firstdrv_class = class_create(THIS_MODULE, "firstdrv");
8 A6 K0 I% Z- ?, _firstdrv_class_dev = class_device_create(firstdrv_class, NULL, MKDEV(major, 0), NULL, "xyz"); /* /dev/xyz */& Y/ _! x. o# b5 K! Q7 N/ V
$ j+ [" k$ U. T/ A& ~  w3 S
三、出口函数里
- b. u! H/ e0 k$ [! k4 [
8 F6 {& a0 `$ [% `class_device_unregister(firstdrv_class_dev);
  ~8 z# ^& n! f* c, q$ Hclass_destroy(firstdrv_class);
' c! Q: }* R' q, F
& q7 v2 o( f# M0 p, h2 W) e+ X( a
; c; c; C2 e5 p" b: R2 U( k  S; V' P0 R/ M8 Z- i# t6 l' |. e5 |
而在linux2.6.30.4里,并没有class_device_create和class_device_unregister函数
' c4 @8 A) j, h. O5 G  h7 y! Y% I' L0 \" ^9 J4 f& _, t# ]
我是这样子创建类和创建类的设备:
- x- J! |" h& y" }  U6 J
5 G5 J8 P( s& n8 v. x一、定义
0 ?4 N5 }8 c% g- ]3 O
* L3 i+ @' `' g* @, e* z4 T2 Q4 L  gstatic struct class *firstdrv_class;/ ]2 K9 E8 [, _: |* e& H
static struct device *firstdrv_device;3 N# {/ |' W8 D3 a
1 F8 `! [& i+ c; i1 @
二、入口函数里
: B" C9 J9 K' i5 U6 s
9 y2 `7 h0 H& S/* 创建firstdrv类 */
; ~, V7 w5 S) Y# S0 v( B- l' N4 D
firstdrv_class = class_create(THIS_MODULE, "firstdrv");) v0 V4 `9 ]( @, S
) u8 y9 V# [' j% m* X

$ ~7 J- {9 ^" ]/* 在firstdrv类下创建xxx设备,供应用程序打开设备*/
8 k; r/ v3 ?; k; D: S+ e) zfirstdrv_device = device_create(firstdrv_class, NULL, MKDEV(major, 0), NULL, "xxx");
) |" X$ p: x5 m  s9 C( ^9 [" F, u7 K) L
三、出口函数里- e! v9 W) k. l4 G  `

; j8 L5 C7 t: s% xdevice_unregister(firstdrv_device);  //卸载类下的设备
2 ]* k; F+ ]7 K+ J* C/ |class_destroy(firstdrv_class); //卸载类( w$ s/ }+ r: ]) T( y

' b/ A! d5 l# x' z* v+ W. I5 K" b

% S6 v# n4 b* @6 Zlinux2.6.30.4使用device_create函数替代class_device_create函数;; W7 f" g, [) U5 b0 |0 l
3 B" s6 Y" j: k5 E) r# j, ~
使用device_unregister函数替代class_device_unregister函数。
2 ?! F! _; P8 @( A5 A+ f" G+ b' ^$ h' W* J' x9 d

$ C8 O7 a: d5 S( f5 R, T. M+ }& t1 A0 B, j, c. N2 M. U- p  L
测试程序和Makefile没有修改。
2 c6 P9 ^# ?( b& K6 ~$ K
! l2 v% H6 g- v, }' i- K9 \4 H) d0 [0 G5 k7 T( u
测试步骤:
5 ?7 _+ ?- u6 N0 X" C# X7 `# D! M" s9 C! t& H+ L

9 q, w# ?9 M: Q9 ^[WJ2440]# ls
9 h/ x2 B. x' X$ s2 eQt            driver_test   lib           root          udisk2 F2 [! ~4 B9 ?' g0 H  E! m3 ^
TQLedtest     etc           linuxrc       sbin          usr& {" k4 V: i, B9 z4 z- }: g
app_test      first_drv.ko  mnt           sddisk        var0 `+ l# J: k- |- h7 [# O$ p: o
bin           first_test    opt           sys           web7 e) Y, m8 Z" b& O. C
dev           home          proc          tmp
) y; J5 j0 j) T$ ]! g, M[WJ2440]# ls -l /dev/xxx
! K. e" i) k$ Kls: /dev/xxx: No such file or directory
1 }' @* E; q& U  j( E: Z/ g3 q[WJ2440]# insmod first_drv.ko - O% s3 _% Q; k/ P/ p+ H9 a
[WJ2440]# lsmod8 t, ^! I$ g) @. y$ |5 L1 Z
first_drv 1912 0 - Live 0xbf000000+ x6 o* s% G$ t8 p& {" B; z
[WJ2440]# ls -l /dev/xxx
7 y+ D" y6 }* S" K. E  N# Zcrw-rw----    1 root     root      252,   0 Jan  1 23:17 /dev/xxx; E- c' ]7 I- R# p$ o: X! |
[WJ2440]# cat proc/devices   |# U+ K8 [9 z* i  D' G' @4 }6 a( _+ x
Character devices:
7 i6 @) m: h7 p8 Z0 O  1 mem+ _' {# q7 t% M) d) d$ g- i
  4 /dev/vc/0
- Y- _7 C# ?2 C( ^4 {. {# T6 X  4 tty1 z) n7 f/ A( {% t' V+ r
  5 /dev/tty
0 Q2 p8 r! e) }9 B" F5 }, H  5 /dev/console
& I5 {8 v; @* U1 p+ m9 g6 h1 T3 X  5 /dev/ptmx- Y/ V$ k: r+ X" {/ I( E
  7 vcs
2 {+ N3 W1 e+ V- e" O: c6 m8 ~ 10 misc
2 l) d! b8 n$ I, P 13 input! S2 C/ R# ]! ?4 j1 C% [* m
14 sound
- G  I+ W) Z' z! Y3 d 29 fb1 ?9 o/ I5 E+ Z, _6 p- j" ]& w
81 video4linux
( c1 y- \( @0 X1 \+ L 89 i2c
" d. R+ {% Y. ` 90 mtd) B9 t+ d0 f/ U% Z) T; [: `
116 alsa" v2 c- G3 J. y, z# `$ v
128 ptm
1 N: J+ W7 _, w136 pts$ E' b9 k2 a) s1 Z" `! Z5 A  s
180 usb+ v+ i. ^/ ^! v- g, o
188 ttyUSB' R6 W1 |) O3 O  y& G1 n
189 usb_device6 ]8 L* }0 G: P3 _, k" I
204 tq2440_serial
/ L7 s0 m. T, `" R! K252 first_drv& S% }! {5 T2 m' ]# o4 p
253 usb_endpoint. c) r; ?& n7 X  i
254 rtc
' C7 z4 R9 v- `; l) @3 B! S: [3 Y/ G% [0 D3 ^0 D: a: {
Block devices:# ^( S: n' g( Y- X# I+ x* Y
259 blkext
: E. y! U; s1 e& E  7 loop
) \# ?8 l# H% G. ?' H( m  8 sd
2 j9 u- B7 U$ n0 _% C4 A4 ^ 31 mtdblock
7 b$ J3 W1 a) M# q 65 sd
! O4 d# M# `6 p$ W 66 sd
# _. Q- o6 y5 K/ R1 v7 I% h 67 sd
  Z) W) K- U6 F: N  t' ]# |! | 68 sd; x! a; p$ ~  m* N6 n# K' D1 K4 j+ v
69 sd1 B" `( N% Z& [3 g4 g
70 sd: R; b9 h3 z1 R# m0 U2 q
71 sd
; J5 \' Y2 ~* Z3 }9 c2 }& e7 ~" x128 sd
! d- G) @; y7 W129 sd$ e: G$ q( Z' C1 I+ U5 ^) i# ~
130 sd
- y4 Q5 x- W; e( |5 e& O131 sd4 ?2 i9 V% P: J6 S+ K  H" h
132 sd
3 Q0 j0 s% r7 z2 C; U9 Y: @+ w133 sd1 R/ G# v# h4 M7 u6 `( D
134 sd
4 G( |: P; V5 W7 f! h2 [! m- P: {6 U135 sd
# U+ W2 A0 R# u$ ?  Y% @( g) z179 mmc8 J+ B, ?, u! j5 B) Z
[WJ2440]# cd /sys/class/
, H( A. \! Y7 T8 G2 p! Y1 [[WJ2440]# ls
2 [; a1 A  N* {: M0 f2 K) Cbdi           i2c-adapter   misc          scsi_device   usb_endpoint, k  x4 i6 o. g: w  x+ T( x
block         i2c-dev       mmc_host      scsi_disk     usb_host
0 L  ?$ v0 q, R# f/ s* [8 r, C7 D1 sfirmware      ieee80211     mtd           scsi_host     vc
( a9 N  e8 W' w( G. Dfirstdrv      input         net           sound         video4linux& Z  E4 T# r* V6 m( W& c6 i  J
graphics      mem           rtc           tty           vtconsole
9 @( ]$ f7 \. O. g8 r5 Z[WJ2440]# cd firstdrv/, x5 Q& F% T/ X
[WJ2440]# ls
7 e8 i0 a2 J. p  ~xxx9 E* z7 y8 ~2 e  R# d/ C. {4 h: ], g$ {
[WJ2440]# cd xxx/
; G# t" @: m4 u) e! f( C7 Y) u[WJ2440]# ls - A1 Z# s" l6 \/ K+ B
dev        subsystem  uevent: W1 [) }, b/ J
[WJ2440]# cat dev . I. \  s* @( P/ A  P1 J! ~' j
252:0
; x1 g) T) k; \6 `5 G) K6 ?) R[WJ2440]# cat uevent
9 u6 ]2 v+ _) w  ^- d, V' j1 B, vMAJOR=252; B. }8 o5 z7 G/ E7 r! P
MINOR=0
3 M1 H' P  x# r& K) c* N[WJ2440]# cd /   # _4 G6 D" H2 Z3 g3 w
[WJ2440]# ./first_test
8 \7 ]2 f  j, J" xfirst_drv_open
( L* R: l* k" U) wfirst_drv_write7 A+ y5 p, U3 ~& ^, Y! v; v4 D
[WJ2440]#
6 [% T+ u5 Y8 I) ~& [4 A4 j( G+ X! ?+ T9 y- X2 d4 ]% u: f% u: T
$ l" O2 {8 ~( U# ]+ F, m
: L) B4 X* L, B7 l
- y  T1 H2 K. w1 F# ^+ M

该用户从未签到

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

本版积分规则

关闭

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

EDA365公众号

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

GMT+8, 2025-11-26 04:38 , Processed in 0.156250 second(s), 24 queries , Gzip On.

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

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

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