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");