Chinaunix首页 | 论坛 | 博客
  • 博客访问: 325543
  • 博文数量: 101
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 774
  • 用 户 组: 普通用户
  • 注册时间: 2018-10-15 14:13
个人简介

搭建一个和linux开发者知识共享和学习的平台

文章分类

全部博文(101)

文章存档

2024年(15)

2023年(24)

2022年(27)

2019年(8)

2018年(27)

分类: LINUX

2022-10-21 15:08:29

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include




typedef unsigned char    UI_08;
typedef unsigned short  UI_16;
typedef unsigned int    UI_32;
typedef char            SI_08;
typedef short            SI_16;
typedef int              SI_32;




static unsigned long flag=1;
static struct mutex uevent_sock_mutex;


static ssize_t att_show(struct kobject *kobj, struct attribute *attr, char *buf)
{
size_t count=0;

count+=sprintf(&buf[count],"%lu\n",flag);
return count;
}


static ssize_t att_store(struct kobject *kobj, struct attribute *attr, const char *buf, size_t count)
{
int retval=-1;
struct kobj_uevent_env *env;
char *devpath;
char *action_string="test_action";

flag=buf[0]-'0';
//通过kobject_uevent来将内核对象kobj的状态变化通知用户程序
switch(flag)
{
case 0:
kobject_uevent(kobj,KOBJ_ADD);
break;
case 1:
kobject_uevent(kobj,KOBJ_REMOVE);
break;
case 2:
kobject_uevent(kobj,KOBJ_CHANGE);
break;
case 3:
kobject_uevent(kobj,KOBJ_MOVE);
break;
case 4:
kobject_uevent(kobj,KOBJ_ONLINE);
break;
case 5:
kobject_uevent(kobj,KOBJ_OFFLINE);

env = kzalloc(sizeof(struct kobj_uevent_env), GFP_KERNEL);
if (!env)
return -ENOMEM;
 
/* complete object path */
devpath = kobject_get_path(kobj, GFP_KERNEL);
if (!devpath) {
retval = -ENOENT;
}
 
/* default keys */
retval = add_uevent_var(env, "ACTION=%s", action_string);

retval = add_uevent_var(env, "DEVPATH=%s", devpath);


//根据形参和获取的subsystem和devpath的值设置默认的环境变量 - 




mutex_lock(&uevent_sock_mutex);

mutex_unlock(&uevent_sock_mutex);
kfree(env);
break;
}
return count;
}


static struct attribute cld_att={
.name="cldatt",
.mode=S_IRUGO|S_IWUSR,
};


static const struct sysfs_ops att_ops={
.show=att_show,
.store=att_store,
};


static struct kobj_type cld_ktype={
.sysfs_ops=&att_ops,
};


static struct kobject *parent;
static struct kobject *child;
static struct kset *c_kset;


static int kobj_demo_init(void)
{
int err;

parent=kobject_create_and_add("pa_obj",NULL);
child=kzalloc(sizeof(*child),GFP_KERNEL);
if(!child)
return PTR_ERR(child);

//一个能够通知用户空间状态变化的kobject必须隶属于某一个kset,也就是
//所谓的subsystem,所以此处给内核对象child创建一个kset对象c_kset
c_kset=kset_create_and_add("c_kset",NULL,parent);
if(!c_kset)
return -1;
child->kset=c_kset;

err=kobject_init_and_add(child,&cld_ktype,parent,"cld_obj");
if(err)
return err;

//为内核对象child创建一个属性文件
err=sysfs_create_file(child,&cld_att);

mutex_init(&uevent_sock_mutex);
return err;
}


static void kobj_demo_exit(void)
{
sysfs_remove_file(child,&cld_att);

kset_unregister(c_kset);
kobject_del(child);
kobject_del(parent);
}


module_init(kobj_demo_init);
module_exit(kobj_demo_exit);




MODULE_LICENSE("GPL");














阅读(714) | 评论(0) | 转发(0) |
0

上一篇:linux uvc驱动demo

下一篇:linux netlink驱动demo

给主人留下些什么吧!~~