添加可自定义操作的proc文件节点

根据项目需求,需要编写文件节点供上层apk操作底层gpio口,其中在proc文件系统下,创建自己的可读写节点,最为简单。
首先添加需要使用到的linux内核头文件:

#include <linux/module.h> 
#include <linux/init.h> 
#include <linux/version.h>
#include <linux/proc_fs.h> 
#include <asm/uaccess.h> 
#include <linux/gpio.h> 
#include <linux/backlight.h>
#include <linux/gpio/consumer.h>
#include <linux/module.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>

#include <drm/drmP.h>
#include <drm/drm_crtc.h>
#include <drm/drm_mipi_dsi.h>
#include <drm/drm_panel.h>

#include <video/display_timing.h>
#include <video/mipi_display.h>
#include <video/of_display_timing.h>
#include <video/videomode.h>

添加自定义宏

#define USER_ROOT_DIR "gpio_control_config" 
#define USER_ENTRY3 "identity"

#define YLMK_EN_GPIO	169 //gpio5 c1 -->medical boot
#define BLOOD_OXYGEN	68 //gpio2 b4 -->blood oxygen
#define IDENTITY	219 //gpio7 a3 -->identity

定义proc结构体指针

static struct proc_dir_entry *gpio_control_config; 
static struct proc_dir_entry *identity;
static char msg[255];  //数据缓冲区

添加节点入口和出口,在系统加载这个字符驱动时,会从module_init()进入,然后调用其中的回调函数在这儿也就是proc_identity_init函数。
然后我们在初始化中,通过proc_mkdir创建一个proc文件节点下的文件夹。其中的参数USER_ROOT_DIR :文件夹的名字。
NULL:文件夹所属的父节点。为MULL时则表示就在proc下。
然后proc_create函数则就是创建节点,其中的参数:
USER_ENTRY3:节点名称
0777 :节点拥有的系统权限
gpio_control_config :节点所属的父节点。为NULL时表示就在proc下。
identity_fops :文件节点的操作函数,为struct file_operations *类型
卸载驱动时则调用module_exit(),通过remove_proc_entry()函数来移除节点,注意需要先移除创建的子节点,然后再移除父节点。

static int proc_identity_init(void) 
{
	//gpio_request(YLMK_EN_GPIO,"medical_boot");
	gpio_request(BLOOD_OXYGEN,"blood_oxygen");
	gpio_request(IDENTITY,"identity");
	//gpio_direction_output(YLMK_EN_GPIO,0);
	gpio_direction_output(IDENTITY,0);

	gpio_control_config = proc_mkdir(USER_ROOT_DIR,NULL);
	identity = proc_create(USER_ENTRY3, 0777, gpio_control_config, &identity_fops);
	return 0;
}

static void proc_identity_exit(void)
{
	remove_proc_entry(USER_ENTRY1,gpio_control_config);
	remove_proc_entry(USER_ROOT_DIR,NULL); 
	printk(KERN_INFO "All proc entry removed !\n");
} 

module_init(proc_identity_init);
module_exit(proc_identity_exit);
MODULE_LICENSE("GPL");

添加file_operations 操作函数(操作函数可根据自己的需要自行编写,我这儿只做了如echo on > /proc/gpio_control_config/identity 则给相应的gpio上电):

ssize_t identity_read(struct file *filp, char __user *buf, size_t len, loff_t *ops)
{
	int ret;
	char val[20];
	sprintf(val, "%s", msg);	
	ret = simple_read_from_buffer(buf, len, ops, val, strlen(val));
	return ret;
}

ssize_t identity_write(struct file *file,const char __user *buffer,size_t count,loff_t *ops) 
{
	//medical_boot control
	if(copy_from_user((void *)msg,(const void __user *)buffer,count)) 
		return -EFAULT;
	//identity control
    if(strcmp(msg,"on") == 1){	
		gpio_direction_output(IDENTITY,1); 	
	}
	else{
		gpio_direction_output(IDENTITY,0);
	}
	return count; 
}

static struct file_operations identity_fops = {
    .owner = THIS_MODULE,
    .write = identity_write,	//echo
    .read =  identity_read,  //cat
};

到这儿一个proc节点就编写完成了,然后需要将该驱动编译到内核中去,在kernel/driver/misc/目录下修改Makefile 和Kconfig文件我的驱动文件名字为ylmk_config.c。
Makefile中添加:

obj-$(CONFIG_YLMK_CONFIG)   += ylmk_config.o

Kconfig中添加:

config YLMK_CONFIG
	tristate "ylmk config Reader Controller support"
	default n
	help
	  say Y here to enable Rockchip Smartcard Reader Controller driver
	  for Soc such as RK3128,RK322x,RK3288,RK3368,RK3366 and etc.

我们平台需要将新增的驱动文件写入默认配置,在/kernel/arch/arm/configs/下修改rockchip_defconfig文件:
添加

CONFIG_YLMK_CONFIG=y

重新编译并烧录kernel即可。

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值