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

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
问:能不能让系统自动创建设备节点?
# U: D8 s: P* q& @
2 K) i0 F7 K% q: }2 O$ {0 P/ c答:可以,linux有udev、mdev的机制,而我们的ARM开发板上移植的busybox有mdev机制,那么就使用mdev机制来自动创建设备节点。( T% ?. g, g" c2 s! s
+ K2 _, s% y8 H5 z
问:文件系统里,在哪里设置了mdev机制?7 e1 E' _1 _% ]- P
' U7 _! T' T1 y  Y
答:在etc/init.d/rcS文件里有一句:. i: i% d. `5 U* |2 u* X
  d9 B: ^$ o) d+ n; o* M
echo /sbin/mdev > /proc/sys/kernel/hotplug
  r; Z8 e8 e4 k' F  j6 v. x1 v  M8 o* n/ }$ A9 n, Q
问:在驱动程序里面如何编写程序,让系统自动创建设备节点?& E* e0 v1 z' C

$ w* M1 H3 y9 I: x/ {6 I+ D" U6 M" R答:首先创建一个class类,然后在class类下,创建一个class_device,即类下面创建类的设备。
: X; F! d  |+ o. N8 g: X
; B+ p# E- t* ^6 \7 |" q! `% Z: j+ `, I

) n" L2 c$ U, G0 \, f0 C详细请参考驱动源码:
5 M6 ]1 K! R. ^& M# J' {: J* K6 T! N$ Y2 ?

/ @- x$ i( Y/ s: n; b6 W#include <linux/kernel.h>
8 l. K( Y8 s0 P) }' b3 S0 j#include <linux/fs.h>7 J0 H, |% b. {9 L+ c
#include <linux/init.h>
1 {  V- J$ d, ]& d- d#include <linux/delay.h>
( w3 s3 ?, O6 P3 E#include <asm/uaccess.h>
1 S- `: [" ^; z( A* T#include <asm/irq.h>
* C8 n0 \7 [" J3 y, A% p$ M6 @#include <asm/io.h>
, ~0 k3 k" o9 t% O: ^#include <linux/module.h>
# _' P( |: @( G9 z#include <linux/device.h>         //class_create! j, b9 r( D, ]6 {0 v  u$ E) B1 n
6 C$ C& b# z- P3 Q" i
static struct class *firstdrv_class;
: k. J& k3 u5 t$ q! l8 Astatic struct device *firstdrv_device;. o) L/ H8 n, y

# u! I# u$ j9 D$ w. _0 E; U. _2 Tint major;
( E( p4 q" \5 V# i, Nstatic int first_drv_open(struct inode * inode, struct file * filp)
1 E& G+ G. O( P" d* ]{
! ?8 h0 m- [; X  K# ~8 L        printk("first_drv_open\n");
3 z/ s! S5 v, l$ X, v        return 0;$ R9 V7 {) X( r
}
' J) S: b, m' d5 O2 Dstatic int first_drv_write(struct file * file, const char __user * buffer, size_t count, loff_t * ppos)
' n6 O* Y4 E; M* Q{. x& o8 V8 i6 \
        printk("first_drv_write\n");) N  \) G$ S0 v+ I
        return 0;
9 z7 k5 s; w" R9 }}
9 O+ q8 I* Y" C! `; n' f
- I& g% M- Z; q# g& r/* File operations struct for character device */
7 z$ U! }# h' ]6 G* mstatic const struct file_operations first_drv_fops = {
7 @) W6 L4 R! d* T. H) B        .owner                = THIS_MODULE,
0 ?& a/ e9 m; j4 J6 U# Z5 l        .open                = first_drv_open,
1 o8 N( l9 N( v: `8 @2 P- ]9 g! {        .write      = first_drv_write,
) t& s' d) `: I$ n3 `4 n# R( H};
1 {# z; ^0 S' d' @  z+ M
5 M9 A/ h% m' t3 B  D3 R/* 驱动入口函数 */
8 Q4 r. T6 w; k" Estatic int first_drv_init(void)2 g) a( Q- O. R/ B6 x" z( @
{
9 n4 s/ E% B8 Q* B" F& L        /* 主设备号设置为0表示由系统自动分配主设备号 */9 V1 v' W& X6 z6 s/ e) E% b
        major = register_chrdev(0, "first_drv", &first_drv_fops);# {% x" g% d5 {$ U! F

% }( I# k% C/ T- G* P        /* 创建firstdrv类 */
2 E& |2 L! C9 B4 B        firstdrv_class = class_create(THIS_MODULE, "firstdrv");
% O+ A6 G' z, x1 r
- ^9 H  n5 f0 b6 }( Q4 t0 k) V4 M* \        /* 在firstdrv类下创建xxx设备,供应用程序打开设备*/1 {5 U; t0 U) O# E% t
        firstdrv_device = device_create(firstdrv_class, NULL, MKDEV(major, 0), NULL, "xxx");7 l6 P4 ?6 M  P
        return 0;
7 c( F& d7 W3 d, K}
. `1 n3 B, c6 E: q. \. X
6 }3 d, f/ f5 {7 I. e$ @: ^1 o/* 驱动出口函数 */
: M0 ]# L3 k# \3 V  lstatic void first_drv_exit(void)
% r* m+ D4 _4 s9 N! }4 `5 T{
3 V6 @" z7 Z& {: y' P        unregister_chrdev(major, "first_drv");! ?; i$ c# d7 t& P6 x
        device_unregister(firstdrv_device);  //卸载类下的设备. v! |, g# M1 a- w# G) z
        class_destroy(firstdrv_class);                //卸载类; k! q1 a1 A6 g* ?$ |% Y
}+ O& {, j; M) v$ m1 k  s% z

8 _) @/ t* \- h* Z3 U) tmodule_init(first_drv_init);  //用于修饰入口函数
' H- v2 [! a: w  }9 a, tmodule_exit(first_drv_exit);  //用于修饰出口函数        % X* h" `9 p& K  f( j" z. N, p
% |# L4 s: T) }; P5 U5 Z
MODULE_AUTHOR("LWJ");
% y& l8 m# e& f2 d/ \4 [. t2 \8 @MODULE_DESCRIPTION("Just for Demon");, Y/ d, z9 p' D  C4 y" I: X; r
MODULE_LICENSE("GPL");  //遵循GPL协议# l. W' ~/ |: \5 M# X( n9 w
( M  Y2 F( _/ E, L- ?4 j4 O

! k3 k/ L& T; f% C( k( e注意事项:
% E4 G9 U, W3 j$ v: X+ W& B1.因韦老师使用的linux版本跟我使用的linux版本不一致,头文件路径可能有所变动。
8 {3 ~0 b# _* I+ J' U( a
: |& g4 B& p2 p( m2.使用的函数名可能也不一样,例如:5 o' ^. [4 G, U. _+ Z
& u7 J: [* p% @; N* H  H3 W; e" W5 n
韦老师是这样子创建类和创建类的设备:+ E+ I' @) X7 j4 s, J2 S/ s
; r6 _! P* Q8 A$ i/ ~% j$ C
一、定义
) H+ T9 s* s( o: \
5 U, p7 f! d& g% J2 z9 E* qstatic struct class *firstdrv_class;+ F$ q, d) k8 \) H
static struct class_device *firstdrv_class_dev;4 Z8 k0 F: _) c
# N; u* k8 D- n9 [+ X7 D3 Z' K5 B5 z4 A
二、入口函数里7 m0 ~6 E' k3 v/ a( F; `( k9 u! Z5 B

- j4 H% C2 @3 e5 k2 mfirstdrv_class = class_create(THIS_MODULE, "firstdrv");
6 z% i( z( O5 p, vfirstdrv_class_dev = class_device_create(firstdrv_class, NULL, MKDEV(major, 0), NULL, "xyz"); /* /dev/xyz */
; Z8 D' A8 Q5 T0 u" Q) j! E2 Y
& \4 ^7 Y! ]: K4 f% U3 A# e- w三、出口函数里
9 [; I% M9 E1 T0 n: B- x7 o& Y5 ~: D/ @0 ~- }/ @6 H
class_device_unregister(firstdrv_class_dev);
" H: R* c  ]. w7 D4 a9 s0 b( X4 v7 Xclass_destroy(firstdrv_class);
) `  Q1 D5 B( d! z" f1 Y
( B' q6 U" k; Y
# t8 ~6 w& s6 j, C. w* q. K
+ m& x0 V* G" B" `. P8 ]而在linux2.6.30.4里,并没有class_device_create和class_device_unregister函数0 s, W7 U* ^, Y# v. u( h0 e

! x* y5 O8 a/ U9 |) z! f2 i2 {我是这样子创建类和创建类的设备:
5 M% S* x) W% ~. L* K# H' ]2 ?4 U) g7 _! j. O+ x5 L7 C* v
一、定义! h% @3 i/ X+ `. W  P+ r
" y* G/ F7 R, y
static struct class *firstdrv_class;
, H" q5 g2 [' c9 x6 w+ V3 v1 O- @static struct device *firstdrv_device;
0 E$ u7 a7 @. h1 d8 j" i" r, k6 k7 ]
& s' t1 w+ x9 x8 W二、入口函数里: n; L5 T, R' ^1 u

1 i7 z0 t; Q: Q4 O/* 创建firstdrv类 */1 J7 M4 r% U. T7 u) k1 d8 b
3 R! x( X$ k0 b# C
firstdrv_class = class_create(THIS_MODULE, "firstdrv");! s. d4 f4 f2 l$ s

8 `5 A5 P- u* b" N
+ [" X7 _4 Q8 K/* 在firstdrv类下创建xxx设备,供应用程序打开设备*/
( j/ M8 ]& @. v4 W6 L# i. }8 V5 Ofirstdrv_device = device_create(firstdrv_class, NULL, MKDEV(major, 0), NULL, "xxx");9 x( L' [3 t, S8 w% }! ~8 ^0 A
3 I: V( N9 i- z( Z- K2 D
三、出口函数里& s' x3 ?# k5 z  f  m1 Y2 `
+ R' z% y+ u0 t
device_unregister(firstdrv_device);  //卸载类下的设备
- D9 Q+ R5 o7 ]! wclass_destroy(firstdrv_class); //卸载类
* e& L4 E+ o% w; s3 i' E2 v0 V0 u/ V) q$ }  S

& F+ }  R  M* t5 d' E% e  G9 ]
. x- q2 _; E3 j& Klinux2.6.30.4使用device_create函数替代class_device_create函数;
+ G3 J- Y7 X( `8 a: O: g* P5 [$ n; [) m+ `' d4 S
使用device_unregister函数替代class_device_unregister函数。9 C# M+ l8 e* p, R& b: ?

5 h* g. d" X+ S3 |
/ }& U: D4 v2 N9 ^4 L0 W7 v# e, M9 x; u
测试程序和Makefile没有修改。) s5 q  R! @( @
; x& j9 i0 g+ _) b. ^- t  i
* \' f, n8 t8 ]- c" X
测试步骤:
# b: R) x2 I- S- j& C& _- k1 z3 l% I* r" G2 v: W2 C! a" c) @
5 E; O0 ?, g8 u: c) g
[WJ2440]# ls$ B2 n) p& N4 z7 e( e! t: [
Qt            driver_test   lib           root          udisk7 |" [  b8 B7 x+ q6 m% c" g
TQLedtest     etc           linuxrc       sbin          usr# w6 a' N! D& Y4 C" ~
app_test      first_drv.ko  mnt           sddisk        var
" ^; F) t6 R" z6 `6 z1 w# }bin           first_test    opt           sys           web
9 R# J( \+ a3 F  U/ U0 ]( u& s/ Hdev           home          proc          tmp* i; L, |4 H- P
[WJ2440]# ls -l /dev/xxx, A! v7 r9 O% c$ `/ @  R
ls: /dev/xxx: No such file or directory
1 e- T) l" _' c  s[WJ2440]# insmod first_drv.ko 0 D1 K* o- ~" ~$ ~4 R+ y; u  m
[WJ2440]# lsmod) z8 t  C$ U) H
first_drv 1912 0 - Live 0xbf000000
8 [8 z6 R; |$ x: X0 Z[WJ2440]# ls -l /dev/xxx  r' `/ X; W( ~7 f
crw-rw----    1 root     root      252,   0 Jan  1 23:17 /dev/xxx
- R5 w& M. r2 c/ o) P2 n" O. {[WJ2440]# cat proc/devices
/ X8 b4 b2 J$ \8 ?% pCharacter devices:
) r0 B: ~0 F$ u8 j  1 mem
5 b- U% @9 \5 b& D6 @2 z  4 /dev/vc/0
6 U) f3 Q" ?) G; J1 [  4 tty
5 U; S7 K; F5 z! E7 Y4 g6 @( a( ~  5 /dev/tty1 B' p9 O% Y9 j" I9 r* P
  5 /dev/console0 t& y3 ^: M- F; K4 e
  5 /dev/ptmx% N1 h/ N& E. p' E/ z% r1 L! o
  7 vcs
3 z4 v" M" C6 n0 m4 S- \6 T 10 misc0 U: n8 U" T% K( X, q8 j. u
13 input
' G9 C( v: ?0 C- u; C 14 sound
5 g" e8 y  u+ @ 29 fb
9 }6 _: `6 }& u 81 video4linux( X' e+ g3 A* L; T4 ^1 o; I- w9 w
89 i2c
- U5 }' S4 e& O( U# b/ _* [ 90 mtd
" x* y% `) r6 Z+ |0 p116 alsa
# ?2 g" a. V8 u6 U8 o5 H8 y128 ptm5 O- f' W9 B$ R  j3 N( S
136 pts
5 l" C: m1 U/ d/ k7 h4 L180 usb7 d: G, {# s# P& [; A, s
188 ttyUSB* M  f8 H# Q' B( N
189 usb_device8 {0 ~' }' c  i
204 tq2440_serial( w' j3 u6 B: {2 n/ a0 @
252 first_drv* ~+ G% W) A5 D% R; r% @
253 usb_endpoint% M4 {/ y" Z5 {' m
254 rtc" j7 t0 m: m  Z. e. S

- n) w2 x  V6 V4 v& T$ Z- o# X$ BBlock devices:
; Y2 w: `+ w& l( X# I1 i- D. c259 blkext* d/ o2 j2 U6 |/ E, e% z7 n
  7 loop+ n/ y# v8 L/ X" V7 R2 y! B
  8 sd. K. i9 o, @' |' H
31 mtdblock  ]/ T- \: N$ |" B6 F# H. ~, H
65 sd, l' w+ i4 F" g/ {6 l) E% M
66 sd6 R6 R1 x5 g1 e- o
67 sd# Q) }1 ]; I4 i/ I& b0 ^
68 sd/ P, `- _, ~6 c: }  I+ N& |* B- |
69 sd
9 x& a# \" Y3 ^. [& w0 K 70 sd! y: S9 s4 F; ]8 C4 G$ l
71 sd5 ?* C) t( ?% g' D* }
128 sd
  F2 r6 o- I% Q129 sd
- Z# x* Z1 j) e; m130 sd
* l) `9 L+ E( x8 H1 v131 sd
/ H0 ]) L4 ]4 p& _6 t6 d1 F3 m+ c7 M132 sd
' p* k( ]6 D( n' c% c+ p133 sd' o4 _  ^% Y1 M' A
134 sd( N+ P" Q. y' x* V8 u
135 sd
8 {/ |* T1 L9 W179 mmc
9 j$ z# Q; T& H% }[WJ2440]# cd /sys/class/
/ N3 p; h) j% B' N, Z[WJ2440]# ls
3 E  q$ a) k9 p1 [$ v2 D. vbdi           i2c-adapter   misc          scsi_device   usb_endpoint
5 x# S& k9 z5 V. ]5 Z1 b: zblock         i2c-dev       mmc_host      scsi_disk     usb_host# i/ x0 V; r1 K0 u
firmware      ieee80211     mtd           scsi_host     vc% ]6 e8 _4 P9 p
firstdrv      input         net           sound         video4linux
' c1 k9 t+ j5 Q5 S2 |9 Y# U: Dgraphics      mem           rtc           tty           vtconsole
9 D0 n' |! K- t; ?3 F$ B) C! O- a[WJ2440]# cd firstdrv/. N) J( s* g/ X+ q0 Y3 J. Y
[WJ2440]# ls; ~* p; L* M4 R' \
xxx
; G5 n3 t% M1 N! ?[WJ2440]# cd xxx/
8 V' G) \$ A" i% ?6 b[WJ2440]# ls
! a7 x# o& y" u6 e# ?5 x' _dev        subsystem  uevent% p4 l- z! C) F: D
[WJ2440]# cat dev , c* h0 y( l2 Y2 {( ^
252:05 l! r$ h7 N. ^( o( @% u0 O5 G4 P
[WJ2440]# cat uevent 2 S- _. y) |& E% f1 p0 J
MAJOR=252
. D# R' V- L3 Y+ eMINOR=06 Z% E1 e! O$ }( t9 m
[WJ2440]# cd /   
+ V0 x9 `2 T/ \/ t$ s[WJ2440]# ./first_test
) z+ ?5 Q% e7 \0 ]first_drv_open
0 v+ ?2 w4 ]; W6 A% @first_drv_write
& S+ P" X6 e9 L7 B( c[WJ2440]#
& J% \* S% b+ R3 P9 @+ H
+ e2 q. Y5 @# i% A
+ M& z' k* v$ n# P7 G" U/ K0 b+ w; F2 l2 r6 n, ?
" a1 L0 m, `& t( \7 F

该用户从未签到

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

本版积分规则

关闭

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

EDA365公众号

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

GMT+8, 2025-11-25 23:05 , Processed in 0.171875 second(s), 24 queries , Gzip On.

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

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

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