EDA365电子论坛网

标题: Linux设备模型 (3) [打印本页]

作者: pulbieup    时间: 2021-7-22 09:58
标题: Linux设备模型 (3)
! U$ M+ D+ t4 d( f7 b+ t
在上文中,我们介绍到如何使用default attribute。Default attribute使用很方便,但不够灵活。比如上篇文章在Kobject一节中提到的那个例子,name和val这两个attribute使用同一个show/store函数来访问,如果attribute非常多,show/store函数里的分支就会很凌乱。5 ^2 N6 M5 n3 a) J( E
! |- w# U0 ~9 _6 Q- [$ T, u; l
为了解决这个问题,我们可以参考内核提供的kobj_attribute。在内核里,kobj_attibute是这样定义的:
1 u& |$ A' v1 I7 y0 y* y
  a" m/ D3 i3 \2 m3 X3 e! C* D# @: x# S/ L# R4 X0 [9 p, b
  j& B4 N& l0 u) c) J' S
每一个attribute会对应自己的show/store函数,这样就极大的提高了灵活性。可是,在上一篇文章中我们的认知是,sysfs是通过kobject里的kobj_type->sysfs_ops来读写attribute的,那如果要利用kobj_attribute中的show/store来读写attribute的话,就必须在kobj_type->sysfs_ops里指定。Linux内核提供了一个默认的kobj_type类型dynamic_kobj_ktype来实现上述的操作。. k! _$ G- G% g1 ?
1 W  _; G7 |7 `4 v. G

% x" h4 [  _3 ?* v, ]. O2 U
$ d  Q4 Y! ^( \1 J% {1 C      kobj_attribute是内核提供给我们的一种更加灵活的处理attribute的方式,但是它还不够。只有当我们使用kobject_create来创建kobject时,使用kobj_attribute才比较方便,但大部分情况下,我们是把kobject内嵌到自己的结构里,此时就无法直接使用内核提供的dynamic_kobj_ktype,因此,我们需要创建自己的kobj_attribute。7 J/ i7 r* o% V5 `. B8 ?
- ^3 r4 h: w7 G+ q$ i+ r( _
本文接下来将围绕一个实作来看看如何创建自己的kobj_attribute,sample code可以从这里下载。这个sample code是基于上篇文章kobject中的例子修改而来的,看过那个例子的读者应该会比较轻松。1 Z0 q  n& B: u4 n  a0 X2 j0 h

! n, ^. F% `: B5 M  T, l* Y首先,我们需要定义自己的attribute:
4 E& T! w+ q4 [# O
1 H: r6 g+ n8 u: L/ [3 s( K" _8 `: o' q- V
& W; g, [& u1 M
在my_attribute里,我们的show/store直接操作my_kobj,这样更加方便。
* n2 s& L" B* u8 k# U3 g
; i* E- i" w6 L' L6 H7 V2 p- ?1 i: y参考Linux内核,kobj_type里的sysfs_ops这样定义:
; |. e1 z  u$ W$ j% X) X# M* f6 d* U/ m) ?# `; e' ~' `2 Y: F

8 Y' P0 k5 p! C; F8 R" M7 U: H3 C+ i* Z9 w. r; v
   下面就可以分别对name和val两个attribute定义自己的show/store。name这个attribute是只读的,只要为它定义show即可。; S" [* f' T) h4 V
$ P* \7 R/ f" F# B

) H7 ~$ o) Z/ _4 U# w; K4 V5 Q7 D
0 d" z  M: V) l4 o; p8 e   接下来,利用内核提供的宏__ATTR来初始化my_attribute,并建立attribute数组。5 {6 V" q0 G2 _0 s) e- L0 p4 G( k2 r

% H9 r  D3 L1 `+ ^6 B# X2 O/ u( M# n! L+ }$ J" `' A$ ^2 z

; t4 O8 ~$ b8 ^" B 其中,宏__ATTR的定义如下:
/ }; y1 _  ~( M- R7 D0 Z4 w& \
) z# v2 ~/ V- P6 |. Z- _) m& Q0 e; c# `) |1 ~& v

* b1 T8 g! [$ y& I在module_init里,我们调用sysfs_create_files来把attribute增加到sysfs中。/ H& h/ U: |9 ]8 g. O" r, h6 a
: g8 Z# F# S1 d+ d' C8 C

5 @7 L$ ]! |: e- ^9 [* F1 Z) q# f% r# i. B' z- q0 y
在kobject对应的目录里,还可以创建子目录,Linux内核里是用attribute_group来实现。在本例中,我们可以这么做:
' }0 d/ s% S$ x! w% h4 p: \. |6 u( r8 ~  g0 N( Z' R6 y5 k
+ X7 P* {- P4 a( @& F0 M
# M3 [; [/ e$ U2 }
然后在module_init里调用sysfs_create_group来添加。
, \9 v5 [, b8 c7 A! s9 i3 k6 p: h( W3 }- X7 I

6 c' q* w3 w1 i- ]7 E3 i3 c$ s
& x' l8 _! z0 }& x本例创建的attribute_group中包含的attribute也是my_attrs,所以在子目录mygroup下的文件和mykobj目录下的文件完全一致。# {- S' f7 [" F  ?, _2 M& h; X4 y
7 y, t5 g- A, \$ m: |& }
最后我们得到的目录结构是这样的。2 O' U5 D, B8 W1 f0 n
5 s# H# l5 g* V$ U3 m
mykobj/( t# Q& p/ h8 w7 s8 `6 |( `) y
|-- mygroup5 H- ?% M- A1 Z- ~
|   |-- name% g* r1 f5 f" ~/ L2 J
|   `-- val& c: ?6 d! `: o( H. }/ S( ^2 J- L
|-- name
7 l, |/ g* Q1 \6 [* o`-- val
8 Z. e: _  v7 ?1 i% _0 ?' u6 L$ ~5 j6 s  J

, n: v1 N" W) X. e) F' _1 Q完成这个实作之后,你可以用命令echo 2 > /sys/mykobj/val来修改mykobj下的val文件,可以观察到/sys/mykobj/mygroup/val的内容也会变成2,反之亦然。
9 ?$ L4 e* w/ t6 A7 P% d, k: [
作者: NNNei256    时间: 2021-7-22 11:17
Linux设备模型 (3)
作者: CCxiaom    时间: 2021-7-22 11:17
Linux设备模型 (3)
作者: qUzalq    时间: 2021-7-22 11:18
Linux设备模型 (3)




欢迎光临 EDA365电子论坛网 (https://bbs.eda365.com/) Powered by Discuz! X3.2