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

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
上一节中,我们是手工创建设备节点,大家肯定也会觉得这样做太麻烦了。
- q# ]6 A) x, Q) ?
: X/ l* r5 Z6 p9 b# ?3 K上一节文章:) j( c8 m& S5 D' v
问:能不能让系统自动创建设备节点?7 a+ V$ C6 J# {6 p, x
' r, L9 }  x4 H; m) k' o6 h2 G
答:可以,linux有udev、mdev的机制,而我们的ARM开发板上移植的busybox有mdev机制,那么就使用mdev机制来自动创建设备节点。. A4 w* Z4 j6 O4 ~- w

. Q2 |7 W: C& |" D8 l问:文件系统里,在哪里设置了mdev机制?- ~# ]: ^) l3 F+ N! q) q

( y8 G+ S7 D! g7 |答:在etc/init.d/rcS文件里有一句:
; M1 N+ V+ N* }3 S
$ I9 @/ e- ~  a, X7 |echo /sbin/mdev > /proc/sys/kernel/hotplug* r2 n' ?! ]. l3 u/ W5 `  G8 F: ?

; N; X. @- j( u# d1 Z问:在驱动程序里面如何编写程序,让系统自动创建设备节点?1 H$ r3 N7 q$ o0 Y

3 j4 |8 s8 V5 a' ]3 n5 r答:首先创建一个class类,然后在class类下,创建一个class_device,即类下面创建类的设备。
5 m; _  B% f" J; V1 H
* A3 M) w, y3 m1 J7 t+ {) r: f4 Y
. f  l5 }4 o3 z# t
0 z+ V; n( z: u+ H3 v4 ~( V  `9 G, `: C详细请参考驱动源码:! s0 \* M6 o& z/ L  `

! k9 n2 [- u. \3 i2 J
1 |- E7 n! B/ t6 N, K, l#include <linux/kernel.h>
% l# I, |0 D8 F* m  _' P#include <linux/fs.h>6 x" c9 u4 H1 w, C# S8 |" z1 V8 y
#include <linux/init.h>
# p7 I% Z1 F! k#include <linux/delay.h>; Y% W( _# k" n& H( B* Y" z
#include <asm/uaccess.h>+ U- q3 L" j+ ^) s0 L' [/ n) b1 g; }
#include <asm/irq.h>$ c: v( s/ h3 @7 C5 w4 W) k
#include <asm/io.h>
8 V( ~7 O# p0 q2 z( O6 I5 L6 K9 t+ M#include <linux/module.h>6 e, N: V$ o% m( |+ @/ E5 @  G
#include <linux/device.h>         //class_create
- m( l. ^& W# _3 J# r" p+ s5 q0 M; g& J
static struct class *firstdrv_class;0 v8 e/ k3 m' B
static struct device *firstdrv_device;/ o6 r! Y4 m0 i* Y" H, R' @
. X% _2 ?( r8 Y9 I
int major;( x. O5 S% Z7 r! z* W, K* ^* H: f
static int first_drv_open(struct inode * inode, struct file * filp)& r7 ~1 e# J$ ]& ~4 O7 t  A& _
{
$ D1 G% y+ ^; M5 L        printk("first_drv_open\n");7 ]4 p3 i6 ^8 G
        return 0;: C) g* D8 \' d8 J% B$ [
}- z; {* z$ \( u+ D$ K
static int first_drv_write(struct file * file, const char __user * buffer, size_t count, loff_t * ppos)4 N$ K# Y/ B! G/ W; F
{
# Q* t' u: W8 B- ]7 H# @: U" o        printk("first_drv_write\n");" n$ M' g) L: ^: ]0 J, \2 l' z
        return 0;, j, z8 H: L  T$ h- j& z' B
}0 `3 y$ P, ?5 [% C2 V

5 K8 j% T8 E- d/ J/* File operations struct for character device */6 ^2 t& U/ C& w. w
static const struct file_operations first_drv_fops = {, B, h2 v8 w+ p" P0 S4 g) X
        .owner                = THIS_MODULE,
) ^: B$ D9 G3 v* J  |        .open                = first_drv_open,
4 i/ N2 Y( k5 M9 v        .write      = first_drv_write,1 t/ ^5 l/ d$ s$ p
};
) m. [4 R2 I, i( M2 V% \; O: V4 ?5 o4 u1 w+ x  c& V, W
/* 驱动入口函数 */6 m) i. ^9 `( z) G
static int first_drv_init(void)
! {5 u# a0 p. O' S{
$ E1 ~6 c9 x/ h7 z- y        /* 主设备号设置为0表示由系统自动分配主设备号 *// `5 q" {' w; q+ q5 X0 s
        major = register_chrdev(0, "first_drv", &first_drv_fops);
+ k/ P# ?$ p1 O. y. N& g+ G) }  q4 M- P3 t, q
        /* 创建firstdrv类 */
; A3 x+ O3 ~. H6 D9 _7 C. I        firstdrv_class = class_create(THIS_MODULE, "firstdrv");: }8 l2 l. ]+ Z0 b8 Y. L( G

% L: z# n2 L$ J) ]! V: [        /* 在firstdrv类下创建xxx设备,供应用程序打开设备*/. x, J% d$ |5 |5 b& l0 I+ R+ \$ o
        firstdrv_device = device_create(firstdrv_class, NULL, MKDEV(major, 0), NULL, "xxx");
3 S: @) b3 b$ I  H( m* \: Z8 V8 a        return 0;
4 r" r' {2 h( u! d; {: E- i0 \0 @}
- D% Z0 u- z/ _/ e* T9 [7 C/ \( c" c! _! N- D) o
/* 驱动出口函数 */
- F9 C+ B8 W+ T% E! ostatic void first_drv_exit(void)
' z* r3 B+ J# V) m{
* e" Q* j! W6 q8 H* s2 X% p6 h/ l; ?5 I) s        unregister_chrdev(major, "first_drv");
; n$ P" k  a/ J2 @* E6 l( F        device_unregister(firstdrv_device);  //卸载类下的设备
6 V4 w' j3 g4 ?0 w# Z" I% q4 j* A" P$ u        class_destroy(firstdrv_class);                //卸载类
" h9 f1 D2 d6 E' @  H) a* a}$ H7 M' K( R2 P! P5 c3 C$ N* u

( Y# j0 r# \4 n2 C5 I9 d( h& v$ Fmodule_init(first_drv_init);  //用于修饰入口函数
1 H; \$ N9 Y! ]& cmodule_exit(first_drv_exit);  //用于修饰出口函数        
1 T" g0 m2 R% n8 c; d
7 z/ ^( S. ?: l$ l, u  cMODULE_AUTHOR("LWJ");$ u& A( }0 |1 J# }+ n! C; S
MODULE_DESCRIPTION("Just for Demon");9 V  K' @1 A0 E) I* c; K0 p$ h
MODULE_LICENSE("GPL");  //遵循GPL协议
" o) e+ v' C, F. i2 Q& _4 f( p7 G4 z' o5 P! h) Q1 z
4 C8 i6 g3 Z3 [# y9 C7 R# U! m3 a( G
注意事项:) p5 P. L. C1 u" y
1.因韦老师使用的linux版本跟我使用的linux版本不一致,头文件路径可能有所变动。
4 T, J0 w" ]; F. b. Q- n/ _
; ^7 a( f7 S" B& |7 n) i2.使用的函数名可能也不一样,例如:
+ A# `' |* _4 C* D
# \8 N. T; [9 q$ D" j6 M韦老师是这样子创建类和创建类的设备:
; S( ^2 Z8 H/ |0 {! X8 H" _3 ~# K6 ]* g9 I" b" v
一、定义
( H- J9 k# P* Y6 ~8 N; \+ X9 E/ V& Q3 H+ v) [" p+ _" y
static struct class *firstdrv_class;: Y7 K  u, W; m1 K. S! e# a5 N
static struct class_device *firstdrv_class_dev;
$ ]+ A6 @4 ^% s) Z3 R! w% M+ k9 T
二、入口函数里
. E$ i0 h5 F) p3 {; ]
2 a% t6 Z# ]/ x: b5 yfirstdrv_class = class_create(THIS_MODULE, "firstdrv");
" N( q& d2 y) n6 R: O: ofirstdrv_class_dev = class_device_create(firstdrv_class, NULL, MKDEV(major, 0), NULL, "xyz"); /* /dev/xyz */% C. P# g% i" K) Q# g' {8 |% A2 d
/ D/ F) C4 P/ n) n% e% a$ S
三、出口函数里9 c7 i. c  ?3 l; `
. d6 c. S1 s4 t' n* h2 X% ?
class_device_unregister(firstdrv_class_dev);3 K- Z3 s. y' o/ E
class_destroy(firstdrv_class);
6 W* y6 D& {1 I8 B, j2 S# A6 Z: e+ I( D& {, g# M

; g: f6 q1 T/ l: u& Z
" y, d3 b3 p' y, c而在linux2.6.30.4里,并没有class_device_create和class_device_unregister函数
, k* }0 r: f/ S; d$ g
3 w  ?6 s$ N: f5 f0 V3 t2 K我是这样子创建类和创建类的设备:
8 b) M# Z! G% x) Z; R
# E# v5 B; A/ p/ k0 y一、定义
9 o2 `! L9 u6 T1 h( Y0 p- @7 Z" A0 f; y/ W# f# [; e3 V8 j; M
static struct class *firstdrv_class;
+ r) G" i0 @) w- Q1 Istatic struct device *firstdrv_device;" }, Z7 w' D2 V) V! o$ z1 [
! `% |6 B0 J. j; |) V, v
二、入口函数里# M: `# v+ o$ R& h

0 ]( M1 c4 C  f& J! Y( A7 s/* 创建firstdrv类 */7 ~2 C" A# K. w1 I+ C' u: f

; k' j0 j; b: Ifirstdrv_class = class_create(THIS_MODULE, "firstdrv");
9 c# L/ Y2 U" ]5 n* l
* `: M9 y2 _8 T5 g* r% O8 p- Y& s- k$ T6 W- g
/* 在firstdrv类下创建xxx设备,供应用程序打开设备*/
; w' B9 {$ o% F! H: a% s/ tfirstdrv_device = device_create(firstdrv_class, NULL, MKDEV(major, 0), NULL, "xxx");" k$ [, I1 b. v. C. @1 X% j) M1 }

3 \; d: m- f- @  U三、出口函数里) o- h2 w4 h5 |5 k# e

/ v( x- ~- x  r) e" ]" Kdevice_unregister(firstdrv_device);  //卸载类下的设备
* B8 O  T: o: x/ l+ ~class_destroy(firstdrv_class); //卸载类8 d7 b" }/ E5 M) t
0 m9 E' }. [' p+ e  Y6 ^
  d  v5 P  l( G

6 N: A+ W. P2 M$ i/ llinux2.6.30.4使用device_create函数替代class_device_create函数;
" C- w. n/ Y7 |& H, ~
% }8 ]! W" ]" a$ I! @使用device_unregister函数替代class_device_unregister函数。, u1 @5 a5 \6 H* A$ f/ D$ |

% y5 ~8 I& S! _
8 L5 P2 C+ r2 Q' ?  S6 S6 R, W: f1 g3 ^! b- @8 Q+ a2 `
测试程序和Makefile没有修改,故再不贴。
0 B0 f" u2 e$ W* m& ~7 E; Q; D' q- t# U
测试步骤:7 z9 d5 S( B% c6 s( G- v2 k9 x6 F

. w: k3 q9 @8 w/ u) @$ x" A# L: Y7 K* q, b
[WJ2440]# ls# |# u  I- E+ _, \
Qt            driver_test   lib           root          udisk
# V! b6 {7 z1 \; e4 {6 l" ], ITQLedtest     etc           linuxrc       sbin          usr
1 h3 H3 o0 y6 y* l$ gapp_test      first_drv.ko  mnt           sddisk        var$ |# Y8 o9 {6 g1 V" g
bin           first_test    opt           sys           web
- ]- x7 E" e; W8 z* X! Zdev           home          proc          tmp; g& p' [" Q% w; P' ?- |1 g; p
[WJ2440]# ls -l /dev/xxx, O2 T  ?' o0 e
ls: /dev/xxx: No such file or directory
; d* B% D1 [, l2 w2 b/ @[WJ2440]# insmod first_drv.ko
7 d! w5 o" [9 k! U. N0 m) }3 k[WJ2440]# lsmod# }1 n+ j* T5 e4 m
first_drv 1912 0 - Live 0xbf0000000 e: P; M0 I3 K4 Z
[WJ2440]# ls -l /dev/xxx
% w0 f  V- I/ A% H2 y5 }) ^. ^crw-rw----    1 root     root      252,   0 Jan  1 23:17 /dev/xxx3 H! s* Z' a0 P2 K
[WJ2440]# cat proc/devices
, z( s3 D" W3 b( GCharacter devices:
) C8 e. u' ]; p; E7 b1 k1 E  1 mem
' n" ~* X6 x7 D/ b. Z  4 /dev/vc/09 I7 A9 P: S. a  m6 W: v
  4 tty
4 b5 o8 \3 k" N/ I& G  5 /dev/tty
) f" q$ F9 F1 [  5 /dev/console- S/ N0 [/ Q4 y! R
  5 /dev/ptmx
4 J' [: ]3 s: Z. l  7 vcs
" ]+ h  U' |2 p. `3 d2 } 10 misc
* S: h1 A0 `- o: c 13 input
  B; B1 d$ a4 g3 W; g: g+ H' b 14 sound) ]0 Z5 P, C1 O4 W  [& P( w. N
29 fb
) N. \- @# D3 K% t1 x* H& h9 C0 | 81 video4linux
) G9 E9 Q8 T& |) f 89 i2c
0 y' g6 {( v6 R- L, N0 H! F7 T- ~ 90 mtd
% r; ?4 l. \5 n3 X4 B6 b( D' M$ u2 u116 alsa
/ V% \( L( j/ w% |) h( l128 ptm" P$ ~; l) ^% X3 O' K
136 pts: j- O$ Q* a, t! b! y
180 usb
" ]4 U! {% c4 B9 V, V( i: g188 ttyUSB
& u) _7 ~! x# }' P) {: X189 usb_device; R% d; n1 C4 [' D! ]9 e
204 tq2440_serial
* k5 @$ M- i) j$ h$ D7 I' S* ~' N252 first_drv
: z5 I: c* P6 b; k3 Q4 i253 usb_endpoint" {0 d' `5 f8 g
254 rtc) h/ L3 n7 _. f0 I* F6 @! s) i$ G6 @

% i8 f# r3 @: GBlock devices:0 K" z9 Q4 `5 V9 r
259 blkext+ H' [+ V: L; B/ e  u! I" R
  7 loop
0 l9 Y3 d8 `. r, `  8 sd. x* W8 @1 a6 w1 a+ {
31 mtdblock2 Z, ]7 \/ K4 [" \6 e; _4 s" L
65 sd
! S! v7 I; z: x  F  | 66 sd3 f- T5 i# p: c
67 sd: i5 v$ Q2 n0 h$ i! Q) ^: @5 h
68 sd. f/ x- B9 n5 z
69 sd
: ^% h$ Y! A( ?9 ] 70 sd# u0 y8 k( g; K; H+ e0 C& s" m( j( \% u
71 sd
2 |8 Y( N& v# C1 d128 sd. x5 ~4 G' N) _, d' a$ X/ O- J
129 sd- Q3 V# e$ F' J- E) n
130 sd
9 q! W7 @9 K' @. ?131 sd8 v0 I1 ~7 ~% x. [% J0 h' ]2 ?) X
132 sd( K. K: h, ?$ B7 Z$ n) @
133 sd. T- s" Y+ G6 B0 f9 D  ?& |
134 sd
8 w2 @$ W* \6 s& [135 sd
5 Y4 [3 P) w" f# i179 mmc9 \$ g" ~) o. R* f7 H( n" Y2 X7 d
[WJ2440]# cd /sys/class/
6 W3 c" l/ o5 r0 }( N2 q- O# m$ r[WJ2440]# ls
* E7 B8 Z7 [* h/ @7 Hbdi           i2c-adapter   misc          scsi_device   usb_endpoint4 d+ I/ W+ ?0 ~
block         i2c-dev       mmc_host      scsi_disk     usb_host; ]5 W, Q' _  O1 d% U
firmware      ieee80211     mtd           scsi_host     vc- k3 T) ?) D. B2 l0 {) m* l# x
firstdrv      input         net           sound         video4linux: T. {  A& L6 r5 |" M6 V
graphics      mem           rtc           tty           vtconsole: f* X8 v( P7 W1 A
[WJ2440]# cd firstdrv/
5 r, i3 F. Y: C# L+ H' y. x[WJ2440]# ls
/ C. n6 t+ _  ?- P$ axxx
- ?0 o6 G3 z! D[WJ2440]# cd xxx/
; ]" P& |% u! B. @5 C5 O4 l0 r; u3 \[WJ2440]# ls
( e! z% W$ C2 `$ L/ Y* Hdev        subsystem  uevent
  I6 e# h" q+ J7 q+ H[WJ2440]# cat dev $ }( H4 U+ ^- I
252:0
* ^" X5 D' Z# K; [2 w: c9 I7 D) S[WJ2440]# cat uevent
" w& f; I: I- I9 QMAJOR=252
  G1 S3 {" m+ @* o0 KMINOR=0' a# q* A/ k: i
[WJ2440]# cd /   + T. c: T, a& Q( g
[WJ2440]# ./first_test ) m- e3 }, G' o/ R
first_drv_open7 T/ k5 r' }7 `
first_drv_write
4 @% c( @' O7 p" `$ f2 A$ P5 _[WJ2440]# & i! W1 J& W: O' H
' I/ J' I% H1 b6 p: q4 o+ ?1 ]
! ~! w/ N, {" F9 W
5 t1 j  u8 W: D( p+ _  h# H

该用户从未签到

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

本版积分规则

关闭

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

EDA365公众号

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

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

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

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

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