1.使用device_create_file创建
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kdev_t.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <asm/io.h>
#include <linux/platform_device.h>
#include <linux/ioport.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/gpio.h>
#include <linux/of_gpio.h>
static char test_flag[32]="0";
static ssize_t test_mode_show(struct device *dev,struct device_attribute *attr,
char *buf)
{
printk("xxxxx xxx %s,%d: buf: %s test_flag:%s\n",__func__,__LINE__,buf,test_flag);
return sprintf(buf, "%s\n",test_flag);
}
static ssize_t test_mode_store(struct device *dev,struct device_attribute *attr,
const char *buf, size_t count)
{
sprintf(test_flag, "%s",buf);
printk("xxxxx %s,%d: buf: %s \n",__func__,__LINE__,buf);
return count;
}
static DEVICE_ATTR(xxx_test_mode,0644, test_mode_show, test_mode_store);
static int test_driver_probe(struct platform_device *pdev)
{
int ret;
int force_gpio;
struct device_node *np = pdev->dev.of_node;
printk("xxxxx %s,%d: Enter\n",__func__,__LINE__);
force_gpio = of_get_named_gpio(np,"qcom,gpio-force-download", 0);
if(gpio_is_valid(force_gpio)){
ret = gpio_request(force_gpio, "qcom-force-9008-gpio");
gpio_export(force_gpio,0);
}
ret = device_create_file(&pdev->dev, &dev_attr_xxx_test_mode);
if (ret < 0){
printk("xxxxx create files fail\n");
return ret;
}
return 0;
}
static int test_driver_remove(struct platform_device *pdev)
{
printk("xxxxx %s,%d: Enter\n",__func__,__LINE__);
device_remove_file(&pdev->dev, &dev_attr_xxx_test_mode);
return 0;
}
static const struct of_device_id of_xxx_test_mode_match[] = {
{ .compatible = "xxx-force-usb-boot", },
{},
};
static struct platform_driver test_driver ={
.probe = test_driver_probe,
.remove = test_driver_remove,
.driver = {
.name = "xxx-test-mode",
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(of_xxx_test_mode_match),
},
};
static int test_driver_init(void)
{
printk("xxxxx %s,%d: Enter\n",__func__,__LINE__);
return platform_driver_register(&test_driver);
}
static void test_driver_exit(void)
{
printk("xxxxx %s,%d: Enter\n",__func__,__LINE__);
platform_driver_unregister(&test_driver);
return;
}
module_init(test_driver_init);
module_exit(test_driver_exit);
2.使用class_create创建
#include <linux/module.h>
#include <linux/kobject.h>
#include <linux/sysfs.h>
#include <linux/string.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/list.h>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/ctype.h>
#include <linux/platform_device.h>
#include <linux/reboot.h>
#include <linux/kdev_t.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <asm/io.h>
#include <linux/ioport.h>
const char * test_reboot_mode = "0";
static struct class *test_class = NULL;
static ssize_t force_reboot_store(struct class *class, struct class_attribute *attr,
const char *buf, size_t count)
{
if (sysfs_streq(buf, "1")){
printk(KERN_INFO "do restart\n");
kernel_restart(NULL);
test_reboot_mode=buf;
}else if (sysfs_streq(buf, "0")){
printk(KERN_INFO "do nothing\n");
test_reboot_mode=buf;
}
return count;
}
static ssize_t force_reboot_show(struct class *class, struct class_attribute *attr,
char *buf)
{
return sprintf(buf, "%s\n", test_reboot_mode);
}
static CLASS_ATTR_RW(force_reboot);
static int test_mode_probe(struct platform_device *pdev)
{
printk(KERN_INFO "%s start...\n",__func__);
return 0;
}
static int test_mode_remove(struct platform_device *pdev)
{
return 0;
}
static struct platform_driver test_mode_driver = {
.probe = test_mode_probe,
.remove = test_mode_remove,
.driver = {
.name = "force-reboot",
},
};
static int test_driver_init(void)
{
int ret;
printk(KERN_INFO "%s,%d: Enter\n",__func__,__LINE__);
test_class = class_create(THIS_MODULE,"test_class");
ret = PTR_ERR(test_class);
if (IS_ERR(test_class)){
printk(KERN_ERR "could not create sysfs files\n");
return ret;
}
ret = class_create_file(test_class, &class_attr_force_reboot);
if (ret) {
printk(KERN_ERR "could not create sysfs files\n");
return ret;
}
return platform_driver_register(&test_mode_driver);
}
static void test_driver_exit(void)
{
printk(KERN_INFO "%s,%d: Enter\n",__func__,__LINE__);
class_remove_file(test_class, &class_attr_force_reboot);
class_destroy(test_class);
platform_driver_unregister(&test_mode_driver);
return;
}
module_init(test_driver_init);
module_exit(test_driver_exit);
3.
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/device.h>
// 自定义设备属性
static ssize_t my_attr_show(struct device *dev, struct device_attribute *attr, char *buf)
{
// 在此处实现读取属性的逻辑
return snprintf(buf, PAGE_SIZE, "Hello, World!\n");
}
static DEVICE_ATTR_RO(my_attr);
static struct attribute *my_attrs[] = { &dev_attr_my_attr.attr, NULL, };
static const struct attribute_group my_attr_group = { .attrs = my_attrs, };
static int __init my_module_init(void)
{
struct class *my_class;
// 创建设备类 my_class = class_create(THIS_MODULE, "my_class");
if (IS_ERR(my_class))
{
pr_err("Failed to create class\n");
return PTR_ERR(my_class);
}
// 创建设备节点
device_create_with_groups(my_class, NULL, 0, NULL, &my_attr_group, "my_device");
return 0;
}
static void __exit my_module_exit(void)
{
// 销毁设备节点
class_destroy(my_class);
}
module_init(my_module_init);
module_exit(my_module_exit);