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

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
问:能不能让系统自动创建设备节点?" ~4 {% @5 @) Q0 i9 {% S7 D% D

( O. o3 b' q6 S! R- Y答:可以,linux有udev、mdev的机制,而我们的ARM开发板上移植的busybox有mdev机制,那么就使用mdev机制来自动创建设备节点。& x* j3 n, s" x, q# o
- \& A$ u$ o9 g5 B6 B' x. W* h
问:文件系统里,在哪里设置了mdev机制?% _% Z! J( ^- P

( K: P  q. P9 U8 B- b) F答:在etc/init.d/rcS文件里有一句:7 r# ?2 y2 m% S4 I& J& {

* _; R: l& k# g0 \/ fecho /sbin/mdev > /proc/sys/kernel/hotplug2 M8 }! ]1 f  W
7 u3 I. }- o3 _# E9 k" l9 L
问:在驱动程序里面如何编写程序,让系统自动创建设备节点?
( B; ?2 _, w: F
- V$ U  X& I% Q5 B答:首先创建一个class类,然后在class类下,创建一个class_device,即类下面创建类的设备。
4 o$ G5 ]( l0 [  b8 K- s3 G9 X. l2 I& {
' n/ Z. ?* g  Q- N! K
1 x2 N4 j+ u) ^
详细请参考驱动源码:
9 g1 s9 h. d3 a& H. J; \+ w' }/ f( b" W! a/ X$ o" ]5 F# l

0 F3 R) d: w/ b#include <linux/kernel.h>
* [1 r& W' g, j8 P#include <linux/fs.h>( z+ |/ m+ e: E. Q+ t+ p) D. B
#include <linux/init.h>/ C. Q5 ?( c5 @8 A* S# s. V
#include <linux/delay.h>
0 i* |; c8 ?7 l' f( u#include <asm/uaccess.h>1 y8 t& d8 Q' S" c% S. i
#include <asm/irq.h>5 B% L" `& c- }  q( c
#include <asm/io.h>
: ?' U  f, w. i" P) v4 Z6 F#include <linux/module.h>
% n' g0 n. q! Q4 ^. J7 u3 }#include <linux/device.h>         //class_create8 B+ p5 h$ b2 b$ `

- ~3 {4 V# l7 d* R3 Sstatic struct class *firstdrv_class;
! {2 ~. I. V9 `3 nstatic struct device *firstdrv_device;
/ V. K: b6 \/ |9 h9 l2 u. g5 ~  ~0 o* ]1 `4 \# g/ l2 G
int major;
* k# v9 O: L7 J( q# ostatic int first_drv_open(struct inode * inode, struct file * filp)
( Q0 B7 H2 R3 g+ i{8 K$ P2 b+ q/ ]: i( J6 F3 E
        printk("first_drv_open\n");
* F/ a7 s; g, K9 }) F4 S        return 0;2 t6 G6 M& R- n0 A0 l" c
}
: b. @9 c4 F. ?  \. Pstatic int first_drv_write(struct file * file, const char __user * buffer, size_t count, loff_t * ppos)# X* ]9 Q$ ^  f* }* X8 c
{* j# ?+ N3 F$ Z0 p9 o
        printk("first_drv_write\n");  F3 _  r* ~  ?4 a
        return 0;5 X9 N3 n; J9 b8 w+ [# P3 {
}3 S, C7 S: t* F
4 }/ c. P- g) `- L! g$ o, J+ o
/* File operations struct for character device */! T) k8 O' X  H% O5 `
static const struct file_operations first_drv_fops = {
% |: X8 z" ~6 ]* j8 P        .owner                = THIS_MODULE,; y; b2 x4 a2 \' B+ d' v5 b
        .open                = first_drv_open,  l4 P2 D* k) z" e% Y2 t. K" H
        .write      = first_drv_write,
; `* d1 D% ]9 }6 ?- I9 S, g};
. M0 n- E. N5 B
; Q& ]+ G. y0 n. |) G& O/* 驱动入口函数 */+ }1 r3 i6 V- O" W8 R+ x+ F* Q0 h" M
static int first_drv_init(void)" T$ z+ I. ~; Q. ~: B
{) ]* ~* \6 q* ^& Q
        /* 主设备号设置为0表示由系统自动分配主设备号 */6 v; x5 ?) h! u8 `/ N' c% N" A
        major = register_chrdev(0, "first_drv", &first_drv_fops);& T/ Z0 |( x2 B& r3 u9 ?- I
! q, o4 x& m- d
        /* 创建firstdrv类 */
. K0 }# w$ t, Z/ G1 x        firstdrv_class = class_create(THIS_MODULE, "firstdrv");" E3 h6 k. a1 v2 p, f

* ]" o2 L/ {5 d8 T: }; L        /* 在firstdrv类下创建xxx设备,供应用程序打开设备*/' u3 t$ j5 H: Z( p. d* ]
        firstdrv_device = device_create(firstdrv_class, NULL, MKDEV(major, 0), NULL, "xxx");9 b  h; z7 e3 J2 W6 D
        return 0;
+ N6 V; o' C4 A}
) l& H& ]0 w* d' {4 w, M
3 x0 k. I$ v; i" M9 t7 N# Y! t+ F/* 驱动出口函数 */
# I- ]! S7 j3 X' A6 gstatic void first_drv_exit(void)- e3 k* |& s' c1 z* ^
{: I6 q; {, V5 Y
        unregister_chrdev(major, "first_drv");# m: I0 P' C( Z4 C- L
        device_unregister(firstdrv_device);  //卸载类下的设备% O  M; S6 j7 m2 ~
        class_destroy(firstdrv_class);                //卸载类- `! C( ^& I; W
}
' l* K7 v+ m0 x( W
" q& B( T8 Q, m' N% Omodule_init(first_drv_init);  //用于修饰入口函数
; M1 R' W. f' R# b) z) V9 Dmodule_exit(first_drv_exit);  //用于修饰出口函数        
- [2 @7 M  h; j5 A: `: W1 q& N4 |# W( e& t
MODULE_AUTHOR("LWJ");- @9 y& e; J! v% n" U3 C
MODULE_DESCRIPTION("Just for Demon");. o5 w( `- W  _  k* Q; g" I6 z
MODULE_LICENSE("GPL");  //遵循GPL协议% x9 d- L; |, P+ \& \

4 ?" W- n1 w& L1 O3 v- t
; \# w. V% E0 B+ _注意事项:1 ]& }, y$ h, X( ^" k3 P& m' v
1.因韦老师使用的linux版本跟我使用的linux版本不一致,头文件路径可能有所变动。* M0 U" y& @# q8 r& S1 ?) v5 Y2 n( y
* V5 i# g  Q# D0 L' O" F! T  l+ r& n
2.使用的函数名可能也不一样,例如:
/ T& i6 J9 [: a& P0 e" K* b2 n, b( \. E
韦老师是这样子创建类和创建类的设备:! R' G' L3 M9 ^) Y, p$ s
6 d! v. W  g3 y+ F* r
一、定义7 `+ Y$ L0 `3 u/ {
" M' s3 W' B: r3 i* `/ {
static struct class *firstdrv_class;
# ]; @9 f: {6 G; d1 Gstatic struct class_device *firstdrv_class_dev;
1 @$ B. ?" s3 H6 ~# I0 C
# h! o" g9 }* h, A/ D二、入口函数里0 w$ i1 |6 h2 r% d* ~2 E
0 x# ^3 V* H" C( O9 v; H- m
firstdrv_class = class_create(THIS_MODULE, "firstdrv");
1 Z; ~9 S# l8 I4 W' Ffirstdrv_class_dev = class_device_create(firstdrv_class, NULL, MKDEV(major, 0), NULL, "xyz"); /* /dev/xyz */
* B+ ]) m" Z- N4 }) j/ ~+ _% }3 H/ K6 F5 C$ Y& f- W; X
三、出口函数里4 k# q: j1 l7 B  N8 \
  Z1 d3 I, I* ]& g
class_device_unregister(firstdrv_class_dev);
5 ]9 n- [; D0 P9 i% y8 Fclass_destroy(firstdrv_class);0 O4 c# w  W" J. O" [- M

. P. ]. _- w0 F" L  F+ p( f, b% m0 I9 Y+ z' O

% J% ?4 g2 P$ Z9 B  K8 l而在linux2.6.30.4里,并没有class_device_create和class_device_unregister函数" y, J: t8 h9 Z) k: D# z( K4 m
# K* R. t; T: g
我是这样子创建类和创建类的设备:3 x* u% V3 z5 s, o
9 `: ~$ q. {& R8 E0 }
一、定义
2 d+ n  h" I7 x% R1 G
3 ?" o* _! n( pstatic struct class *firstdrv_class;
+ Y4 r% j. k# }! J: }static struct device *firstdrv_device;! Q+ u; y3 {4 B

: U+ B; K: @9 p: u& `# b二、入口函数里
8 o$ C3 C' q5 ~5 T2 z
6 `# T7 S; @$ k. l3 G/* 创建firstdrv类 */
: v" ^. B0 ]1 i7 @: J
9 l  m/ i! Q; E( {/ u9 G6 e$ D( @firstdrv_class = class_create(THIS_MODULE, "firstdrv");
7 a& `0 s& E" K1 A- o: G$ F7 R. Q9 N. j$ }& r* H/ h

# u# C# {6 f+ p  O% t* j. K/* 在firstdrv类下创建xxx设备,供应用程序打开设备*/6 i& v* X" H6 u" ^/ m+ }7 W
firstdrv_device = device_create(firstdrv_class, NULL, MKDEV(major, 0), NULL, "xxx");
* a5 c2 L8 c, z. \! w" |9 {" Y7 T9 z& {8 V  x) r  f
三、出口函数里
0 {( f1 c& S8 e3 ?6 y, t/ k; r
# H6 I* ?  T& v% N7 L7 Y* Ldevice_unregister(firstdrv_device);  //卸载类下的设备
' @1 O, n8 I- A6 ^# y: F0 m7 Tclass_destroy(firstdrv_class); //卸载类
7 O2 |1 A; g/ r: K/ [: G; t% z' k

$ `( U$ ~) E# I& P% x: X5 f6 Z+ Q8 q$ p( C1 ]+ i
linux2.6.30.4使用device_create函数替代class_device_create函数;5 T; e6 }1 w/ F9 F6 t1 X* {! P1 ~

0 ^) B+ N0 |8 G6 I0 v使用device_unregister函数替代class_device_unregister函数。" T& {# R" ^. C+ p8 Q! @/ H

# _8 K" p; n. j: {; @3 [% b# J) B2 o* t, k; v% z1 d
+ }- {- Y! e5 }" S3 y
测试程序和Makefile没有修改。& K; d* ?( [$ v8 m! }# D! ^* Z
0 F! [& U( |! l
0 _6 @* E( K& e
测试步骤:# z! s9 |2 h1 E2 e3 M
/ Z% F$ F4 d" d) }3 P1 k9 \
/ {5 m( P5 Y8 f. |
[WJ2440]# ls
5 W8 {5 z6 E$ ]Qt            driver_test   lib           root          udisk3 F4 L8 |8 }, P; \  M1 w: @$ q
TQLedtest     etc           linuxrc       sbin          usr  L1 j: z6 m- g, R
app_test      first_drv.ko  mnt           sddisk        var
: ~2 A) `  X' l/ _3 v+ u" fbin           first_test    opt           sys           web
# [/ F% x: x$ m4 `! e2 p1 u" Q- W5 Rdev           home          proc          tmp
. r. R3 k% n" w/ Y9 L# Q/ l% W[WJ2440]# ls -l /dev/xxx
$ J* j1 I- A- Y& x7 Sls: /dev/xxx: No such file or directory
* F. D/ Z3 l7 s2 ?( H. `+ Q- R[WJ2440]# insmod first_drv.ko
- X- J1 W! b0 K, F5 N[WJ2440]# lsmod
6 r& N4 d% ~2 t$ A8 yfirst_drv 1912 0 - Live 0xbf000000* E8 V* [. @8 o2 G: o3 l
[WJ2440]# ls -l /dev/xxx
. o! }* T) `5 s* t, Icrw-rw----    1 root     root      252,   0 Jan  1 23:17 /dev/xxx
1 x* i; u* `" Q/ V8 P[WJ2440]# cat proc/devices / s7 M' Z% h6 S( Q
Character devices:' M0 m& z+ y. K
  1 mem
: o/ D+ I8 C- B% R. A* J' Q2 x- x' m  4 /dev/vc/0/ |4 [  D3 }- W3 M8 x6 l) k
  4 tty* `% v, [0 l. I# u0 \
  5 /dev/tty
) X4 `$ f( n6 N1 Y  5 /dev/console, I' i: @9 e0 s8 E
  5 /dev/ptmx# c3 g1 M8 j9 P! f' r
  7 vcs# \2 @+ T6 W4 H  u' G
10 misc3 S/ Z) f+ S9 ~1 ~7 h( f. j
13 input
: f0 ]3 n7 p+ T$ A* G 14 sound- K* _1 l6 o2 D8 [
29 fb4 Y: g' S  M( X7 Y
81 video4linux
) {. w6 y* L$ f3 X; e9 c( D 89 i2c
9 v5 T7 Z; g) h9 M  K 90 mtd
+ e: l$ g- |$ F5 I116 alsa
& o% i/ J. u" k8 T128 ptm
) ]8 C) I' {/ _136 pts" o/ r% o/ b9 o5 G- H& d
180 usb
( `9 |2 V7 B: l  ]* D0 O! M8 J188 ttyUSB
4 _" ?! X, O4 {( p189 usb_device
% @7 F7 z9 ?1 j1 w2 t7 @& L5 u204 tq2440_serial2 a/ m! S  e* t, [! v
252 first_drv
+ ?, p6 X2 U3 i# C5 s253 usb_endpoint
! z* G7 h5 v. n& |6 p) V3 M254 rtc
* e& Z: p# {8 F: k
9 c( y, D2 p; VBlock devices:8 \0 ], c2 A, U  Z
259 blkext
) f3 M# c/ F# l0 k3 Q) N$ n  7 loop
. @/ x  Q$ B! W  8 sd( x; l8 t6 L  ]. T' U
31 mtdblock" E" x% O2 z" e+ Y% G' ]
65 sd
$ E9 D8 D1 l- U+ W. a/ Z 66 sd9 }  Q2 h# q, p7 E2 Y
67 sd8 P2 \+ D) i! G7 {
68 sd+ k8 Q1 c3 V& b+ N
69 sd
: d( }% R' f0 n6 K 70 sd! _$ ?' e7 S# J- }9 X. D
71 sd2 S) T$ P) m6 i1 A* i
128 sd4 H2 q: `; ~" T% v; W# }) N& }9 M
129 sd
) T: X5 @: o- _+ r/ p' Q8 t2 I1 r130 sd8 Q5 ], C, J8 ]. J7 P9 \
131 sd$ D' Z5 @' {, M7 Z9 M9 b8 ~7 G" {
132 sd2 q2 p# n1 d5 @5 S
133 sd* E+ [* e/ h) J( M  x- @
134 sd' G# L/ |) |7 |1 v1 y$ t  C: R3 y
135 sd
% h$ E$ O5 S9 [- N( m179 mmc
- F6 j1 d$ G( Z  O' V! a, l[WJ2440]# cd /sys/class/  x6 Z: [7 G$ Y, q- g) w' ^
[WJ2440]# ls
# L+ c, |  b# Q& j2 i& c# n  h& h4 Abdi           i2c-adapter   misc          scsi_device   usb_endpoint
8 f& O, K; n: d% Pblock         i2c-dev       mmc_host      scsi_disk     usb_host+ U- U+ [* B5 M6 u3 C/ u1 v' T
firmware      ieee80211     mtd           scsi_host     vc
# A, F  w$ G* c, \: ~firstdrv      input         net           sound         video4linux
% _! n* [5 X) ^' [% ngraphics      mem           rtc           tty           vtconsole
, {) Q- S' |4 H" {6 ?% g[WJ2440]# cd firstdrv/
/ G: R, _  j1 I: Y& r[WJ2440]# ls
# u6 r7 F/ \& }8 Z' D& w3 f4 Axxx1 v& Y* U( _( ?0 x
[WJ2440]# cd xxx/
( s  h1 n) |. O7 W' [( V# q[WJ2440]# ls
6 u+ _2 Q9 j2 ^0 b! a, \dev        subsystem  uevent
& Q# X# a! Z$ j4 }[WJ2440]# cat dev
; e# O7 ?6 C. n' x: ?252:0, H; k4 n) z# F* G3 h
[WJ2440]# cat uevent
$ |5 l* i: z4 a! bMAJOR=252" F6 A7 p' c" O; P" B# J# ~
MINOR=0$ U  n/ N- e( @& Y
[WJ2440]# cd /   6 h$ k9 j$ J2 s, @) `& L
[WJ2440]# ./first_test
& b" U! b/ Z+ n" C. J9 Lfirst_drv_open% B0 }; f  G1 y' L: R8 t4 R/ [
first_drv_write
6 |* \8 o6 J9 i9 c[WJ2440]# : ^8 N, P7 U/ S' X
& t1 O: S3 l7 V; i5 E/ e

' ?' z" C( f$ H0 c- F! [1 L5 |& D4 y% s! c) o; k

  f) O  n+ o$ A# i2 q

该用户从未签到

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

本版积分规则

关闭

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

EDA365公众号

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

GMT+8, 2025-11-26 05:49 , Processed in 0.156250 second(s), 23 queries , Gzip On.

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

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

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