kernel与用户层接口之proc接口

本文详细探讨了Linux内核与用户空间交互的重要接口——proc文件系统。通过proc,用户可以获取内核状态、进程信息以及系统配置等关键数据。proc提供了一种文本接口,使得开发者能够轻松读取和写入内核数据,从而实现诊断、监控和调试等功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

kernel与用户层接口之proc接口


#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/proc_fs.h>
#include <linux/string.h>
#include <linux/uaccess.h> //copy_from_user

#define ENTRYNAME  "n802"
static struct proc_dir_entry *proc_entry;
static char pin_name[32] = {0};
static char pin_pull[32] = {0};

/* 
  get pin level:
     echo "g12 up" > /proc/n802 
     cat /proc/n802   
*/
static int n802_read( char *page, char **start, off_t off, int count, int *eof, void *data )
{
	int i;
	char buf[64] = {0};
	int len = 0;
	int pin_level = 0;
	int gpio_index = -1;
	unsigned int pin_pull_val = GPIO_PULL_DISABLE;	

	gpio_index = find_mygpio(pin_name);
	if ( -1 == gpio_index ) {
		printk("Error: no found gpio(%s)\n", pin_name);
		goto end_n802_read;
	}

	if ( NULL != strstr(pin_pull,"up") )
		pin_pull_val = GPIO_PULLUP;

	if ( NULL != strstr(pin_pull,"down") )
		pin_pull_val = GPIO_PULLDOWN;

	gpio_request(gpio_index,pin_name);
	tcc_gpio_config(gpio_index, GPIO_FN(0)|pin_pull_val);
	tcc_gpio_direction_input(gpio_index);

	msleep(20);
	pin_level = gpio_get_value(gpio_index);
	sprintf(buf, "%s %d", pin_name, pin_level );
	len = strlen(buf);

	strcpy( page, (char*)buf);

	printk("%s: pin_name=%s(%d) pin_level=%d\n", __FUNCTION__, pin_name, gpio_index,pin_level);

	if (D>0){
	printk("%s:\n", __FUNCTION__ );
	for (i=0;i<len;i++)
		printk("%02x ", buf[i] );
	printk("\n");
	printk("%s\n", buf);
	}

end_n802_read:
	return len;
}

/*  
 set pin level:  
    echo "g12 disable 1" > /proc/n802 
    echo "g12 up 1"      > /proc/n802
    echo "g12 down 1"    > /proc/n802  
*/
static int n802_write( struct file *filp, const char __user *buff, unsigned long len, void *data )
{
	int i;
	char *p = NULL;
	char *p1 = NULL;
	int pin_level = 0;
	int is_set_pin_level = 0;
	int gpio_index = -1;
	char buf[64] = {0};
	unsigned int pin_pull_val = GPIO_PULL_DISABLE;

	memset( buf, 0, sizeof(buf) );
	if (copy_from_user( buf, buff, len )) {
		return -EFAULT;
	}

	if (D>0){
	printk("%s:  len=%d\n", __FUNCTION__, (int)len);
	for (i=0;i<10;i++)
		printk("%02x ", buf[i] );
	printk("\n");
	printk("%s\n", buf);
	}

	memset( pin_name, 0, sizeof(pin_name) );
	memset( pin_pull, 0, sizeof(pin_pull) );

	p1 = buf;
	if ( NULL != (p = strchr(p1, ' ')) ) {
		*p = 0;
		strcpy(pin_name, p1);

		p++;
		p1 = p;
		if ( NULL != (p = strchr(p1, ' ')) ) {
			*p = 0;
			strcpy(pin_pull, p1);
			p++;
			pin_level = simple_strtoul(p, NULL, 0);
			is_set_pin_level = 1;
		}else{
			strcpy(pin_pull, p1);
			if ( NULL != (p = strchr(pin_pull, '\n')))
				*p = 0;
		}
	}

	if ( NULL != strstr(pin_pull,"up") )
		pin_pull_val = GPIO_PULLUP;

	if ( NULL != strstr(pin_pull,"down") )
		pin_pull_val = GPIO_PULLDOWN;

	gpio_index = find_mygpio(pin_name);
	if ( -1 == gpio_index ) {
		printk("Error: no found gpio(%s)\n", pin_name);
		goto end_n802_write;
	}

	if (is_set_pin_level ) {
		printk("set pin_name=%s(%d) pin_pull=%s pin_level=%d\n", pin_name, gpio_index, pin_pull, pin_level);
		gpio_request(gpio_index,pin_name);
		tcc_gpio_config(gpio_index, GPIO_FN(0)|pin_pull_val);
		gpio_direction_output(gpio_index,1);
		gpio_set_value(gpio_index,pin_level);
	}else{
		printk("get pin_name=%s(%d) pin_pull=%s\n", pin_name, gpio_index, pin_pull);
	}
end_n802_write:
	return len;
}

static int __init n802_init(void)
{
	printk("%s\n", __FUNCTION__);

        proc_entry = create_proc_entry( ENTRYNAME, 0666, NULL );
        if (proc_entry == NULL) {
                printk(KERN_INFO "%s:  Couldn't create proc entry\n", __FUNCTION__ );
                return  -ENOMEM;
        }
        proc_entry->write_proc = n802_write;
        proc_entry->read_proc  = n802_read;

}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值