1.系统调用 2.命令行接口
3.共享内存 4.管道
5.信号 6.消息队列
7.套接字 8.文件系统
内核启动参数、 模块参数与 sysfs、sysctl、系统调用、netlink、procfs、seq_file、debugfs、relayfs,
模块参数与sysfs、procfs、debugfs、relayfs是基于文件系统的通信机制,用于内核空间向用户控件输出信息
sysctl、系统调用是由用户空间发起的通信机制
以上均为单工通信机制,在内核空间与用户空间的双向互动数据交换上略显不足
Netlink是基于socket的通信机制,由于socket本身的双共性、突发性、不阻塞特点,因此能够很好的满足内核与用户空间小量数据的及时交互
1、创建sysfs节点
典型的属性文件,利用sysfs_create_group 创建节点
static DEVICE_ATTR_RW(status);
static DEVICE_ATTR_RO(enabled);
用的是 kernfs_file_fops, 需要自己封装接口
这种方式一般是创建在已经存在的的sys文件系统下的 dev节点目录下
/* add typec ccpin normalization node for factory test start*/
typedef enum
{
CC1,
CC2,
CCNone
} CCOrientation;
static int typec_polarity = CCNone;
static ssize_t ccpin_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
if (typec_polarity == CC1)
return snprintf(buf, 256, "%s\n", "CC1");
else if (typec_polarity == CC2)
return snprintf(buf, 256, "%s\n", "CC2");
else
return snprintf(buf, 256, "%s\n", "Unknown");
}
static DEVICE_ATTR_RO(ccpin);
static struct attribute *typec_attrs[] = {
&dev_attr_ccpin.attr,
NULL,
};
static struct attribute_group typec_group = {
.attrs = typec_attrs,
};
static int extcon_create_typec_sysfs(struct device *dev)
{
int ret = 0;
ret = sysfs_create_group(&dev->kobj, &typec_group);
if (ret) {
dev_info(dev, "typec ccpin node create fail \n");
sysfs_remove_group(&dev->kobj, &typec_group);
return ret;
}
return 0;
}
2、创建debugfs节点,然后封装file_operations 接口
这种方式一般是创建在debugfs下面
自己封装 file_operations 接口
static ssize_t xxx_debugfs_read(struct file *file, char __user *buffer, size_t length, loff_t *offset)
{
return length;
}
static ssize_t xxx_debugfs_write(struct file *file, const char __user *buffer, size_t length, loff_t *offset)
{
struct device *dev = (struct device *)(file->f_inode->i_private);
struct xxx_chip *data= dev_get_drvdata(dev);
/* You need to make your own changes and confirm
the regmap address location
*/
struct regmap *regmap = data->data.regmap;
char data_buffer[128], type = 0;
unsigned int reg, reg_len, num;
unsigned short value;
ssize_t size;
if (regmap == NULL) {
dev_err(dev, "regmap is null, please init regmap\n");
goto regmap_err;
}
size = simple_write_to_buffer(data_buffer, 128, offset, buffer, length);
dev_err(dev, "data_buffer = %s\n", data_buffer);
if ((data_buffer[0] != 'r') && (data_buffer[0] != 'w')) {
dev_err(dev, "%s type error, please input 'r' or 'w'\n", __func__);
goto type_err;
}
dev_err(dev, "write format:echo w [reg] [reg_val] [reg_len] [num] > xxx_file\n");
dev_err(dev, "read format:echo r [reg] [reg_len] [num] > xxx_file\n");
sscanf(data_buffer, "%c", &type);
switch (type) {
case 'r':
sscanf(data_buffer, "%c %x %d %d", &type, ®, ®_len, &num);
do {
if (regmap_raw_read(regmap, reg, (void *)&value, reg_len)) {
dev_err(dev, "%s regmap_raw_read %d byte fail %d\n",
__func__, reg_len, __LINE__);
goto read_err;
}
dev_err(dev, "regmap_raw_read %d byte success value = 0x%x\n",
reg_len, value);
} while(--num);
break;
case 'w':
sscanf(data_buffer, "%c %x %hx %d %d", &type, ®, &value, ®_len, &num);
do {
if (regmap_raw_write(regmap, reg, (void *)&value, reg_len)) {
dev_err(dev, "%s regmap_raw_write %d byte fail %d\n",
__func__, reg_len, __LINE__);
goto write_err;
}
dev_err(dev, "regmap_raw_write %d byte success value = 0x%x\n",
reg_len, value);
} while(--num);
break;
}
read_err:
write_err:
regmap_err:
type_err:
return length;
}
static const struct file_operations xxx_debugfs_fops = {
.read = xxx_debugfs_read,
.write = xxx_debugfs_write,
};
static int xxx_debugfs_init(struct device *dev)
{
struct dentry *debugfs_dir = NULL;
int ret = 0;
debugfs_dir = debugfs_create_dir(xxx_debugfs, NULL); //创建目录
if (!debugfs_dir) {
dev_err(dev, "%s create debug file system fail\n", __func__);
ret = -1;
goto debugfs_create_error;
}
debugfs_create_file(xxx_file, 0664,
debugfs_dir, dev, &xxx_debugfs_fops); //创建文件
dev_err(dev, "%s create debug file system success\n", __func__);
return ret;
debugfs_create_error:
return ret;
}
3、创建proc 节点,封装 proc_ops
只需要封装open接口就可以
static const struct proc_ops xxx_fops = {
.proc_open = xxx_open,
.proc_read = seq_read,
.proc_lseek = seq_lseek
.proc_release = single_release,
}