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; }