Add description of sysfs attribute

The description of the attribute was added in sysfs section and referenced in vinput section.

In vinput section, just described the class_attribute and some macros about sysfs class.

Add file name at vinput-related examples begin.
This commit is contained in:
asas1asas200 2022-04-17 22:20:18 +08:00
parent 565a599342
commit 04465b1a44
4 changed files with 69 additions and 1 deletions

View File

@ -1,3 +1,7 @@
/*
* vinput.c
*/
#include <linux/cdev.h> #include <linux/cdev.h>
#include <linux/input.h> #include <linux/input.h>
#include <linux/module.h> #include <linux/module.h>

View File

@ -1,3 +1,7 @@
/*
* vinput.h
*/
#ifndef VINPUT_H #ifndef VINPUT_H
#define VINPUT_H #define VINPUT_H

View File

@ -1,3 +1,7 @@
/*
* vkbd.c
*/
#include <linux/init.h> #include <linux/init.h>
#include <linux/input.h> #include <linux/input.h>
#include <linux/module.h> #include <linux/module.h>

View File

@ -1257,6 +1257,40 @@ You can find sysfs directories and files under the \verb|/sys| directory on your
ls -l /sys ls -l /sys
\end{codebash} \end{codebash}
Attributes can be exported for kobjects in the form of regular files in the filesystem.
Sysfs forwards file I/O operations to methods defined for the attributes, providing a means to read and write kernel attributes.
An attribute definition in simply:
\begin{code}
struct attribute {
char *name;
struct module *owner;
umode_t mode;
};
int sysfs_create_file(struct kobject * kobj, const struct attribute * attr);
void sysfs_remove_file(struct kobject * kobj, const struct attribute * attr);
\end{code}
For example, the driver model defines \cpp|struct device_attribute| like:
\begin{code}
struct device_attribute {
struct attribute attr;
ssize_t (*show)(struct device *dev, struct device_attribute *attr,
char *buf);
ssize_t (*store)(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count);
};
int device_create_file(struct device *, const struct device_attribute *);
void device_remove_file(struct device *, const struct device_attribute *);
\end{code}
To read or write attributes, \cpp|show()| or \cpp|store()| method must be specified when declaring the attribute.
For the common cases \src{include/linux/sysfs.h} provides convenience macros (\cpp|__ATTR|, \cpp|__ATTR_RO|, \cpp|__ATTR_WO|, etc.) to make defining attributes easier as well as making code more concise and readable.
An example of a hello world module which includes the creation of a variable accessible via sysfs is given below. An example of a hello world module which includes the creation of a variable accessible via sysfs is given below.
\samplec{examples/hello-sysfs.c} \samplec{examples/hello-sysfs.c}
@ -1293,6 +1327,12 @@ Finally, remove the test module:
sudo rmmod hello_sysfs sudo rmmod hello_sysfs
\end{codebash} \end{codebash}
In the above case, we use a simple kobject to create a directory under sysfs, and communicate with its attributes.
Since Linux v2.6.0, the \cpp|kobject| structure made its appearance.
It was initially meant as a simple way of unifying kernel code which manages reference counted objects.
After a bit of mission creep, it is now the glue that holds much of the device model and its sysfs interface together.
For more information about kobject and sysfs, see \src{Documentation/driver-api/driver-model/driver.rst} and \url{https://lwn.net/Articles/51437/}.
\section{Talking To Device Files} \section{Talking To Device Files}
\label{sec:device_files} \label{sec:device_files}
Device files are supposed to represent physical devices. Device files are supposed to represent physical devices.
@ -1897,6 +1937,23 @@ The buffer will then be copied to user.
vinput devices are created and destroyed using sysfs. vinput devices are created and destroyed using sysfs.
And, event injection is done through a \verb|/dev| node. And, event injection is done through a \verb|/dev| node.
The device name will be used by the userland to export a new virtual input device. The device name will be used by the userland to export a new virtual input device.
The \cpp|class_attribute| structure is similar to other attribute types we talked about in section \ref{sec:sysfs}:
\begin{code}
struct class_attribute {
struct attribute attr;
ssize_t (*show)(struct class *class, struct class_attribute *attr,
char *buf);
ssize_t (*store)(struct class *class, struct class_attribute *attr,
const char *buf, size_t count);
};
\end{code}
In \verb|vinput.c|, the macro \cpp|CLASS_ATTR_WO(export/unexport)| defined in \src{include/linux/device.h} (in this case, \verb|device.h| is included in \src{include/linux/input.h}) will generate the \cpp|class_attribute| structures which are named \verb|class_attr_export/unexport|.
Then, put them into \cpp|vinput_class_attrs| array and the macro \cpp|ATTRIBUTE_GROUPS(vinput_class)| will generate the \cpp|struct attribute_group vinput_class_group| that should be assigned in \cpp|vinput_class|.
Finally, call \cpp|class_register(&vinput_class)| to create attributes in sysfs.
To create a \verb|vinputX| sysfs entry and \verb|/dev| node. To create a \verb|vinputX| sysfs entry and \verb|/dev| node.
\begin{codebash} \begin{codebash}
@ -1933,7 +1990,6 @@ echo "-34" | sudo tee /dev/vinput0
\samplec{examples/vkbd.c} \samplec{examples/vkbd.c}
% TODO: Add description of attribute
% TODO: Add vts.c and vmouse.c example % TODO: Add vts.c and vmouse.c example
\section{Standardizing the interfaces: The Device Model} \section{Standardizing the interfaces: The Device Model}