对这段时间涉及到的Linux内核中重要结构体和宏的研究总结
1.structdevice
2.klist_node
3.structkref
4.struct class
5.device_driver
6.device_node
7.of_device_id
8.platform_driver
9.platform_device
10.platform_match
11.input_device
12.iio_channel
13.iio_chan_spec
14.list_for_each_entry
1.struct device
/**
*struct device - The basic device structure //基本设备结构体
*@parent: The device's "parent" device, the device to whichit is attached.//从属于
*In most cases, a parent device is some sort of bus orhost //一般是总线或者主控制器
*controller. If parent is NULL, the device, is a top-level device,
*which is not usually what you want.//父空,则它就是顶层设备,通常不是你想要的
*@p: Holds the private data of the driver core portions of thedevice.
*See the comment of the struct device_private for detail.
*@kobj: A top-level, abstract class from which other classes arederived.
*@init_name: Initial name of the device.
*@type: The type of device.
*This identifies the device type and carries type-specific
*information.
*@mutex: Mutex to synchronize calls to its driver.
*@bus: Type of bus device is on.
*@driver: Which driver has allocated this
*@platform_data: Platform data specific to the device.
*Example: For devices on custom boards, as typical of embedded
*and SOC based hardware, Linux often uses platform_data to point
*to board-specific structures describing devices and how they
*are wired. That can include what ports are available, chip
*variants, which GPIO pins act in what additional roles, and so
*on. This shrinks the "Board Support Packages" (BSPs) and
*minimizes board-specific #ifdefs in drivers.
*@power: For device power management.
*See Documentation/power/devices.txt for details.
*@pm_domain: Provide callbacks that are executed during systemsuspend,
*hibernation, system resume and during runtime PM transitions
*along with subsystem-level and driver-level callbacks.
*@pins: For device pin management.
* SeeDocumentation/pinctrl.txt for details.
*@numa_node: NUMA node this device is close to.
*@dma_mask: Dma mask (if dma'ble device).
*@coherent_dma_mask: Like dma_mask, but for alloc_coherent mapping asnot all
*hardware supports 64-bit addresses for consistent allocations
*such descriptors.
*@dma_parms: A low level driver may set these to teach IOMMU codeabout
*segment limitations.
*@dma_pools: Dma pools (if dma'ble device).
*@dma_mem: Internal for coherent mem override.
*@archdata: For arch-specific additions.
*@of_node: Associated device tree node.
*@acpi_node: Associated ACPI device node.
*@devt: For creating the sysfs "dev".
*@id: device instance
*@devres_lock: Spinlock to protect the resource of the device.
*@devres_head: The resources list of the device.
*@knode_class: The node used to add the device to the class list.
*@class: The class of the device.
*@groups: Optional attribute groups.
*@release: Callback to free the device after all references have
*gone away. This should be set by the allocator of the
*device (i.e. the bus driver that discovered the device).
*
*At the lowest level, every device in a Linux system is represented byan
*instance of struct device. The device structure contains theinformation
*that the device model core needs to model the system. Mostsubsystems,
*however, track additional information about the devices they host. Asa
*result, it is rare for devices to be represented by bare devicestructures;
*instead, that structure, like kobject structures, is usually embeddedwithin
*a higher-level representation of the device.
*/
struct device {
@1.structdevice *parent;//设备从属于父,一般父为总线或者主机控制器
@2.structdevice_private *p; //用来保存设备的核心部分私有数据
platform_set_drvdata(structplatform*pdev, void*ddata );
本质就是pdev->dev->p= ddata;
@3.structkobject kobj; A top-level, abstract(抽象)class from which other classes are derived(起源,导出,衍生).
@4.constchar *init_name; /* initial name of the device,设备初始化名,*
init_name,该设备的名称,用于platform_match时和平台总线驱动匹配。
注1:在设备模型中,名称是一个非常重要的变量,任何注册到内核中的设备,都必须有一个合法的名称,可以在初始化时给出,也可以由内核根据“busname + device ID”的方式创造
@5.conststruct device_type *type;
@6.structmutex mutex; /* mutex to synchronize calls to
* its driver.
*/
@7.structbus_type *bus; /* type of bus device is on,platform,iic,spi..*/
@8.structdevice_driver *driver; /* which driver has allocated this
device device_driver?*/
@9.void *platform_data; /*Platform specific data, device
core doesn't touch it平台特殊数据*/
*Example: For devices on custom boards, as typical of embedded
*and SOC based hardware, Linux often uses platform_data to point
*to board-specific structures describing devices and how they
*are wired. That can include what ports are available, chip
*variants, which GPIO pins act in what additional roles, and so
*on. This shrinks the "Board Support Packages" (BSPs) and
*minimizes board-specific #ifdefs in drivers.
@10.structdev_pm_info power;//电源管理SeeDocumentation/power/devices.txt for details
@11.structdev_pm_domain *pm_domain;
#ifdefCONFIG_PINCTRL
@12.structdev_pin_info *pins;For device pin management.
* SeeDocumentation/pinctrl.txt for details.
#endif
#ifdefCONFIG_NUMA
@13.int numa_node; /*NUMA node this device is close to */
#endif
@14.u64 *dma_mask; /*dma mask (if dma'able device) */
@15.u64 coherent_dma_mask;/*Like dma_mask, but for
alloc_coherent mappings as
not all hardware supports
64 bit addresses for consistent
allocations such descriptors. */
@16.structdevice_dma_parameters *dma_parms;
@17.structlist_head dma_pools; /* dma pools (if dma'ble) */
如果需要有某种数据结构的双向队列,就在这种结构内部放一个list_head数据结构成员。
@18.structdma_coherent_mem *dma_mem; /* internal for coherent mem
override */
#ifdefCONFIG_DMA_CMA
@19.structcma *cma_area; /* contiguous memory area for dma
allocations */
#endif
/*arch specific additions */
@20.structdev_archdata archdata;//Forarch-specific additions.
@21.structdevice_node *of_node; /* associated device tree node 设备树节点*/
@22.structacpi_dev_node acpi_node; /* associated ACPI device node */
@23.dev_t devt; /*dev_t, creates the sysfs "dev" */
typedefu_long dev_t;
@24.u32 id; /*device instance(实例)*/
设备资源管理自旋锁
@26.structlist_head devres_head; //设备资源管理链表,参照蜗窝科技http://www.wowotech.net/tag/devres
@27.structklist_node knode_class; //内核
@28.structclass *class; //设备属于的类,都有哪些类?
@29.conststruct attribute_group **groups; /* optional groups Optionalattribute groups */
@30.void (*release)(structdevice *dev);
Callbackto free the device after all references have
*gone away. Thisshould be setby the allocator of the
*device (i.e. the bus driver that discovered the device).
@31.structiommu_group *iommu_group;
};
2.klist_nodde
struct klist_node {
void *n_klist; /*never access directly */
structlist_head n_node;
structkref n_ref;
};
3.kref
structkref {
atomic_trefcount; //引用计数
};
4.struct class
【释疑解惑】
代码中出现的 class指的是 设备类(deviceclasses),是对于设备的高级抽象。但实际上class也是一个结构体,只不过class结构体在声明时是按照类的思想来组织其成员的。
运用class,可以让用户空间的程序根据自己要处理的事情来调用设备,而不是根据设备被接入到系统的方式或设备的工作原理来调用。
class 结构体的原型和相关描述可以在linux-4.3/include/linux/device.h中找到,内容如下:
structclass {
const char *name; // 类名称
struct module *owner; // 类所属的模块,比如usb模块、led模块等
structclass_attribute *class_attrs; //类所添加的属性
const struct attribute_group **dev_groups; // 类所包含的设备所添加的属性
struct kobject *dev_kobj; // 用于标识类所包含的设备属于块设备还是字符设备
int (*dev_uevent)(struct device *dev, structkobj_uevent_env *env); // 用于在设备发出uevent消息时添加环境变量
char *(*devnode)(struct device *dev, umode_t*mode); // 设备节点的相对路径名
void (*class_release)(struct class *class); // 类被释放时调用的函数
void (*dev_release)(struct device *dev); // 设备被释放时调用的函数
int (*suspend)(struct device *dev, pm_message_tstate); // 设备休眠时调用的函数
int (*resume)(struct device *dev); //设备被唤醒时调用的函数
const struct kobj_ns_type_operations *ns_type;
const void *(*namespace)(struct device *dev);
const struct dev_pm_ops *pm; //用于电源管理的函数
struct subsys_private *p; // 指向class_private结构的指针
};
5.device_driver
/**
*struct device_driver - The basic device driver structure
*@name: Name of the device driver.
*@bus: The bus which the device of this driver belongs to.
*@owner: The module owner.
*@mod_name: Used for built-in modules.
*@suppress_bind_attrs: Disables bind/unbind via sysfs.
*@of_match_table: The open firmware table.
*@acpi_match_table: The ACPI match table.
*@probe: Called to query the existence of a specific device,
* whetherthis driver can work with it, and bind the driver
* toa specific device.
*@remove: Called when the device is removed from the system to
* unbinda device from this driver.
*@shutdown: Called at shut-down time to quiesce the device.
*@suspend: Called to put the device to sleep mode. Usually to a
* lowpower state.
*@resume: Called to bring a device from sleep mode.
*@groups: Default attributes that get created by the driver core
* automatically.
*@pm: Power management operations of the device which matched
* thisdriver.
*@p: Driver core's private data, no one other than the driver
* corecan touch this.
*
*The device driver-model tracks all of the drivers known to thesystem.
*The main reason for this tracking is to enable the driver core tomatch
*up drivers with new devices. Once drivers are known objects withinthe
*system, however, a number of other things become possible. Devicedrivers
*can export information and configuration variables that areindependent
*of any specific device.
*/
struct device_driver {
constchar *name; //设备驱动名,用于platform_match时和平台设备匹配
structbus_type *bus; //总线类型
structmodule *owner;
constchar *mod_name; /* used for built-in modules */
boolsuppress_bind_attrs; /* disables bind/unbind via sysfs */
conststruct of_device_id *of_match_table; //Theopen firmware table.
conststruct acpi_device_id *acpi_match_table; //The ACPI match table.
int(*probe) (struct device *dev);//probe函数,平台入口函数,注意形参,写驱动时提取设备信息
int(*remove) (struct device *dev);
void(*shutdown) (struct device *dev);
int(*suspend) (struct device *dev, pm_message_t state);
int(*resume) (struct device *dev);
conststruct attribute_group **groups;//Defaultattributes that get created by the driver core automatically.
conststruct dev_pm_ops *pm;//Powermanagement operations of the device which matched this driver.,电源管理
structdriver_private *p; //这里也可以保存驱动似有数据
};
6.struct device_node
struct device_node {
constchar *name;
constchar *type;
phandlephandle;
constchar *full_name;
struct property*properties;
struct property*deadprops; /* removed properties */
struct device_node*parent;
struct device_node*child;
struct device_node*sibling;
struct device_node*next; /* next device of same type */
struct device_node*allnext; /* next in list of all nodes */
struct proc_dir_entry*pde; /* this node's proc directory */
struct krefkref;
unsignedlong _flags;
void *data;
#ifdefined(CONFIG_SPARC)
constchar *path_component_name;
unsignedint unique_id;
structof_irq_controller *irq_trans;
#endif
};
7.of_device_id
/*
*Struct used for matching a device用于平台驱动中从dts的,compatible属性值去匹配一个平台设备
*/
struct of_device_id
{
char name[32];
char type[32];
char compatible[128];
constvoid *data;
};
9.platform_driver
struct platform_driver {
int(*probe)(struct platform_device *);
int(*remove)(struct platform_device *);
void(*shutdown)(struct platform_device *);
int(*suspend)(struct platform_device *, pm_message_t state);
int(*resume)(struct platform_device *);
structdevice_driver driver;
conststruct platform_device_id *id_table; //用于platform_match
详见http://blog.csdn.net/mcgrady_tracy/article/details/38980991
};
10.platform_device
struct platform_device {
constchar *name;
int id;
bool id_auto;
structdevice dev;
u32 num_resources;
structresource *resource;
conststruct platform_device_id *id_entry;
/*MFD cell pointer */
structmfd_cell *mfd_cell;
/*arch specific additions */
structpdev_archdata archdata;
};
11.platform_match
各种总线的匹配方法及函数
详见:http://blog.csdn.net/fanqipin/article/details/8153053
12.input_device
/**
*struct input_dev - represents an input device
*@name: name of the device
*@phys: physical path to the device in the system hierarchy(分层)
*@uniq: unique identification code for the device (if device has it)
*@id: id of the device (struct input_id)
*@propbit: bitmap of device properties and quirks
*@evbit: bitmap of types of events supported by the device (EV_KEY,
* EV_REL,etc.)
*@keybit: bitmap of keys/buttons this device has
*@relbit: bitmap of relative axes for the device
*@absbit: bitmap of absolute axes for the device
*@mscbit: bitmap of miscellaneous events supported by the device
*@ledbit: bitmap of leds present on the device
*@sndbit: bitmap of sound effects supported by the device
*@ffbit: bitmap of force feedback effects supported by the device
*@swbit: bitmap of switches present on the device
*@hint_events_per_packet: average number of events generated by the
* devicein a packet (between EV_SYN/SYN_REPORT events). Used by
* eventhandlers to estimate size of the buffer needed to hold
* events.
*@keycodemax: size of keycode table
*@keycodesize: size of elements in keycode table
*@keycode: map of scancodes to keycodes for this device
*@getkeycode: optional legacy method to retrieve current keymap.
*@setkeycode: optional method to alter current keymap, used toimplement
* sparsekeymaps. If not supplied default mechanism will be used.
* Themethod is being called while holding event_lock and thus must
* notsleep
*@ff: force feedback structure associated with the device if device
* supportsforce feedback effects
*@repeat_key: stores key code of the last key pressed; used toimplement
* softwareautorepeat
*@timer: timer for software autorepeat
*@rep: current values for autorepeat parameters (delay, rate)
*@mt: pointer to multitouch state
*@absinfo: array of &struct input_absinfo elements holdinginformation
* aboutabsolute axes (current value, min, max, flat, fuzz,
* resolution)
*@key: reflects current state of device's keys/buttons
*@led: reflects current state of device's LEDs
*@snd: reflects current state of sound effects
*@sw: reflects current state of device's switches
*@open: this method is called when the very first user calls
* input_open_device().The driver must prepare the device
* tostart generating events (start polling thread,
* requestan IRQ, submit URB, etc.)
*@close: this method is called when the very last user calls
* input_close_device().
*@flush: purges the device. Most commonly used to get rid of force
* feedbackeffects loaded into the device when disconnecting
* fromit
*@event: event handler for events sent _to_ the device, like EV_LED
* orEV_SND. The device is expected to carry out the requested
* action(turn on a LED, play sound, etc.) The call is protected
* by@event_lock and must not sleep
*@grab: input handle that currently has the device grabbed (via
* EVIOCGRABioctl). When a handle grabs a device it becomes sole
* recipientfor all input events coming from the device
*@event_lock: this spinlock is is taken when input core receives
* andprocesses a new event for the device (in input_event()).
* Codethat accesses and/or modifies parameters of a device
* (suchas keymap or absmin, absmax, absfuzz, etc.) after device
* hasbeen registered with input core must take this lock.
*@mutex: serializes calls to open(), close() and flush() methods
*@users: stores number of users (input handlers) that opened this
* device.It is used by input_open_device() and input_close_device()
* tomake sure that dev->open() is only called when the first
* useropens device and dev->close() is called when the very
* lastuser closes the device
*@going_away: marks devices that are in a middle of unregistering and
* causesinput_open_device*() fail with -ENODEV.
*@dev: driver model's view of this device
*@h_list: list of input handles associated with the device. When
* accessingthe list dev->mutex must be held
*@node: used to place the device onto input_dev_list
*@num_vals: number of values queued in the current frame
*@max_vals: maximum number of values queued in a frame
*@vals: array of values queued in the current frame
*@devres_managed: indicates that devices is managed with devresframework
* andneeds not be explicitly unregistered or freed.
*/
struct input_dev {
@1const char *name; //输入设备名,和device->name有什么联系device_driver->nameplatform_divice->name,platform_driver->name ;
@2const char *phys;//设备在system层的物理路径,这和在/sys/device/xxx文件夹名有关吗?
@3const char *uniq;
@4struct input_id id;
structinput_id {
__u16bustype;
__u16vendor;
__u16product;
__u16version;
};
@5unsigned long propbit[BITS_TO_LONGS(INPUT_PROP_CNT)];
@6unsigned long evbit[BITS_TO_LONGS(EV_CNT)]; //支持的事件类型
__set_bit(EV_KEY,...,input->evbit);
//事件类型下产生的数据具体上报方法
@7unsigned long keybit[BITS_TO_LONGS(KEY_CNT)];
@8unsigned long relbit[BITS_TO_LONGS(REL_CNT)];
@9unsigned long absbit[BITS_TO_LONGS(ABS_CNT)];
@10unsigned long mscbit[BITS_TO_LONGS(MSC_CNT)];
@11unsigned long ledbit[BITS_TO_LONGS(LED_CNT)];
@12unsigned long sndbit[BITS_TO_LONGS(SND_CNT)];
@13unsigned long ffbit[BITS_TO_LONGS(FF_CNT)];
@14unsigned long swbit[BITS_TO_LONGS(SW_CNT)];
@15unsigned int hint_events_per_packet;
@16unsigned int keycodemax;
@17unsigned int keycodesize; //size of elements(元素)inkeycode table
@18void *keycode;
@19int (*setkeycode)(struct input_dev *dev,
const struct input_keymap_entry *ke,
unsigned int *old_keycode);
@20int (*getkeycode)(struct input_dev *dev,
struct input_keymap_entry *ke);
@21struct ff_device *ff;
//按键自动重复机制?
@22unsigned int repeat_key; //stores key code of the last key pressed; used toimplement (实施)softwareautorepeat
@23structtimer_list timer;//timer for software autorepeat
@24intrep[REP_CNT]; //currentvalues for autorepeat parameters (delay, rate)
@25struct input_mt *mt;
@26struct input_absinfo *absinfo;
@27unsigned long key[BITS_TO_LONGS(KEY_CNT)];
//reflects current state ofdevice's keys/buttons
@28unsigned long led[BITS_TO_LONGS(LED_CNT)];
//reflectscurrent state of device's LEDs
@29unsigned long snd[BITS_TO_LONGS(SND_CNT)];
//reflectscurrent state of sound effects
@30unsigned long sw[BITS_TO_LONGS(SW_CNT)];
//reflectscurrent state of device's switches
@31int (*open)(struct input_dev *dev);
@32void (*close)(struct input_dev *dev);
@33int (*flush)(struct input_dev *dev, struct file *file);
@34int (*event)(struct input_dev *dev,unsigned int type, unsigned int code, int value);
eventhandler for events sent _to_ the device, like EV_LED
* orEV_SND. The device is expected to carry out the requested
* action(turn on a LED, play sound, etc.) The call is protected
* by@event_lock and must not sleep
@35struct input_handle __rcu *grab;
@grab: input handle that currently has the device grabbed (via
EVIOCGRABioctl). When a handle grabs a device it becomes sole
recipient(唯一的容器)forall input events coming fr om the device
@36spinlock_t event_lock;
@37struct mutex mutex;
@38unsigned int users; //存储打开该设备的用户数量
@39bool going_away;
@40struct device dev; //保存一个设备
@41struct list_head h_list;
@42structlist_head node; //用于把该设备放入input_dev_list输入设备链表上
@43unsigned int num_vals;
@44unsigned int max_vals;
@45struct input_value *vals;
@46bool devres_managed; //资源管理
};
13.iio_channel
/**
*struct iio_channel - everything needed for a consumer to use achannel
*@indio_dev: Device on which the channel exists. //
*@channel: Full description of the channel.//详细描述通道
*@data: Data about the channel used by consumer. //用户使用的通道数据
*/
struct iio_channel {
structiio_dev *indio_dev;
conststruct iio_chan_spec *channel;
void*data;
};
14.iio_chan_spec
/**
*struct iio_chan_spec - specification of a single channel
*@type: What type of measurement is the channel making.
*@channel: What number do we wish to assign the channel.
*@channel2: If there is a second number for a differential
* channelthen this is it. If modified is set then the
* valuehere specifies the modifier.
*@address: Driver specific identifier.
*@scan_index: Monotonic index to give ordering in scans when read
* froma buffer.
*@scan_type: Sign: 's' or 'u' to specify signed or unsigned
* realbits: Numberof valid bits of data
* storage_bits: Realbits+ padding
* shift: Shiftright by this before masking out
* realbits.
* endianness: littleor big endian
*@info_mask: What information is to be exported about this channel.
* Thisincludes calibbias, scale etc.
*@info_mask_separate: What information is to be exported that isspecific to
* thischannel.
*@info_mask_shared_by_type: What information is to be exported that isshared
* byall channels of the same type.
*@event_mask: What events can this channel produce.
*@ext_info: Array of extended info attributes for this channel.
* Thearray is NULL terminated, the last element should
* haveits name field set to NULL.
*@extend_name: Allows labeling of channel attributes with an
* informativename. Note this has no effect codes etc,
* unlikemodifiers.
*@datasheet_name: A name used in in-kernel mapping of channels. Itshould
* correspondto the first name that the channel is referred
* toby in the datasheet (e.g. IND), or the nearest
* possiblecompound name (e.g. IND-INC).
*@modified: Does a modifier apply to this channel. What these are
* dependson the channel type. Modifier is set in
* channel2.Examples are IIO_MOD_X for axial sensors about
* the'x' axis.
*@indexed: Specify the channel has a numerical index. If not,
* thechannel index number will be suppressed for sysfs
* attributesbut not for event codes.
*@output: Channel is output.
*@differential: Channel is differential.
*/
struct iio_chan_spec {
enumiio_chan_type type;
int channel;
int channel2;
unsignedlong address;
int scan_index;
struct{
char sign;
u8 realbits;
u8 storagebits;
u8 shift;
enumiio_endian endianness;
}scan_type;
long info_mask;
long info_mask_separate;
long info_mask_shared_by_type;
long event_mask;
conststruct iio_chan_spec_ext_info *ext_info;
constchar *extend_name;
constchar *datasheet_name;
Aname used in in-kernel mapping of channels. It should
* correspondto the first name that the channel is referred
* toby in the datasheet (e.g. IND), or the nearest
* possiblecompound name (e.g. IND-INC).
unsigned modified:1;
unsigned indexed:1;
unsigned output:1;
unsigned differential:1;
};
15.list_for_each_entry
在Linux内核源码中,经常要对链表进行操作,其中一个很重要的宏是list_for_each_entry:
意思大体如下:
假设下面y有几个结点,则第一个member代表head,list_for_each_entry的作用就是循环遍历每一个pos中的member子项。
list_for_each_entry应用:
它实际上是一个 for循环,利用传入的 pos作为循环变量,从表头head开始,逐项向后(next方向)移动pos,直至又回head(prefetch()可以不考虑,用于预取以提高遍历速度)。
在程序中的使用如下:
list_for_each_entry(pos, head,member)
{
………………
addr= pos; //对返回值pos的操作,这样更容易去理解list_for_each_entry,可以把它看作for()循环
……………
input_device->name,和device->name,device_driver->name,platform_divice->name,platform_driver->name``有什么联系?