• Android : kernel中添加虚拟文件节点


      Android 系统开发时有些数据需要同步到上层应用进行UI显示,如果是定制功能且数据量不大,可以考虑通过文件节点方式在应用和驱动之间进行通信。

      以下介绍两种文件节点的添加方法:

    一、/proc/节点:

    #include <linux/uaccess.h>
    #include <linux/proc_fs.h>
    #include <linux/module.h>
    #include <linux/kernel.h>
    #include <linux/delay.h>
    #include <asm/uaccess.h>
    #include <linux/sched.h>
    #include <linux/init.h>
    #include <asm/irq.h>
    #include <asm/io.h>
    
    #define MSG_BUF_LEN     1024
    static unsigned char msg_buf[MSG_BUF_LEN] = {0};
    static unsigned int msg_len = 0;
    static DECLARE_WAIT_QUEUE_HEAD(upgrade_percentage_waitq);
    
    uint8_t  upgrade_percentage = 0;
    
    //读接口
    static ssize_t upgrade_percentage_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { unsigned int ret = 0; // 如果 msg_len 为 0,则等待数据 wait_event_interruptible(upgrade_percentage_waitq, msg_len); copy_to_user(user_buf, msg_buf, msg_len); ret = msg_len; msg_len = 0; printk("upgrade_percentage(r) : %d ", upgrade_percentage); return ret; }
    //写接口
    static ssize_t upgrade_percentage_write(struct file *file, const char __user *user_buf, size_t count, loff_t *ppos) { if(copy_from_user(msg_buf, user_buf, count)) { return -EFAULT; } msg_len = count; wake_up_interruptible(&upgrade_percentage_waitq); return count; } const struct file_operations upgrade_percentage_operations = { .read = upgrade_percentage_read, .write = upgrade_percentage_write, }; static int nti2c_init(void) { int ret; // -> "/proc/nt68411/upgrade_percentage" printk("proc_create upgrade_percentage ... ");
    proc_mkdir("nt68411", NULL);
    proc_create("upgrade_percentage", S_IRUSR, NULL, &upgrade_percentage_operations);
      return ret;
    }
    
    static void nti2c_exit(void)
    {
        remove_proc_entry("nt68411/upgrade_percentage", NULL);
        printk("%s, ok! 
    ", __func__);
    }
    
    module_init(nti2c_init);
    module_exit(nti2c_exit);
    
    MODULE_AUTHOR("Sheldon");
    MODULE_DESCRIPTION("driver for linux platform");
    MODULE_LICENSE("GPL");

    二、/sys/class/ 节点:

    #include <linux/module.h>
    #include <linux/moduleparam.h>
    #include <linux/mod_devicetable.h>
    #include <linux/device.h>
    #include <linux/platform_device.h>
    #include <linux/init.h>
    #include <linux/fs.h>
    #include <linux/string.h>
    #include <asm/uaccess.h>
    #include <linux/delay.h>
    #include <linux/of.h>
    #include <linux/io.h>
    #include <linux/gpio.h>
    #include <linux/of_gpio.h>
    #include <linux/vmalloc.h>
    #include <linux/uaccess.h>
    #include <linux/proc_fs.h>
    #include <linux/kernel.h>
    #include <linux/sched.h>
    #include <asm/irq.h>
    #include <asm/io.h>
    
    
    static struct class *driver_class = NULL;
    static struct device *driver_dev = NULL;
    
    static ssize_t driver_percentage_show(struct device *dev, struct device_attribute *attr, char *buf)
    {
        printk("NT68411 upgrade_percentage : %d 
    ", upgrade_percentage);
        return sprintf(buf,"%u
    ",upgrade_percentage);
    }
    
    static ssize_t driver_percentage_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size)
    {
        int value = simple_strtoul(buf, NULL, 0);
        printk("NT68411 driver_percentage_store : %d 
    ", value);
        return size;
    }
    
    static struct device_attribute dev_nt68411_upgrade_attr = {
        .attr = {
            .name = "percentage",
            .mode = 0666,
        },
        .show = driver_percentage_show,
        .store = driver_percentage_store,
    };
    
    static int nti2c_init(void)
    {
        printk("%s, Enter 
    ", __func__);
    
       // --> /sys/class/nt68411/upgrade/percentage driver_class
    = class_create(THIS_MODULE, "nt68411"); if (IS_ERR(driver_class)) { printk("nt68411 class_create fail "); } driver_dev = device_create(driver_class, NULL, 0, 0,"upgrade"); if(NULL == driver_dev){ printk("nt68411 device_create fail "); } device_create_file(driver_dev, &dev_nt68411_upgrade_attr); printk("%s, Exit ", __func__); return 0; } static void nti2c_exit(void) { device_remove_file(driver_dev, &dev_nt68411_upgrade_attr); device_unregister(driver_dev); if(driver_class!=NULL) class_destroy(driver_class); printk("%s, ok! ", __func__); } module_init(nti2c_init); module_exit(nti2c_exit); MODULE_AUTHOR("Sheldon"); MODULE_DESCRIPTION("driver for linux platform"); MODULE_LICENSE("GPL");
  • 相关阅读:
    SQL中的选择判断
    Rsync
    LAMP性能优化的一些建议
    Toad9.7与Oracle11g在X86的Win7下的情况
    IIS中IUSR_和IWAM_:计算机名帐户的用户名和密码的用途
    winform编程中的跨线程访问资源(转)
    MSTDC服务的应用及相关错误的解决方案(转载)
    SQL Server 错误代码详解
    poj 1777梅森素数
    hdu 2815 baby_step c可为非素数
  • 原文地址:https://www.cnblogs.com/blogs-of-lxl/p/13371072.html
Copyright © 2020-2023  润新知