linux添加扩展gpio,linux中创建gpio节点

转自:http://blog.chinaunix.net/uid-29165999-id-4296162.html

#define GPIO_MAJOR 230 // major device NO.

#define GPIO_MINOR 0 // minor device NO.

#define DEVICE_NAME "gpios"

#define SET_OUTPUT_LOW 0

#define SET_OUTPUT_HIGH 1

#define GET_VALUE 2

#define SET_INPUT 3

static struct class *gpio_class;

static struct gpio gpio_array[] =

{

{ GPIO_TO_PIN(0, 0), GPIOF_OUT_INIT_LOW, "RTU_WDI_SIGNAL" },

{ GPIO_TO_PIN(0, 1), GPIOF_OUT_INIT_HIGH, "RTU_PLC_BAK_IO1"},

};

static int gpio_open(struct inode *inode,struct file *file)

{

printk(KERN_WARNING"gpio open success!\n");

return 0;

}

static int gpio_release(struct inode *inode, struct file *filp)

{

printk (KERN_ALERT "Device gpio released\n");

return 0;

}

static long gpio_ioctl(struct file *file,unsigned int cmd,unsigned long gpio)

{

int i;

unsigned long gpio_num = (gpio/100)*16+gpio%100;

for (i = 0; i < ARRAY_SIZE(gpio_array); i++) {

if(gpio_array[i].gpio == gpio_num)

goto valid_gpio;

}

return -1;

valid_gpio:

switch(cmd)//cmd表示应用程序传入的 GPIO 动作

{

case SET_OUTPUT_LOW://0

{

gpio_direction_output(gpio_num, 0);

break;

}

case SET_OUTPUT_HIGH://1

{

gpio_direction_output(gpio_num, 1);

break;

}

case GET_VALUE://2

{

return gpio_get_value(gpio_num);

}

case SET_INPUT://3

{

gpio_direction_input(gpio_num);

break;

}

default:

{

printk(KERN_EMERG "GPIO command mistake!!!\n");

break;

}

}

return 0;

}

static const struct file_operations gpio_fops =

{

.owner = THIS_MODULE,

.open = gpio_open,

.release = gpio_release,

.unlocked_ioctl = gpio_ioctl,

};

//驱动加载函数

static int __init gpio_init(void)

{

int ret;

//注册一些列GPIO

ret = gpio_request_array(gpio_array, ARRAY_SIZE(gpio_array));

if (ret < 0)

{

printk(KERN_EMERG "GPIO request failed\n");

goto request_failed;

}

const char *name = DEVICE_NAME;

dev_t my_dev_no;

struct cdev *gpio_cdev;

//分配cdev结构体

gpio_cdev = cdev_alloc();

if(gpio_cdev == NULL)

{

printk(KERN_EMERG "Cannot alloc cdev\n");

goto request_failed;

}

//初始化cdev结构体

cdev_init(gpio_cdev,&gpio_fops);

gpio_cdev->owner=THIS_MODULE;

int result=alloc_chrdev_region(&my_dev_no,0,1,DEVICE_NAME); //动态分配设备号

if(result < 0)

{

printk(KERN_EMERG "alloc_chrdev_region failed\n");

goto request_failed;

}

kobject_set_name(&cdev->kobj, "%s", name);

ret=cdev_add(gpio_cdev,my_dev_no,1);

if(ret < 0)

{

printk(KERN_EMERG "GPIO register failed\n");

goto request_failed;

}

//在sysfs文件系统下创建一个类

gpio_class = class_create(THIS_MODULE, DEVICE_NAME);

//在/dev中创建设备节点

device_create(gpio_class, NULL, my_dev_no, NULL, DEVICE_NAME);

return ret;

request_failed:

gpio_free_array(gpio_array, ARRAY_SIZE(gpio_array));

return ret;

}

static void __exit gpio_exit(void)

{

device_destroy(gpio_class, MKDEV(GPIO_MAJOR, GPIO_MINOR));

class_unregister(gpio_class);

unregister_chrdev(GPIO_MAJOR, DEVICE_NAME);

}

module_init(gpio_init);

module_exit(gpio_exit);

MODULE_LICENSE("GPL");

原文:http://www.cnblogs.com/dirt2/p/5893756.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值