Rumah > Tutorial sistem > LINUX > Penjelasan terperinci tentang model peranti Linux (7)_Class

Penjelasan terperinci tentang model peranti Linux (7)_Class

WBOY
Lepaskan: 2024-02-13 22:39:19
ke hadapan
1246 orang telah melayarinya

1. Gambaran keseluruhan

Dalam model peranti, Bas, Peranti, Pemacu peranti, dsb. agak mudah difahami, kerana semuanya sepadan dengan perkara sebenar, dan semua logik berkisar pada entiti ini. Walau bagaimanapun, Kelas yang akan diterangkan dalam artikel ini agak berbeza, kerana ia adalah maya, hanya untuk mengabstrakkan kesamaan peranti.

Penjelasan terperinci tentang model peranti Linux (7)_Class

Sebagai contoh, jika sesetengah orang yang sama umur dan perlu memperoleh pengetahuan yang sama berkumpul untuk belajar, mereka membentuk kelas. Kelas ini boleh mempunyai namanya sendiri (seperti "295"), tetapi ia tidak bermakna tanpa pelajar (Peranti) yang membentuknya. Di samping itu, apakah kepentingan terbesar kewujudan kelas? Setiap kursus diajar oleh seorang guru! Kerana guru hanya perlu bercakap sekali sahaja, pelajar dalam satu kelas boleh mendengarnya. Jika setiap pelajar belajar di rumah, seorang guru akan diambil untuk setiap pelajar untuk mengajar mereka dengan cara ini. Kebanyakan kandungan adalah sama, yang merupakan pembaziran yang besar.

Kelas dalam model peranti menyediakan fungsi yang serupa. Sebagai contoh, beberapa Peranti serupa (pelajar) perlu menyediakan antara muka (kursus) yang serupa kepada ruang pengguna. Jika setiap pemacu peranti perlu dilaksanakan sekali, ia akan membawa kepada sejumlah besar kod berlebihan dalam kernel, yang merupakan pembaziran yang besar. Jadi, Kelas berkata: "Biar saya bantu anda melaksanakannya, asalkan anda tahu cara menggunakannya."

Ini adalah fungsi Kelas dalam model peranti. Digabungkan dengan komen kernel: Kelas ialah paparan peringkat lebih tinggi bagi peranti yang mengabstrak butiran pelaksanaan peringkat rendah (include/linux/device.h line326), ia mudah difahami.

2. Penerangan struktur data

2.1 kelas struct

kelas struct ialah abstraksi kelas, definisinya adalah seperti berikut:

   1: /* include/linux/device.h, line 332 */
   2: struct class {
   3:         const char              *name;
   4:         struct module           *owner;
   5:  
   6:         struct class_attribute          *class_attrs;
   7:         struct device_attribute         *dev_attrs;
   8:         struct bin_attribute            *dev_bin_attrs;
   9:         struct kobject                  *dev_kobj;
  10:  
  11:         int (*dev_uevent)(struct device *dev, struct kobj_uevent_env *env);
  12:         char *(*devnode)(struct device *dev, umode_t *mode);
  13:  
  14:         void (*class_release)(struct class *class);
  15:         void (*dev_release)(struct device *dev);
  16:  
  17:         int (*suspend)(struct device *dev, pm_message_t state);
  18:         int (*resume)(struct device *dev);
  19:  
  20:         const struct kobj_ns_type_operations *ns_type;
  21:         const void *(*namespace)(struct device *dev);
  22:  
  23:         const struct dev_pm_ops *pm;
  24:  
  25:         struct subsys_private *p;
  26: };
Salin selepas log masuk

Malah, kelas struct dan bas struct adalah sangat serupa, dijelaskan seperti berikut:

nama, nama kelas, akan ditunjukkan dalam direktori "/sys/class/".

class_atrrs, atribut lalai kelas ini, secara automatik akan mencipta fail atribut yang sepadan di bawah "/sys/class/xxx_class" apabila kelas didaftarkan dalam kernel.

dev_attrs, atribut setiap peranti di bawah kelas ini, akan secara automatik mencipta fail atribut yang sepadan dalam direktori sysfs peranti apabila peranti didaftarkan ke kernel.

dev_bin_attrs, serupa dengan dev_attrs, hanyalah atribut jenis binari.

dev_kobj bermakna peranti di bawah kelas ini berada dalam direktori di bawah /sys/dev/ Pada masa ini, secara amnya terdapat dua jenis: char dan block Jika dev_kobj ialah NULL, char dipilih secara lalai.

dev_uevent, apabila peranti di bawah kelas ini berubah, fungsi panggil balik uevent kelas akan dipanggil.

class_release, fungsi panggil balik yang digunakan untuk keluaran itu sendiri.

dev_release, digunakan sebagai fungsi panggil balik untuk peranti dalam kelas keluaran. Dalam antara muka device_release, Peranti, Jenis Peranti dan kelas di mana Peranti berada akan diperiksa untuk melihat sama ada antara muka keluaran didaftarkan, jika ya, antara muka keluaran yang sepadan akan dipanggil untuk melepaskan penuding peranti.

p, ia adalah sama dengan struktur bas struct dalam "Model Peranti Linux (6)_Bus" dan tidak akan dijelaskan lagi.

2.2 struct class_interface

struct class_interface ialah struktur yang membenarkan pemacu kelas memanggil fungsi panggil balik pratetap (add_dev dan remove_dev) apabila peranti ditambah atau dialih keluar di bawah kelas. Jadi apa yang anda lakukan dengan memanggil mereka? Anda boleh melakukan apa sahaja yang anda mahu (seperti menukar nama peranti), dan ia dilaksanakan oleh pemacu kelas tertentu.

Struktur ditakrifkan seperti berikut:

   1: /* include/linux/device.h, line 434 */
   2: struct class_interface {
   3:         struct list_head        node;
   4:         struct class            *class;
   5:  
   6:         int (*add_dev)          (struct device *, struct class_interface *);
   7:         void (*remove_dev)      (struct device *, struct class_interface *);
   8: };
Salin selepas log masuk

3. 功能及内部逻辑解析

3.1 class的功能

看完上面的东西,蜗蜗依旧糊里糊涂的,class到底提供了什么功能?怎么使用呢?让我们先看一下现有Linux系统中有关class的状况(这里以input class为例):

root@android:/ # ls /sys/class/input/ -l
lrwxrwxrwx root root 2014-04-23 03:39 event0 -> ../../devices/platform/i2c-gpio.17/i2c-17/17-0066/max77693-muic/input/input0/event0
lrwxrwxrwx root root 2014-04-23 03:39 event1 -> ../../devices/platform/gpio-keys.0/input/input1/event1
lrwxrwxrwx root root 2014-04-23 03:39 event10 -> ../../devices/virtual/input/input10/event10
lrwxrwxrwx root root 2014-04-23 03:39 event2 -> ../../devices/platform/s3c2440-i2c.3/i2c-3/3-0048/input/input2/event2

lrwxrwxrwx root root 2014-04-23 03:39 event8 -> ../../devices/platform/soc-audio/sound/card0/input8/event8
lrwxrwxrwx root root 2014-04-23 03:39 event9 -> ../../devices/platform/i2c-gpio.8/i2c-8/8-0020/input/input9/event9
lrwxrwxrwx root root 2014-04-23 03:39 input0 -> ../../devices/platform/i2c-gpio.17/i2c-17/17-0066/max77693-muic/input/input0

lrwxrwxrwx root root 2014-04-23 03:39 mice -> ../../devices/virtual/input/mice

root@android:/ # ls /sys/devices/platform/s3c2440-i2c.3/i2c-3/3-0048/input/input2/event2/ -l

-r–r–r– root root 4096 2014-04-23 04:08 dev
lrwxrwxrwx root root 2014-04-23 04:08 device -> ../../input2
drwxr-xr-x root root 2014-04-23 04:08 power
lrwxrwxrwx root root 2014-04-23 04:08 subsystem -> ../../../../../../../../class/input
-rw-r–r– root root 4096 2014-04-23 04:08 uevent

root@android:/ # ls /sys/devices/virtual/input/mice/ -l
-r–r–r– root root 4096 2014-04-23 03:57 dev
drwxr-xr-x root root 2014-04-23 03:57 power
lrwxrwxrwx root root 2014-04-23 03:57 subsystem -> ../../../../class/input
-rw-r–r– root root 4096 2014-04-23 03:57 uevent

看上面的例子,发现input class也没做什么实实在在的事儿,它(input class)的功能,仅仅是:

  • 在/sys/class/目录下,创建一个本class的目录(input)
  • 在本目录下,创建每一个属于该class的设备的符号链接(如,把“sys/devices/platform/s3c2440-i2c.3/i2c-3/3-0048/input/input2/event2”设备链接到”/sys/class/input/event2”),这样就可以在本class目录下,访问该设备的所有特性(即attribute)
  • 另外,device在sysfs的目录下,也会创建一个subsystem的符号链接,链接到本class的目录

算了,我们还是先分析一下Class的核心逻辑都做了哪些事情,至于class到底有什么用处,可以在后续具体的子系统里面(如input子系统),更为细致的探讨。

3.2 class的注册

class的注册,是由__class_register接口(它的实现位于”drivers/base/class.c, line 609″)实现的,它的处理逻辑和bus的注册类似,主要包括:

  • Peruntukkan ruang untuk penunjuk jenis subsys_private struct (cp) dalam struktur kelas dan mulakan medan di dalamnya, termasuk cp->subsys.kobj.kset, cp->subsys.kobj.ktype, dll.
  • Panggil kset_register untuk mendaftarkan kelas (ingat huraian dalam "Model Peranti Linux (6)_Bus", kelas ialah subsistem, jadi mendaftarkan kelas juga merupakan subsistem pendaftaran). Selepas proses selesai, direktori yang sepadan dengan kelas (subsistem) akan dibuat dalam direktori /sys/class/
  • Panggil antara muka add_class_attrs untuk menambah atribut yang ditunjuk oleh penunjuk class_attrs dalam struktur kelas ke kernel. Selepas pelaksanaan, anda akan melihat fail yang sepadan dengan atribut ini dalam direktori /sys/class/xxx_class/

3.3 Tindakan berkaitan kelas semasa pendaftaran peranti

Dalam "Model Peranti Linux (5)_device dan pemacu peranti", kita telah bercakap tentang dua struktur data peranti struct dan struct device_driver Struktur peranti struct akan mengandungi penunjuk kelas struct (ini menunjukkan dari sisi bahawa kelas adalah peranti A koleksi, malah, kelas boleh menjadi pemacu peranti). Apabila pemacu kelas mendaftarkan kelas dengan kernel, ia perlu menggunakan peranti kelas dengan menuding kelasnya sendiri ke kelas Kernel mengendalikan yang lain semasa mendaftarkan peranti.

Dalam bahagian ini, kita akan bercakap tentang tindakan berkaitan kelas semasa mendaftarkan peranti:

Pendaftaran peranti akhirnya dilaksanakan oleh antara muka device_add (pemacu/asas/teras.c Tindakan berkaitan kelas dalam antara muka ini termasuk:

).
  • Panggil antara muka device_add_class_symlinks untuk mencipta pelbagai pautan simbolik yang diterangkan dalam Bahagian 3.1, iaitu: dalam direktori kelas yang sepadan, buat pautan simbolik yang menghala ke peranti dalam direktori peranti, buat pautan simbolik bernama subsistem yang menunjuk ke direktori kelas yang sepadan
  • Panggil device_add_attrs untuk menambah atribut yang ditentukan oleh kelas (class->dev_attrs)
  • Jika terdapat fungsi panggil balik add_dev yang sepadan dengan kelas, panggil fungsi panggil balik

4. Kesimpulan

Malah, selepas tamat artikel ini, Wowo masih belum mengetahui cara kelas digunakan dalam kernel. Tetapi tidak mengapa Dalam analisis subsistem berikutnya (seperti subsistem input, subsistem RTC, dll.), kita akan melihat banyak kes penggunaan kelas. Apabila tiba masanya, ia akan menjadi sangat jelas apabila kita melihat ke belakang dan merumuskan.

Atas ialah kandungan terperinci Penjelasan terperinci tentang model peranti Linux (7)_Class. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:lxlinux.net
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan