//分析container_of
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#define container_of(ptr, type, member) ( { \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );} )
/*
container_of(p, struct adv7170, sd)展开就是:
{
const typeof( ((struct adv7170 *)0)->sd ) *__mptr = (p); //这句是定义,定义一个变量__mptr(不在函数一开始定义时就得另起一对花括号)
(struct adv7170 *) ( (char *)__mptr - ( (size_t) &((struct adv7170 *)0)->sd ) );
}
重点分析: const typeof( ((struct adv7170 *)0)->sd ) *__mptr = (p);
这句其实等价: const struct v4l2_subdev *__mptr = p;
说明: typeof( ((struct adv7170 *)0)->sd )这货其实就是获取sd这个变量的类型,它的类型当然是struct v4l2_device
总结: 已知p的位置,求它外层结构体struct adv7170中的首地址?
解决问题的思路就是将p的地址减去p在 struct adv7170结构体中的偏移量就得出
struct adv7170的首地址了;
*/
struct adv7170 {
int test;
struct v4l2_subdev sd; // struct adv7170 里包含struct v4l2_subdev ,现在想知道struct adv7170的位置
unsigned char reg[128];
v4l2_std_id norm;
int input;
};
struct v4l2_subdev {
struct list_head list;
struct module *owner;
struct v4l2_device *v4l2_dev;
const struct v4l2_subdev_ops *ops;
/* name must be unique */
char name[V4L2_SUBDEV_NAME_SIZE];
/* can be used to group similar subdevs, value is driver-specific */
u32 grp_id;
/* pointer to private data */
void *priv;
};
static inline struct adv7170 *to_adv7170(struct v4l2_subdev *p)
{
return container_of(p, struct adv7170, sd);
}
static int adv7170_write_block(struct v4l2_subdev *sd, const u8 *data, unsigned int len)
{
struct i2c_client *client = v4l2_get_subdevdata(p);
struct adv7170 *encoder = to_adv7170(p); //在这里调用的,想利用sd找到母体 ???????????????????????????
... ...
}
static int adv7170_s_std_output(struct v4l2_subdev *p, v4l2_std_id std)
{
struct adv7170 *encoder = to_adv7170(p);
v4l2_dbg(1, debug, p, "set norm %llx\n", (unsigned long long)std);
if (std & V4L2_STD_NTSC) {
adv7170_write_block(sd, init_NTSC, sizeof(init_NTSC)); //这里调用的
... ...
}
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#define container_of(ptr, type, member) ( { \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );} )
/*
container_of(p, struct adv7170, sd)展开就是:
{
const typeof( ((struct adv7170 *)0)->sd ) *__mptr = (p); //这句是定义,定义一个变量__mptr(不在函数一开始定义时就得另起一对花括号)
(struct adv7170 *) ( (char *)__mptr - ( (size_t) &((struct adv7170 *)0)->sd ) );
}
重点分析: const typeof( ((struct adv7170 *)0)->sd ) *__mptr = (p);
这句其实等价: const struct v4l2_subdev *__mptr = p;
说明: typeof( ((struct adv7170 *)0)->sd )这货其实就是获取sd这个变量的类型,它的类型当然是struct v4l2_device
总结: 已知p的位置,求它外层结构体struct adv7170中的首地址?
解决问题的思路就是将p的地址减去p在 struct adv7170结构体中的偏移量就得出
struct adv7170的首地址了;
*/
struct adv7170 {
int test;
struct v4l2_subdev sd; // struct adv7170 里包含struct v4l2_subdev ,现在想知道struct adv7170的位置
unsigned char reg[128];
v4l2_std_id norm;
int input;
};
struct v4l2_subdev {
struct list_head list;
struct module *owner;
struct v4l2_device *v4l2_dev;
const struct v4l2_subdev_ops *ops;
/* name must be unique */
char name[V4L2_SUBDEV_NAME_SIZE];
/* can be used to group similar subdevs, value is driver-specific */
u32 grp_id;
/* pointer to private data */
void *priv;
};
static inline struct adv7170 *to_adv7170(struct v4l2_subdev *p)
{
return container_of(p, struct adv7170, sd);
}
static int adv7170_write_block(struct v4l2_subdev *sd, const u8 *data, unsigned int len)
{
struct i2c_client *client = v4l2_get_subdevdata(p);
struct adv7170 *encoder = to_adv7170(p); //在这里调用的,想利用sd找到母体 ???????????????????????????
... ...
}
static int adv7170_s_std_output(struct v4l2_subdev *p, v4l2_std_id std)
{
struct adv7170 *encoder = to_adv7170(p);
v4l2_dbg(1, debug, p, "set norm %llx\n", (unsigned long long)std);
if (std & V4L2_STD_NTSC) {
adv7170_write_block(sd, init_NTSC, sizeof(init_NTSC)); //这里调用的
... ...
}