Basic bus knowledge

Source: Internet
Author: User

Last night, I started to check the LCD and found that the front bus was not very well mastered. Later I summarized the reasons: First, I understood the bus principle very early, and second, there was no big routine during bus learning, third, it was just returned from the Dragon Boat Festival holiday and it was not in the status. Forget it. If you don't have a reason, write down the basic knowledge and consolidate it.

The bus is the channel between the processor and one or more devices. In the device model, all devices are connected through the bus, or even the internal virtual "Platform" bus. You can see all the bus loaded by the system through LS-L/sys/bus.
Drwxr-XR-x Root 1970-01-01 00:02 Platform
Drwxr-XR-x Root 1970-01-01 00:02 SPI
Drwxr-XR-x Root 1970-01-01 00:02 SCSI
Drwxr-XR-x Root 1970-01-01 00:02 USB
Drwxr-XR-x Root 1970-01-01 00:02 Serio
Drwxr-XR-x Root 1970-01-01 00:02 I2C
Drwxr-XR-x Root 1970-01-01 00:02 MMC
Drwxr-XR-x Root 1970-01-01 00:02 sdio
Drwxr-XR-x Root 1970-01-01 00:02 ac97
The bus can be inserted into each other. The device model shows the actual connection between the bus and the devices they control. In the Linux device model, the bus is represented by the bus_type structure and defined in <Linux/device. h>:
Struct bus_type {
Const char * Name;/* Name of the bus type */
Struct bus_attribute * bus_attrs;/* bus attribute */
Struct device_attribute * dev_attrs;/* Device attribute refers to the default Attribute Linked List created for each device that joins the bus */
Struct driver_attribute * drv_attrs;/* driver attributes */

INT (* match) (struct device * Dev, struct device_driver * DRV);/* bus operation function */
INT (* uevent) (struct device * Dev, struct kobj_uevent_env * env );
INT (* probe) (struct device * Dev );
INT (* remove) (struct device * Dev );
Void (* shutdown) (struct device * Dev );

 

INT (* suspend) (struct device * Dev, pm_message_t State);/* power management function */
INT (* suspend_late) (struct device * Dev, pm_message_t State );
INT (* resume_early) (struct device * Dev );
INT (* resume) (struct device * Dev );
Struct pm_ext_ops * PM;
Struct bus_type_private * P;
};
1. Bus registration and deletion:
(1) declare and initialize the bus_type struct. Only a few bus_type members need initialization, most of which are controlled by the device model core. However, you must specify the name of the bus and some necessary methods. For example:
Struct bus_type ldd_bus_type = {
. Name = "LDD ",
. Match = ldd_match,
. Uevent = ldd_uevent,
};
(2) Call the bus_register function to register the bus. Int bus_register (struct bus_type * Bus), This call may fail, so you must always check the return value.
Ret = bus_register (& ldd_bus_type );
If (RET)
Return ret;
If it succeeds, the new bus subsystem will be added to the system, and then you can add devices to the bus. When a bus must be deleted from the system, call:
Void bus_unregister (struct bus_type * Bus );

2. Bus Method
Many methods are defined in the bus_type structure. They allow the bus core to act as an intermediary between the device core and a separate driver to provide services. The following two methods are introduced: int (* match) (struct device * Dev, struct device_driver * DRV );
/* When a new device or driver is added to the bus, this method is called once or multiple times. If the specified driver can process the specified device, returns a non-zero value. */
INT (* uevent) (struct device * Dev, struct kobj_uevent_env * env );
/* Before a hot swapping event is generated for the user space, This method allows the bus to add environment variables */

Iteration of devices and drivers: To write bus-layer code, you may have to perform iterative operations on all the devices or drivers that have registered the bus, this may require careful consideration of other data structures embedded into the bus_type structure, but it is best to use the helper functions provided by the kernel:

Int bus_for_each_dev (struct bus_type * bus, struct device * Start, void * data, INT (* fN) (struct device *, void *));
Int bus_for_each_drv (struct bus_type * bus, struct device_driver * Start, void * data, INT (* fN) (struct device_driver *, void *));
/* Each device or driver (including next_device and next_driver respectively) on the two Function Iteration bus transmits the associated device or device_driver to FN and the data value at the same time. If start is null, it starts from the first device; otherwise, it starts from the first device after start. If FN returns a non-zero value, iteration stops, and that value is returned from bus_for_each_dev or bus_for_each_drv. */
 

3. Bus attributes

Almost every layer of the Linux device model provides functions for adding attributes, and the bus layer is no exception. The bus_attribute type is defined in <Linux/device. h> as follows:

Struct bus_attribute {
Struct attribute ATTR;
Ssize_t (* Show) (struct bus_type *, char * BUF );
Ssize_t (* store) (struct bus_type *, const char * Buf, size_t count );
};
The kernel provides a macro to create and initialize the bus_attribute structure during compilation:

Bus_attr (_ name, _ mode, _ show, _ store)/* This macro declares a structure and uses bus_attr _ as the prefix of the given _ name to create the real name of the bus */
/* The attributes of the bus must be created by explicitly calling bus_create_file :*/
Int bus_create_file (struct bus_type * bus, struct bus_attribute * ATTR );
/* Call to delete a bus property :*/
Void bus_remove_file (struct bus_type * bus, struct bus_attribute * ATTR );
For example, you can create a simple attribute that contains the source code version number as follows:

Static ssize_t show_bus_version (struct bus_type * bus, char * BUF)
{
Return snprintf (BUF, page_size, "% s/n", version );
}

Static bus_attr (version, s_irugo, show_bus_version, null); // get bus_attr_version

/* Create an attribute file when the module is loaded :*/
If (bus_create_file (& ldd_bus_type, & bus_attr_version ))
Printk (kern_notice "unable to create version attribute/N ");

/* This call creates an attribute file (/sys/bus/LDD/version) containing the version number of the ldquo Code )*/

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.