linux gpio 用户态,Linux内核学习笔记之使用ioctl函数实现用户态命令

驱动程序:

/********************************

* GPIO驱动程序控制GPIO接口高低电平

* 基于gpio库,四个GPIO识别为一个设备

* 使用miscdevice结构体动态分配设备号,自动创建/dev/文件

* 使用ioctl函数实现用户态命令

* 更多内容见于笔记05

* 开发板:Tiny 4412

* 主控芯片:Exynos 4412

* author: zhangn

* date: 2016-1-12

********************************/

#include

#include

#include

#include

//包含gpio库头文件

#include //所有处理器通用

#include //三棒子芯片公用

#include //只针对4412芯片

#define GPIO_NUM4

//0.定义ioctl命令,本例我们定义两个带一个参数的命令

/****************************************************************

关于_IOW,这是内核中定义的一个用于向内核写数据的一个宏

其参数是_IOW(幻数, 命令序号, 命令所占内存大小)

对于第三个字段,这里要使用参数的数据类型,内核里会使用sizeof获得

这里具体说明详见ldd3的第六章关于ioctl的说明

最后要注意的是这的宏定义要和用户态程序完全相同

*****************************************************************/

#define GPIO_TYPE'Z'//区分不同命令而取的8位幻数,为简便随便使用一个字母

#define GPIO_ON_IOW(GPIO_TYPE, 1, int)//用户态定义命令参数

#define GPIO_OFF_IOW(GPIO_TYPE, 2, int)

//四个设备,定义四个gpio号

static int gpios[GPIO_NUM];

//7.实现ioctl函数

//这里书上说函数实参应该在file前面还有个inode参数

//但加上该参数后用户态传进来的命令和参数错位,

//去掉该参数后程序正常,不晓得什么原因,是版本问题?

static long gpio_ioctl(struct file *filp,

unsigned int req, unsigned long arg)

{

printk("req = %d, arg = %ld\n", req, arg);

/*if(arg>3 || arg<0)

{

printk("Only support gpio 0~3\n");

return -1;

}*/

//req为命令代码,代表开关.arg为命令参数,代表gpio序号

switch(req)

{

case GPIO_ON:

gpio_set_value(gpios[arg], 0);

printk("arg_on = %ld\n", arg);

break;

case GPIO_OFF:

gpio_set_value(gpios[arg], 1);

printk("arg_off = %ld\n", arg);

break;

default:

printk("arg_err = %ld\n", arg);

break;

}

return 0;

}

//1.准备file_operations

static struct file_operations fops =

{

//本例中使用了ioctl函数,不需要open,read等函数

.owner = THIS_MODULE,

.unlocked_ioctl = gpio_ioctl,

};

//2.准备miscdevice

//如果将4个GPIO看成一个设备,推荐使用miscdevice代替cdev

//如果一个驱动程序要驱动多个设备,那么就不应该使用miscdevice

//miscdevice会在内核中使用同一个主设备号,设备间使用次设备号进行区分

//内核中会为所有使用misc的设备维护一个链表,具体请自行查阅misc相关信息

//使用misc的好处是内核会自动创建/dev/文件,自动分配设备号

static struct miscdevice misc =

{

.minor = MISC_DYNAMIC_MINOR,//次设备号,使用MISC_DYNAMIC_MINOR系统会自动分配

.name = "gpios",//设备名称,自动创建的/dev/文件也使用这个名字

.fops = &fops,

};

static int __init my_init(void)

{

int i, ret, gpio_num;

//以下工作,每个设备完成一次

for(i = 0; i < GPIO_NUM; ++i)

{

//3.在头文件中找到寄存器的宏定义

gpios[i] = EXYNOS4_GPX3(i+2);

gpio_num = gpios[i];

printk("i = %d, gpios[%d] = %d, num = %d\n", i, i, gpios[i], gpio_num);

//4.申请gpio

ret = gpio_request(gpio_num, "myio");

if(ret)

{

printk("Request failed...%d\n", ret);

for(; i-1 > 0; --i)

gpio_free(gpios[i-1]);

return ret;

}

//5.对io进行配置

s3c_gpio_cfgpin(gpio_num, S3C_GPIO_OUTPUT);

//写入数据,这里是设置默认值

gpio_set_value(gpio_num, 0);

}

//6.注册misc

ret = misc_register(&misc);

if(ret)

for(i = 0; i < GPIO_NUM; ++i)

gpio_free(gpios[i]);

return ret;

}

static void __exit my_exit(void)

{

int i;

misc_deregister(&misc);

for(i = 0; i < GPIO_NUM; ++i)

gpio_free(gpios[i]);

}

module_init(my_init);

module_exit(my_exit);

MODULE_LICENSE("GPL");

MODULE_AUTHOR("ZhangN");

用户态测试程序

/*******************************

* GPIO的用户态测试

* &> test /dev/gpios 0|1|2|3 on|off

* author:zhangn

* date:2016-1-12

*******************************/

#include

#include

#include

#include

#include

#define GPIO_TYPE 'Z'

#define GPIO_ON _IOW(GPIO_TYPE, 1, int)

#define GPIO_OFF _IOW(GPIO_TYPE, 2, int)

int main(int argc, char **argv)

{

int fd;

int gpio_num;

char *endp;

fd = open(argv[1], O_RDWR);

if(fd < 0)

{

printf("Cannot open %s\n", argv[1]);

exit(1);

}

gpio_num = strtol(argv[2], &endp, 10);

if(gpio_num > 3)

{

close(fd);

printf("Only support gpio 0~3\n");

exit(1);

}

printf("arg = %d\n", gpio_num);

if(strncmp(argv[3], "on", 2) == 0)

{

ioctl(fd, GPIO_ON, gpio_num);

}

else if(strncmp(argv[3], "off", 3) == 0)

{

ioctl(fd, GPIO_OFF, gpio_num);

}

else

{

close(fd);

exit(1);

}

close(fd);

exit(0);

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值