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

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
问:能不能让系统自动创建设备节点?* M& W& Q6 \, a) e# ~$ v
2 Q5 t4 |, u6 w  G" D
答:可以,linux有udev、mdev的机制,而我们的ARM开发板上移植的busybox有mdev机制,那么就使用mdev机制来自动创建设备节点。( b8 r+ }: |: ~2 I$ O; F

! `; \5 k8 @3 [5 T( Q. F问:文件系统里,在哪里设置了mdev机制?, c- A( |5 a* ^6 a  o/ E# n

7 [+ T% o5 {% A" ]. \1 y答:在etc/init.d/rcS文件里有一句:1 X6 r( `" c7 o: N

1 w( ~  q* ]9 {5 g/ \1 @7 |* m2 q( hecho /sbin/mdev > /proc/sys/kernel/hotplug9 _$ l5 K' |* L
$ P1 T8 f. z9 x) z
问:在驱动程序里面如何编写程序,让系统自动创建设备节点?7 B& [# i7 d) @% n# y. r

9 d) E8 C' V8 G) y0 y, A答:首先创建一个class类,然后在class类下,创建一个class_device,即类下面创建类的设备。5 k( w! ]4 G8 q; l- @

3 |' i  M+ \; M5 c* o
# L' X) Z0 D2 g: S! X& F2 g
0 [% _# z3 y# I  q% J详细请参考驱动源码:
5 t, ~+ ?9 M' e3 |8 R9 j9 i
: k- i7 C  z  K+ {& O' o( Y
( J5 N& o. X7 z: B7 Q! }#include <linux/kernel.h>
! ]/ y' E' {/ s1 s" F#include <linux/fs.h>
. b3 M, V8 i$ ]+ D& v4 Y5 \* J#include <linux/init.h>
& W/ ]* n( d3 O4 c1 K! }; I7 c#include <linux/delay.h>
3 Z  y9 m, C% Y9 I, h: X2 I6 W#include <asm/uaccess.h>% g( e. ]+ v7 }! T1 W, L
#include <asm/irq.h>* g6 E+ @2 ^5 S) y3 |( J* S" E
#include <asm/io.h>7 q' j: \+ j3 f
#include <linux/module.h>
# U+ u! d9 T. S. G# W#include <linux/device.h>         //class_create
, d3 v# Z' Y, a; |3 q
4 m# _! U, |+ |. T  U$ Cstatic struct class *firstdrv_class;6 ?+ z- c. ?" Y
static struct device *firstdrv_device;
# H0 g4 Q* E% A" p% m  T% u2 a# A& \' M
int major;( l+ H/ [: E9 s7 W  Q8 Q0 k
static int first_drv_open(struct inode * inode, struct file * filp)9 d: P  I" K# v8 J5 V4 V$ r! l% i
{5 ~) \& ]" d; X
        printk("first_drv_open\n");
) D# B- \! L/ F$ O        return 0;
! {( i; q/ C: y2 Q}( b. \  v! Y$ M5 {5 ^
static int first_drv_write(struct file * file, const char __user * buffer, size_t count, loff_t * ppos)
* z6 h6 ]# Q; z{* y- T4 f& f* M/ v% L' r
        printk("first_drv_write\n");: U& g6 E% u+ h! Z
        return 0;
; {: K8 V8 t" H( z* z2 G2 t}
/ Y9 m. x$ r' y" d6 f6 l
' Z; O, n( d2 D/* File operations struct for character device */
% _0 A, N- Q; hstatic const struct file_operations first_drv_fops = {
( Y: `$ J0 j( R8 U$ R! h        .owner                = THIS_MODULE,
& u0 V$ Q: H5 c+ t$ t        .open                = first_drv_open,5 \3 R' {0 R/ a6 I" I7 i/ A+ {3 T
        .write      = first_drv_write,
. I: C( T' N: V. R3 z. i. Q6 v) R' B};
. R0 O1 I. J, P1 ^
5 [: a7 z/ Z8 T  C/* 驱动入口函数 */# m9 E3 r! B1 |
static int first_drv_init(void)
; R, {$ _4 F% z" h" n$ O2 `8 D{2 W  Q1 f1 `: y4 N" X- E
        /* 主设备号设置为0表示由系统自动分配主设备号 */
2 I: \8 K" x5 T" k        major = register_chrdev(0, "first_drv", &first_drv_fops);
( ~6 Q+ X! S: }  \! D! V/ G% t# L4 g' O& e# `
        /* 创建firstdrv类 */; K' _  }5 U# E! L7 h5 j
        firstdrv_class = class_create(THIS_MODULE, "firstdrv");. e& ^( P' y& W- y: f
) ]6 s+ o/ m7 E: R
        /* 在firstdrv类下创建xxx设备,供应用程序打开设备*/, `1 _1 J7 \# c* c
        firstdrv_device = device_create(firstdrv_class, NULL, MKDEV(major, 0), NULL, "xxx");, H+ n  P+ T+ o$ ]
        return 0;" `, X' [) u. O, H
}7 s' F( u7 u% P+ h) I$ p& |* C0 F
8 l7 I- b* Q! \5 g/ [! N3 E8 w4 M+ C
/* 驱动出口函数 */# a! u8 r: S( C$ Q) h# \& x% [
static void first_drv_exit(void)6 ^* n% l  y# ?  I5 Y
{! I  Z7 B: X; H8 j, {
        unregister_chrdev(major, "first_drv");
& M( ^, G, L- c8 X8 W        device_unregister(firstdrv_device);  //卸载类下的设备5 x6 E* D. {9 C3 b% F
        class_destroy(firstdrv_class);                //卸载类  Z, t7 O9 P, @- a  z# w
}3 N' e3 ]" q% A+ H! J) T, h  G

4 C0 o+ ]/ E" e; j! Zmodule_init(first_drv_init);  //用于修饰入口函数
" J; v# Z6 `! v3 j( s2 Bmodule_exit(first_drv_exit);  //用于修饰出口函数        
7 N  f7 Z& Z+ R" {, \8 V
9 W& S4 h- ?' K6 GMODULE_AUTHOR("LWJ");
! e5 g, v3 m8 j. `3 q' r2 |; Y) @+ r: wMODULE_DESCRIPTION("Just for Demon");
7 Z! p/ |+ k5 H. x; Q+ X5 [MODULE_LICENSE("GPL");  //遵循GPL协议* `& c7 `, t% A

3 t1 {7 N: ^! p! l! w  ~6 @& P
" N" G0 E: u2 b% L  D7 K注意事项:; t1 p8 Q2 m6 V- f
1.因韦老师使用的linux版本跟我使用的linux版本不一致,头文件路径可能有所变动。
# K* i3 {. P8 H! C; D4 V8 q3 \
$ j# _: [- Q$ _5 Q2.使用的函数名可能也不一样,例如:
  R4 ~" {! x: J6 J, ?, m
! D$ G8 Z1 H* A8 Y% e* L2 c韦老师是这样子创建类和创建类的设备:
) |) v% u" s( ]( c; ]1 J% O
6 K8 K9 P5 U) j0 j) [% M4 B  v5 m一、定义. W% C2 ]$ s/ m9 p9 {, @

7 y8 J  ]- {( l: b- {static struct class *firstdrv_class;0 ^+ p5 u% J6 _  {  y
static struct class_device *firstdrv_class_dev;
$ L. J* C$ ^1 G% ~) R% z9 M- M: b/ ]( ^
二、入口函数里
1 o7 f5 M1 C0 e6 t! m0 t, F5 Q  w& I
firstdrv_class = class_create(THIS_MODULE, "firstdrv");! b( _! @5 R( j" L; ?
firstdrv_class_dev = class_device_create(firstdrv_class, NULL, MKDEV(major, 0), NULL, "xyz"); /* /dev/xyz */' k7 `' c8 u! o- l8 [1 u# p
! ?+ B% s+ W/ f& K+ J& i
三、出口函数里" ^' a' l+ h4 f4 i7 @( P
4 y$ w, B$ K( D1 s1 N& e. T
class_device_unregister(firstdrv_class_dev);- `' S1 U# O3 ]0 e$ W+ i
class_destroy(firstdrv_class);; d; [* S% G. i- s3 }
$ E; t7 x- l- m, V9 K
4 M. A2 L: C# z( l  j
1 s+ \( r0 M; M& a  J( {' }; V" _" e% z
而在linux2.6.30.4里,并没有class_device_create和class_device_unregister函数: J: k7 T: h, l1 T, |
7 x, B3 }3 u( O. e
我是这样子创建类和创建类的设备:, k2 e3 [6 d  Z

7 d" g; M& {* F4 z0 T4 u9 U+ L一、定义
1 I! Z. v6 H- d: ?
% t- |  ?, H0 C$ _9 Z  z$ R4 wstatic struct class *firstdrv_class;
, `( @$ K- I* g4 O1 ~static struct device *firstdrv_device;
) L! t0 B5 S+ v- [
* O- m2 |: n' d3 }& }二、入口函数里* Z0 v: V; V+ K2 u

; n9 G' A! ?( l2 a# L; j  h/* 创建firstdrv类 */" }' J" \5 o; t- S# @
/ K& q' c0 }3 K& `4 `& z- o. A8 j
firstdrv_class = class_create(THIS_MODULE, "firstdrv");3 G* v. ?' B0 u8 W2 F2 I

5 e; j1 h5 f' D7 J% b; t: q7 _$ F0 a; W
/* 在firstdrv类下创建xxx设备,供应用程序打开设备*/
8 ]) }2 g+ |7 u2 W, W& [4 sfirstdrv_device = device_create(firstdrv_class, NULL, MKDEV(major, 0), NULL, "xxx");, y. b) w0 ?7 @& ^' o/ |1 _+ O
. b: ?1 Y' G2 R( c" O2 ~4 C- K, R
三、出口函数里; O2 n1 X# R. w. A2 i8 Y' ^
6 l, m2 ^& s- u
device_unregister(firstdrv_device);  //卸载类下的设备
, x# B  M8 H7 A/ J. X  M) I4 Aclass_destroy(firstdrv_class); //卸载类
% g7 I8 @' \+ {! e) Q7 b, D
- J; B4 M( v7 V9 j, d) N8 j; s9 B5 n' [+ }
* R9 G- x# K# O% U4 }# X0 e
linux2.6.30.4使用device_create函数替代class_device_create函数;, @: T/ E+ X* l9 X

, j, j1 `" O( A* c% R& L使用device_unregister函数替代class_device_unregister函数。
6 z6 T& c+ b) k# Z. c  t! K6 Q2 g2 I& \! v2 M) J' a5 U
$ `- o6 f5 A' ~

$ G. v4 E; R; J  Y& i测试程序和Makefile没有修改。
  G  A+ J; Q3 [% A# G8 l) U0 E- e3 f" O: o, n$ n$ n4 x
/ u4 ]) _5 R  ]0 [) t
测试步骤:" H) K9 W3 s5 @( `

, ^2 c- U* H% M; c. @( j& U8 n; {4 ^3 t1 B( {) i. Y' C% e
[WJ2440]# ls, w# b' U" @% [* |
Qt            driver_test   lib           root          udisk
# d& ?; Z/ |) F. [# `# {9 K1 XTQLedtest     etc           linuxrc       sbin          usr
  S/ G' h4 o/ f& r: G, a/ o7 kapp_test      first_drv.ko  mnt           sddisk        var& b# y/ |# }( K, K
bin           first_test    opt           sys           web
8 k" k7 s  S  Fdev           home          proc          tmp
; k; s4 x; a" a. o3 c[WJ2440]# ls -l /dev/xxx
% u5 J: c6 r! A: U6 Gls: /dev/xxx: No such file or directory2 p5 r, }+ m4 h" c3 T- R
[WJ2440]# insmod first_drv.ko ' _  n8 s8 X' n2 B, O4 L- c9 _! X
[WJ2440]# lsmod
+ N* C2 l# M3 S) `7 f- l; W: m8 [first_drv 1912 0 - Live 0xbf000000  T1 k) ?0 O( }+ p9 }# _
[WJ2440]# ls -l /dev/xxx6 T; R" q- s: }- j3 g& v
crw-rw----    1 root     root      252,   0 Jan  1 23:17 /dev/xxx
5 `$ i# D: G+ Z6 r[WJ2440]# cat proc/devices
3 i- n* }7 C4 rCharacter devices:% [: ~$ q2 h3 ^6 D) Q0 f# z  Y# f
  1 mem
$ [! R9 N. ]6 W  4 /dev/vc/0
3 ~) S  x, R2 s  U  P$ W! Q  4 tty7 e& K6 C' T( a* R! [; L& ^# g0 l
  5 /dev/tty
' E$ A2 A2 |& s6 I  5 /dev/console
( N1 |5 D  Y( h- C8 E  5 /dev/ptmx
8 u0 @9 k5 g/ r; A( v% ?$ G  7 vcs; ~8 ^$ ^* V. j/ {3 I" a
10 misc$ S' g2 @9 O+ }  g* g" i" \
13 input. G3 m3 X/ l; ]. B: U# j0 A
14 sound
9 u" y5 z. M  S# D 29 fb
' j' r2 U' k' M1 H) o 81 video4linux' I& x/ t; B1 Y4 }  j4 l0 C' M
89 i2c% _# l0 R- W" X3 {: d
90 mtd
' a5 Y5 f; i$ ?8 \1 d116 alsa
- p  G: j* q4 h128 ptm
) y, D$ o) L- w- X0 w136 pts
9 D) N' h' b6 Z  M180 usb
$ _0 l# c1 X, {$ q188 ttyUSB* Y0 }$ m7 I3 g
189 usb_device( v: f/ R, E( G+ Q3 U
204 tq2440_serial
% \; Z( G# z* G1 u4 l* v252 first_drv* J4 V2 A8 ?3 u) L$ O7 L1 o, C
253 usb_endpoint: i7 _+ I; z* H* {- J: X" W" Z
254 rtc4 K0 c& ^# @) Y$ r7 G6 V9 r

6 @" O7 j/ x( o/ `, |; h& OBlock devices:
$ j+ e0 x" p6 L259 blkext0 c; u& l8 [  s+ l8 R4 X
  7 loop- v! L* A# `5 _/ M1 i! f' L0 E
  8 sd
4 M: d1 c, x  [1 j6 U 31 mtdblock8 v& |; G$ Z: R+ Z' t# j
65 sd
8 d/ z" `. P& F0 ?5 p* v 66 sd# }+ f! S3 e1 D, @6 |, q6 S2 p6 T! `
67 sd% A! j2 A4 J0 B1 K
68 sd
2 w+ b" ~' a& |' y5 b; P 69 sd2 c  \5 H2 S0 z; _4 V7 _8 Q3 N5 R
70 sd, W% m6 z. j. p7 Y* v' W
71 sd3 [, W" ^# @; g/ T$ b/ |  w! f; o
128 sd
1 U9 @5 }) Y) A+ l129 sd4 h2 M- y3 U$ ?) J* B- m0 h
130 sd
" z( u" W- I" ~) j131 sd
  K5 e7 p/ L) p# n, @9 u" f132 sd5 J6 }+ p3 |5 ]( v; d
133 sd
0 {  f; }2 T. A* S. P1 I134 sd
8 @, K" d2 U- W135 sd
- P' R9 q6 n+ }! r  L179 mmc
" [, C+ C5 Y2 @- B2 X0 e% Q$ p" f[WJ2440]# cd /sys/class/
0 `; o7 t& F+ Y: h[WJ2440]# ls
4 R8 {; g( [/ w5 j- ]: G. Qbdi           i2c-adapter   misc          scsi_device   usb_endpoint
3 n7 r7 S( Z1 ?- u# T$ hblock         i2c-dev       mmc_host      scsi_disk     usb_host
! x& ^3 l7 ~8 [4 \) p0 Xfirmware      ieee80211     mtd           scsi_host     vc
) l) ]& G2 O3 {& I9 L0 t+ a0 }0 Hfirstdrv      input         net           sound         video4linux$ |/ x& P, r: l0 t. L, O& d& g
graphics      mem           rtc           tty           vtconsole
4 r: {! k0 H  x% b" I[WJ2440]# cd firstdrv/
2 a# X% _, e$ D' A( u" T' U[WJ2440]# ls) Z, e' G( ]: u2 g9 N
xxx
& V8 z7 {9 b" w' Z8 D3 e[WJ2440]# cd xxx/8 Y& P; O) `. K: ?" h6 q
[WJ2440]# ls 8 p* s8 o2 b" f* q2 _, ]( t5 f
dev        subsystem  uevent9 k! `3 P2 e5 S- f, z( t
[WJ2440]# cat dev
+ }) |2 Y- F! h% A$ g252:0" q- E5 C, ^: l& Y
[WJ2440]# cat uevent
% v4 x# E0 o. l0 }2 DMAJOR=2528 T1 ]6 L" h, G( c& O1 }
MINOR=0
6 ?9 m  q2 Z# J* L9 u# D$ P[WJ2440]# cd /   
2 G& w" V5 |9 W% Q1 J[WJ2440]# ./first_test ! L+ k1 `( Z5 i! f% D& I
first_drv_open
- B8 b) N6 J0 D; C5 M7 q5 P/ L" lfirst_drv_write0 c+ L1 \) Y0 h$ J
[WJ2440]# , K8 }: d$ g5 P5 I
, J* }  G6 i; \! Q7 X

8 Y* v- V/ F, b0 [; X' q- @4 V! d  s2 U+ N; m) h# n

. I# q6 D# {7 L

该用户从未签到

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

本版积分规则

关闭

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

EDA365公众号

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

GMT+8, 2025-7-3 23:04 , Processed in 0.078125 second(s), 23 queries , Gzip On.

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

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

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