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

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
问:能不能让系统自动创建设备节点?
. D2 d$ K1 q+ y. M% X0 l# S4 U. }5 b7 G6 \- s$ y
答:可以,linux有udev、mdev的机制,而我们的ARM开发板上移植的busybox有mdev机制,那么就使用mdev机制来自动创建设备节点。. A; r3 f7 w- H& O$ N

) l* j, I8 Z# }  z' J; @$ T% {; n% @问:文件系统里,在哪里设置了mdev机制?- r+ O$ V; `: W' n9 r9 S2 L, i* b; g

& l* B8 e" y' K1 c! }& \8 @答:在etc/init.d/rcS文件里有一句:* \1 P; Q& J) g2 x4 h

4 e3 E+ s) u8 [4 m" Jecho /sbin/mdev > /proc/sys/kernel/hotplug
9 X, G$ M/ H( t: ]5 C2 k. I# w# w* D
9 h/ c' P5 R( ^6 V7 L- n+ V问:在驱动程序里面如何编写程序,让系统自动创建设备节点?6 n( h/ ?* `! S3 f
1 _: |7 ^! x; |0 d. T* p: U5 s* W
答:首先创建一个class类,然后在class类下,创建一个class_device,即类下面创建类的设备。
; N! ~9 ^8 t! o% a+ y# t$ b8 u" u1 o! p9 P: M
0 y% R) e$ P/ c2 C  f0 Y. i) R' K
) Q) z7 a8 J5 Y% l3 [% T2 |0 E
详细请参考驱动源码:8 |- n1 d5 t, `- h3 P

! c, U/ X- `$ N
" X3 Q7 N5 q5 m+ H, M#include <linux/kernel.h>
6 i$ N2 ^+ p  u  F% S$ f#include <linux/fs.h>
  e. I' C% g, d# q- O4 |* \#include <linux/init.h>
0 d5 n0 j) v' o* w* l8 l5 ]* K. O#include <linux/delay.h>
4 f1 D- J8 _3 T1 _# `/ g. x#include <asm/uaccess.h>
' }( ~& |. f! e#include <asm/irq.h>' [/ F/ ~$ M- z- C
#include <asm/io.h>
# f8 n# \7 S+ _: z- b* f! X#include <linux/module.h>
/ g1 H: t5 q) k, a2 W/ K#include <linux/device.h>         //class_create
7 R2 ^& f4 K) `1 s, Y; A3 [' L0 |% a2 H" l2 Z, b2 x* s
static struct class *firstdrv_class;
9 o; \( s4 v. cstatic struct device *firstdrv_device;
" K2 S) I: Y5 m/ n3 B7 o
% @% {5 n! {" G; ]2 t; x$ G  n- bint major;
* {9 F. c* J8 O& ~8 Gstatic int first_drv_open(struct inode * inode, struct file * filp)3 o) p& F/ E9 o2 A
{
6 k! N$ \& V$ u; v" B( \3 G7 @        printk("first_drv_open\n");8 c) k) ^/ G' u) q$ ~
        return 0;
8 X7 c& R9 J0 k. U# U7 f$ S  T1 g% a}
7 R  K8 R2 v3 L7 ^, ^  H8 p6 M& S1 O. s* xstatic int first_drv_write(struct file * file, const char __user * buffer, size_t count, loff_t * ppos)
  r" L, C& _5 Y" V2 Q{/ }* J* ]. s/ _5 T% ~" o  r/ a9 D
        printk("first_drv_write\n");# Q  l9 k+ b) z. H' D" M+ }6 z
        return 0;  D3 [8 G6 w9 k: ~/ D! w
}$ U$ V/ ]0 h' Q1 S% A' K* }

( J6 q) M9 ~. ~3 `' j/* File operations struct for character device */
( i3 H2 ^, {  |* Rstatic const struct file_operations first_drv_fops = {- o/ t3 _- {$ V8 T) ]- N. }
        .owner                = THIS_MODULE,
+ O, h* o* @( b  j/ d3 [        .open                = first_drv_open,9 v( h5 _) f5 \
        .write      = first_drv_write,
7 B8 T: u: \, F3 C! u# k};
2 x% {$ M$ g; }
& U% P! e3 l4 {6 X/* 驱动入口函数 */1 V$ O/ L$ N+ h) s! Y9 e2 J( b2 `6 x
static int first_drv_init(void)- O. c; C* ]7 z2 Z7 T
{5 I( j. B9 c" y  A1 C' E- n
        /* 主设备号设置为0表示由系统自动分配主设备号 */7 {% N1 H* F+ z( ]- v5 ]9 f
        major = register_chrdev(0, "first_drv", &first_drv_fops);
: t; B4 a/ t# [+ _+ m- Z) v. |2 |
        /* 创建firstdrv类 */" i7 v" I+ @% u* P
        firstdrv_class = class_create(THIS_MODULE, "firstdrv");
3 c" v+ n" x4 D8 q4 A
/ L9 W1 ~9 x( ~( F" g- A( q, V        /* 在firstdrv类下创建xxx设备,供应用程序打开设备*/
. R4 v  k5 b( z5 W1 Y( B3 d        firstdrv_device = device_create(firstdrv_class, NULL, MKDEV(major, 0), NULL, "xxx");# W6 w: r8 j' `4 g4 `5 C
        return 0;/ u8 X/ T7 M& b' X- J
}; c. `8 C/ [0 y. V

: R0 G$ C/ _& G, m/* 驱动出口函数 */( j+ a. `) k) _% E2 i$ j1 v
static void first_drv_exit(void)' N+ [0 @* V7 y  E3 L& k6 }
{5 D' G, f1 a5 A
        unregister_chrdev(major, "first_drv");
( t  Y4 G6 y8 ?  z, U) ~& ]& q) K        device_unregister(firstdrv_device);  //卸载类下的设备
, J1 a4 C: ?4 ?# {( [1 R; b        class_destroy(firstdrv_class);                //卸载类/ L6 H3 p( @4 ]/ K6 X
}- H$ ^7 W; C3 u" |% K- z
' o* B: g. H+ ?
module_init(first_drv_init);  //用于修饰入口函数
6 f3 Z: ^1 ?! W; w6 p/ X6 Dmodule_exit(first_drv_exit);  //用于修饰出口函数        
+ k+ c7 M' p+ e2 n! [( g9 D' t# [* u/ l/ `( e! s3 x
MODULE_AUTHOR("LWJ");
5 A8 {2 [" {/ ?8 `5 b! oMODULE_DESCRIPTION("Just for Demon");
- p! h! c, s/ SMODULE_LICENSE("GPL");  //遵循GPL协议; r( Y. e' `/ y( }: z; c; d

+ X7 H  k; B0 w3 b$ |6 n! j$ Z3 T" V6 e- e
注意事项:
6 L1 k7 y6 H& Q  q7 \, t1.因韦老师使用的linux版本跟我使用的linux版本不一致,头文件路径可能有所变动。2 \( p* ]! L1 L; x$ ~# _$ R
3 D4 O- \" N( ]3 K6 |  a
2.使用的函数名可能也不一样,例如:$ W1 e$ j/ T9 F
2 r) J$ a9 B7 \: m+ U
韦老师是这样子创建类和创建类的设备:2 c5 P; B7 F# P: L, d
0 s2 L' Y- j+ X: S1 z- e
一、定义
$ `% N) ^: w+ m- E8 K! s4 i0 s- Y, \) m/ H" N2 e8 A$ Q
static struct class *firstdrv_class;/ _% F5 u& {! p) G+ q
static struct class_device *firstdrv_class_dev;7 D: \( ?5 X6 C, s' M

( U/ t3 b& ]' o2 j: q* L/ X) ]二、入口函数里
! C& q0 D: |/ u& C8 b, i' y6 B
: W2 |0 E/ O6 B) z& T8 K* x" i" Pfirstdrv_class = class_create(THIS_MODULE, "firstdrv");+ N. @# a! i- `* D* u
firstdrv_class_dev = class_device_create(firstdrv_class, NULL, MKDEV(major, 0), NULL, "xyz"); /* /dev/xyz */
# o- [0 G2 q/ b) P% L( u- v: r0 B$ m4 h& F+ O1 z
三、出口函数里  Y2 @  B, q/ v" p( j5 \) A
& ?1 ?& F* x8 J9 P* p, A. @* D* K
class_device_unregister(firstdrv_class_dev);
" I8 C, a2 v7 {* ~% J8 jclass_destroy(firstdrv_class);
/ N' Z" T+ B1 g* F! `" r
1 [6 q" t# W5 I* v$ t. C' u5 h0 V. M: j2 B3 m% f9 P
" S' Y$ ?3 b: y& o( x
而在linux2.6.30.4里,并没有class_device_create和class_device_unregister函数( n5 {) y  w6 n- b
6 [# y3 l" Y8 a, |6 P7 T+ n) J# F
我是这样子创建类和创建类的设备:  }3 X8 j5 |+ n" i& a: J" S5 m
; R& t$ G, ?6 n& P! l9 R6 W
一、定义
1 J0 w. x  q# c# @5 I
2 T9 l4 F* p0 t5 M3 pstatic struct class *firstdrv_class;
8 f9 [; Q7 P; Y+ ustatic struct device *firstdrv_device;
$ \7 _3 P& _- g6 B- W: @; c0 n' y& N% y2 S( D
二、入口函数里! a: L& ^% v) w9 |; N
9 I# T9 f5 w0 K. B$ |5 x% n
/* 创建firstdrv类 */! k* y" S! l9 q/ V* |9 h4 A$ N
( V9 r% U2 t- H( e2 X
firstdrv_class = class_create(THIS_MODULE, "firstdrv");
7 r) j: {+ t, C/ f% g1 `8 f9 n. H  v# `
* [: k$ R# P! G
/* 在firstdrv类下创建xxx设备,供应用程序打开设备*/
0 Z8 [2 L# Z/ }' |% y7 vfirstdrv_device = device_create(firstdrv_class, NULL, MKDEV(major, 0), NULL, "xxx");
9 ^4 U1 N  T% @
& W5 X( U5 |6 N+ S9 C# J& C三、出口函数里0 H9 i! L/ i# l  ~! O. E+ t
7 q( |! o0 I: u- r
device_unregister(firstdrv_device);  //卸载类下的设备
2 G* L3 ~6 f; r# Y: xclass_destroy(firstdrv_class); //卸载类3 @) G# I; h! t+ D. g5 _
* J9 K  C& m* K+ s
) r/ ?0 o' `7 N2 ^% w! _/ g: @) `

5 E0 m  E* b: H+ `9 B( G7 Ilinux2.6.30.4使用device_create函数替代class_device_create函数;
+ W( `" y( G$ k
, \5 X5 F( V: G7 F# j使用device_unregister函数替代class_device_unregister函数。
( I  c/ B! e  n; S. _8 l: Y( G9 u$ x8 r

9 m  [  U/ f. W' J
4 W; r6 i% D" M4 S- I/ |3 a  K测试程序和Makefile没有修改。
  |( }2 \* w  f1 w5 R& u& t7 A. ]  d; Q* w( G
; q' \. P) D! ^3 ~1 b. \8 c
测试步骤:" m. u8 C! J4 _
) ]3 {1 j: {0 N2 E- u4 y

- F3 A! X# U) W+ L. ][WJ2440]# ls
$ J2 l4 U. Y. BQt            driver_test   lib           root          udisk: G8 Z3 |. d- p3 c+ a4 r2 h, B
TQLedtest     etc           linuxrc       sbin          usr
( \# R% h$ P# H- yapp_test      first_drv.ko  mnt           sddisk        var  K2 D5 R! b8 X1 A; N
bin           first_test    opt           sys           web
: T$ }: h* C; j, k* Qdev           home          proc          tmp
1 }: S3 h8 l  Z[WJ2440]# ls -l /dev/xxx
0 b4 ~$ x0 o" D6 xls: /dev/xxx: No such file or directory
/ E9 ^4 l- y2 f2 I' e. @[WJ2440]# insmod first_drv.ko
$ z# |6 k0 s  q+ c' i7 M5 v) S% i[WJ2440]# lsmod
% B% B, d/ c$ M  \- s* bfirst_drv 1912 0 - Live 0xbf000000
  A# X' u% W2 P0 \; |0 R[WJ2440]# ls -l /dev/xxx
4 o9 `7 V+ d- @& Acrw-rw----    1 root     root      252,   0 Jan  1 23:17 /dev/xxx
6 o; [) [/ u/ p6 K; t[WJ2440]# cat proc/devices
1 m" g9 q: s; O7 hCharacter devices:
; O4 h. s4 M( T+ l  R" w  1 mem
9 X# M2 g8 M6 z/ z5 K  w  4 /dev/vc/0" y3 s. e4 l: O; w3 d9 h! O7 o
  4 tty
, D6 N7 p- \) m, S5 Y% [# I2 S  5 /dev/tty6 Z- M. Z" _- \- _' S
  5 /dev/console
* R$ J0 l; F6 u  q0 G/ n  5 /dev/ptmx
# V3 H# x( |3 q$ f) K# l' k  7 vcs
& h2 `+ S( g+ C& ?8 s+ q 10 misc* o; K" }2 B+ n6 q2 D, i0 o
13 input& m$ G8 \! ]1 ?6 u, g. \2 Q
14 sound
' G+ f' w8 J1 _3 @ 29 fb
) V2 j1 q7 r: T6 d5 a9 t 81 video4linux; h4 j) ^, |& r. O/ y6 u$ n
89 i2c* h( H6 o/ r# A5 p9 X4 r  C" ^
90 mtd4 a1 J; n; q8 }/ \7 K
116 alsa' q# X5 N9 F/ m2 }/ N+ |+ n
128 ptm% m! n2 n7 y/ G3 Q- L6 r5 V
136 pts# q! [3 U5 ]- S! x  E) P  y
180 usb" }" ?6 u6 L  |1 A
188 ttyUSB( \' ^8 Q. C; k% L
189 usb_device: i. C7 i+ l) Z6 Q9 x2 m& e
204 tq2440_serial6 U' J! s6 R' c+ @% N0 d8 z& ~2 `
252 first_drv
& U3 O! K3 `% a3 K253 usb_endpoint
% {0 t, h) P! z254 rtc
3 W8 U, {7 m* _% \, V1 ]1 J* F) h' d4 y2 ?9 ^# k1 j% D: f( T
Block devices:# K+ b+ C, M/ v0 S' `$ ?/ H* t
259 blkext' {1 [! Z. p* n' T; Z8 e
  7 loop* T3 _, i. p9 D& m
  8 sd! O7 ~; _7 [9 }' {: m' a, }
31 mtdblock3 E7 x9 r) u4 k+ Y" w
65 sd5 V2 _) D( h+ u) H& r$ ~7 G$ }
66 sd8 c) z4 O, p( \% y
67 sd$ A5 B. ]. ]) ~, o" |7 r8 B
68 sd& r0 E% F  _( o6 z& Q! [7 I
69 sd
6 g! c2 M( F" N. V 70 sd7 J8 ~4 v7 O3 U7 ^  g: G1 D, b) S
71 sd
6 {, l7 }8 ^/ z3 }: U/ D128 sd
& u4 E% S! Y8 @2 s129 sd
3 w% i* }# l1 ~130 sd$ b4 j: \% j# B+ n* G6 X3 I- C2 ?
131 sd
' O6 L+ x# n. k- P132 sd$ C, j( A2 p9 Z4 j: w
133 sd5 d$ o4 A& t8 `" }# y) x1 |+ b! V
134 sd( M' Y$ ^  Z3 b, y
135 sd
  T# q8 j7 s6 G4 `' p' k179 mmc5 @6 D: F' i& g, |' ?. l5 a
[WJ2440]# cd /sys/class/
3 r4 S8 r; u, U" b7 }9 ~  ~& M5 v[WJ2440]# ls) l# j' S4 R) I3 H0 Z0 d
bdi           i2c-adapter   misc          scsi_device   usb_endpoint/ r5 z+ Q9 @; t( o3 i
block         i2c-dev       mmc_host      scsi_disk     usb_host% a3 ^) R; I. g8 h7 K' g! D* q
firmware      ieee80211     mtd           scsi_host     vc# ?0 t) m/ e5 p* r5 l9 I* z
firstdrv      input         net           sound         video4linux
+ x; y2 r! X6 b7 Ngraphics      mem           rtc           tty           vtconsole
, F7 W9 k$ h. V# f[WJ2440]# cd firstdrv/
% p; I2 }5 x$ S0 J8 \% ~# ?[WJ2440]# ls9 t( p1 K0 C7 P, X, G3 O: F
xxx! F- a  S% ^8 M
[WJ2440]# cd xxx/$ m! Q0 ~, L9 f% L; C. @5 g
[WJ2440]# ls
7 N. E! `% m" e; f6 s: idev        subsystem  uevent
* A8 O2 a1 e" a[WJ2440]# cat dev 3 ?) o$ b; E; T
252:0
3 b) m" c& A; R4 k4 A+ K[WJ2440]# cat uevent
4 n' q( n3 c# ?+ F( UMAJOR=252
3 |  n5 w* \4 R0 z% f& n# @MINOR=0% |3 V# x, a. ^* e6 u; a
[WJ2440]# cd /   
% ^6 L/ _& [2 l$ t& e- c* E[WJ2440]# ./first_test
) V; ~/ X. c6 tfirst_drv_open
, G0 E7 x2 s0 ^first_drv_write+ w- C* N9 ]3 \9 n
[WJ2440]#
6 C% j' S3 V4 U8 |# s' T! m& N. R1 l* L  G- n

$ S9 H6 v5 Q% A4 [0 x  b% b4 x, |: \9 C, G

, }9 @' s. r& Q6 U7 R. @$ k5 M

该用户从未签到

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

本版积分规则

关闭

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

EDA365公众号

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

GMT+8, 2025-7-12 17:27 , Processed in 0.140625 second(s), 23 queries , Gzip On.

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

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

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