kobject 实现了面向对象的管理机制,一般嵌入一个更大的结构体中 在内核中注册的一个kobject 对应 sysfs系统中的一个目录。
1、在/sys/kernel/目录下创建一个目录用到函数为 kobject_create_and_add ,原型如下:
struct kobject *kobject_create_and_add(const char *name, struct kobject *parent)
2、通常kobject_create_and_add 和 sysfs_create_file通常一起用,后者的作用是在sysfs某一个目录下创建一个文件,sysfs_create_file原型如下:
int sysfs_create_file(struct kobject *kobj, const struct device_attribute *attr)
3、经过以上两个函数后kobject对应目录下可能存在若干文件,这些文件被称为属性文件,每个文件对应着一个kobj_attribute结构体实例,创建kobj_attribute结构体实例时需要指定文件名、用户权限、读写函数(可选)。结构体定义在include/linux/kobject.h:
struct kobj_attribute {
struct attribute attr;
ssize_t (*show)(struct kobject *kobj, struct kobj_attribute *attr,
char *buf);
ssize_t (*store)(struct kobject *kobj, struct kobj_attribute *attr,
const char *buf, size_t count);
};
下面一起来看看代码,代码从实际驱动中拿来的
//只贴出用代表的两个读写函数
static ssize_t hdmi_in1_update_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf) {
return 0;
}
static ssize_t hdmi_in1_update_store(struct kobject *kobj,
struct kobj_attribute *attr, char *buf, size_t count)
{
char tmp[128] = { 0 };
int err= 0;
struct msm_camera_power_ctrl_t *power_info;
struct msm_camera_i2c_client *sensor_i2c_client;
sensor_i2c_client = hdmi_6911_csi1_total_s_ctrl->sensor_i2c_client;
power_info = &hdmi_6911_csi1_total_s_ctrl->sensordata->power_info;
err = msm_camera_power_up(power_info, hdmi_6911_csi1_total_s_ctrl->sensor_device_type,sensor_i2c_client);
if(err<0){
pr_err("Failed power up msm_camera hdmi_in0\n");
return -1;
}
if(count > 1 && count < 127)
{ pr_err("hdmi_6911_csi1_total_s_ctrl = %p.\n", hdmi_6911_csi1_total_s_ctrl);
memcpy(tmp, buf, count - 1);
rom_len = get_lt6911_bin_file_buf(tmp, rom_buf);
err = lt6911_upgrade(hdmi_6911_csi1_total_s_ctrl, rom_buf, rom_len);
if(err<0){
pr_err("Failed upgrade lt6911\n");
return -1;
}
//升级完固件后reset芯片
gpio_direction_output(46, 1);
msleep(100);
gpio_direction_output(46, 0);
msleep(1000);
}
return count;
}
//定义创建的koject,这里hdmi_in硬件有两个,所以是两个目标
static struct koject hdmi_in_state_kobj[2];
//以下的给对应目标文件的文件权限以及读写函数,其中读写函数若不需要可用NULL代替
/*create lt6911 state interface*/
static struct kobj_attribute hdmi_in0_state_attribute = __ATTR(hdmi_in0_state,
0664, hdmi_in0_state_show, hdmi_in0_state_store);
static struct kobj_attribute hdmi_in1_state_attribute = __ATTR(hdmi_in1_state,
0664, hdmi_in1_state_show, hdmi_in1_state_store);
/*create lt6911 parameter interface*/
static struct kobj_attribute hdmi_in0_parameter_attribute = __ATTR(hdmi_in0_parameter,
0664, hdmi_in0_parameter_show, hdmi_in0_parameter_store);
static struct kobj_attribute hdmi_in1_parameter_attribute = __ATTR(hdmi_in1_parameter,
0664, hdmi_in1_parameter_show, hdmi_in1_parameter_store);
/*create lt6911 reset interface*/
static struct kobj_attribute hdmi_in0_reset_attribute = __ATTR(hdmi_in0_reset,
0664, hdmi_in0_reset_show, hdmi_in0_reset_store);
static struct kobj_attribute hdmi_in1_reset_attribute = __ATTR(hdmi_in1_reset,
0664, hdmi_in1_reset_show, hdmi_in1_reset_store);
/*create lt6911 update interface*/
static struct kobj_attribute hdmi_in0_update_attribute = __ATTR(hdmi_in0_update,
0664, hdmi_in0_update_show, hdmi_in0_update_store);
static struct kobj_attribute hdmi_in1_update_attribute = __ATTR(hdmi_in1_update,
0664, hdmi_in1_update_show, hdmi_in1_update_store);
int hdmi_in_kobj_init(int hdmi_in_num)
{
int err = -1;
if(hdmi_in_num==0){
hdmi_in_state_kobj[0] = *(kobject_create_and_add("hdmi_in0",
kernel_kobj));//创建了名为hdmi_in0的目录
err = sysfs_create_file(&hdmi_in_state_kobj[0], &hdmi_in0_state_attribute.attr);//创建了名为hdmi_in_state的文件,以下同理
if (err) {
kobject_put(&hdmi_in_state_kobj[0]);
pr_err("hdmi_in0_state sysfs create fail .\n");
return err;
}
err = sysfs_create_file(&hdmi_in_state_kobj[0], &hdmi_in0_parameter_attribute.attr);
if (err) {
kobject_put(&hdmi_in_state_kobj[0]);
pr_err("hdmi_in0_parameter create fail .\n");
return err;
}
err = sysfs_create_file(&hdmi_in_state_kobj[0], &hdmi_in0_reset_attribute.attr);
if (err) {
kobject_put(&hdmi_in_state_kobj[0]);
pr_err("hdmi_in0_reset create fail .\n");
return err;
}
err = sysfs_create_file(&hdmi_in_state_kobj[0], &hdmi_in0_update_attribute.attr);
if (err) {
kobject_put(&hdmi_in_state_kobj[0]);
pr_err("hdmi_in0_update create fail .\n");
return err;
}
}
if(hdmi_in_num==1){
hdmi_in_state_kobj[1] = *(kobject_create_and_add("hdmi_in1", kernel_kobj));
err = sysfs_create_file(&hdmi_in_state_kobj[1], &hdmi_in1_state_attribute.attr);
if (err) {
kobject_put(&hdmi_in_state_kobj[1]);
pr_err("hdmi_in1_state sysfs create fail .\n");
return err;
}
err = sysfs_create_file(&hdmi_in_state_kobj[1], &hdmi_in1_parameter_attribute.attr);
if (err) {
kobject_put(&hdmi_in_state_kobj[1]);
pr_err("hdmi_in1_parameter create fail .\n");
return err;
}
err = sysfs_create_file(&hdmi_in_state_kobj[1], &hdmi_in1_reset_attribute.attr);
if (err) {
kobject_put(&hdmi_in_state_kobj[1]);
pr_err("hdmi_in1_reset create fail .\n");
return err;
}
err = sysfs_create_file(&hdmi_in_state_kobj[1], &hdmi_in1_update_attribute.attr);
if (err) {
kobject_put(&hdmi_in_state_kobj[1]);
pr_err("hdmi_in1_update create fail .\n");
return err;
}
}
pr_info("%s, successed to creat kobject for hdmi_in%d\n", __func__, hdmi_in_num);
return err;
}
自此分析完了可以自己动手去试试吧