container_of
is often seen in the Linux kernel, and it is also widely used in actual driver writing.
##Function: through a member of the structure The variable address finds the first address of the structure.
is defined as follows:/** * container_of - cast a member of a structure out to the containing structure * @ptr: the pointer to the member. * @type: the type of the container struct this is embedded in. * @member: the name of the member within the struct. * */ #define container_of(ptr, type, member) ({ \ const typeof( ((type *)0)->member ) *__mptr = (ptr); \ (type *)( (char *)__mptr - offsetof(type,member) );})
: pointer to the structure member variable
: Structure type
: Name of structure member variable
The address ptr of the member member of the known structure
type is known, and the starting address
of the structure type
is solved.
The calculation formula is: starting address of type
= ptr
-size
(size is the size of member)
Use a picture to illustrate the relationship between ptr
, type
, and member
:
container_of
is that uses 0
as a member variable The base address of member
is .
An intermediate variable __mptr
is defined, "__
" represents internal use, "m
" represents middle
.
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
typeof( ((type *)0)->member )
是获取member
的类型,__mptr = (ptr)
判断ptr
与member
是否为同一类型,offsetof
计算成员member
的大小size
。
例如内核的pwm
驱动,通过成员变量chip
,找到结构体bcm2835_pwm
:
struct bcm2835_pwm { struct pwm_chip chip; struct device *dev; void __iomem *base; struct clk *clk; }; static inline struct bcm2835_pwm *to_bcm2835_pwm(struct pwm_chip *chip_ptr) { return container_of(chip_ptr, struct bcm2835_pwm, chip); }
使用container_of
通常都会定义一个函数,并且命名为to_xxx
或者to_find_xxx
,代表要找xxx
这个结构体,传参则传入成员变量指针,另外函数也会声明为inline
。
The above is the detailed content of Basics of Linux kernel - container_of principle and practical application. For more information, please follow other related articles on the PHP Chinese website!