编写LED混杂设备驱动:静态映射,如何用Linux内核里的gpio_request(),gpio_set_value()等函数,ioctl函数

来源:互联网 发布:神经网络算法分类 编辑:程序博客网 时间:2024/06/02 02:32


如何用Linux内核里的gpio_request(),gpio_set_value()等函数编写LED驱动

        

步骤一:打开Linux内核源代码里的Documentation文件夹下的gpio.txt文档

文档里介绍了要用到的头文件和gpio函数介绍,用到的头文件是

#include <linux/gpio.h>

步骤二:打开Linux sourceindight工程搜索gpio.h,打开Linux目录下的那个里面是gpio函数的介绍,还有要包含的头文件,头文件里是gpio引脚号的定义

#include<asm/gpio.h>

 找到arch/arm/include/asm/gpio.h,里面需要包含的头文件是

#include<mach/gpio.h>这个头文件和具体的平台有关,这里我们以S5PC100平台为例

linux/arch/arm/mach-s5pc100/include/mach/gpio.h

 

按键驱动程序设计

 

/*********************************混杂设备驱动:miscdevice*majior=10;** *****************************//********************************/转载请注明原文地址:http://blog.csdn.net/oyhb_1992/article/details/77227276#include <linux/kernel.h>#include <linux/module.h>#include <linux/fs.h>#include <linux/types.h>#include <linux/init.h>//#include <linux/moduleparam.h>//#include <linux/slab.h>//kcalloc,kzalloc等内存分配函数//---------ioctl------------#include <linux/ioctl.h>//---------misc_register----#include <linux/miscdevice.h>//----------cdev--------------#include <linux/cdev.h>//----------delay-------------#include <linux/delay.h>//----------GPIO---------------#include <mach/gpio.h>#include <mach/regs-gpio.h>#include <plat/gpio-cfg.h>#define MISC_DYNAMIC_MINOR 0#define DEVICE_NAME "leds"//静态映射的管脚虚拟地址static int led_gpios[] = {S5PV210_MP04(4),S5PV210_MP04(5),S5PV210_MP04(6),S5PV210_MP04(7),};//4个LED#define LED_NUM        ARRAY_SIZE(led_gpios)static long fl210_leds_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)    //第二个参数是命令号,第三个参数是附加参数{switch(cmd) {case 0:     //命令码:如果写规范格式如:#define LED2_OFF _IOR(‘L’,0,unsigned char) case 1:     //命令码:如果写规范格式如:#define LED2_ON _IOR(‘L’,1,unsigned char) 也可以把命令码放在一个头文件里,应用和驱动都包含它if (arg > LED_NUM) {return -EINVAL;}gpio_set_value(led_gpios[arg], !cmd);//根据cmd设置LED的暗灭printk(DEVICE_NAME": %ld %d\n", arg, cmd);break;default:return -EINVAL;}return 0;}static struct file_operations fl210_led_dev_fops = {.owner            = THIS_MODULE,.unlocked_ioctl    = fl210_leds_ioctl,};//----------------miscdevice------------------static struct miscdevice fl210_led_dev = {.minor            = MISC_DYNAMIC_MINOR,.name            = DEVICE_NAME,.fops            = &fl210_led_dev_fops,};//--------------------------------------------static int __init fl210_led_dev_init(void) {int ret;int i;//申请gpio,只有在gpio_request后才可以调用gpio_set_value,gpio_get_value等函数for (i = 0; i < LED_NUM; i++) {ret = gpio_request(led_gpios[i], "LED");//申请GPIO口if (ret) {printk("%s: request GPIO %d for LED failed, ret = %d\n", DEVICE_NAME,led_gpios[i], ret);return ret;}s3c_gpio_cfgpin(led_gpios[i], S3C_GPIO_OUTPUT);//设置GPIO口为输出//也可以用函数gpio_direction_output(unsigned gpio, int value);gpio_set_value(led_gpios[i], 1);//初始化GPIO口的值}ret = misc_register(&fl210_led_dev);//注册混杂设备printk(DEVICE_NAME"\tinitialized\n");printk("led num is: %d\n",LED_NUM);return ret;}static void __exit fl210_led_dev_exit(void) {int i;for (i = 0; i < LED_NUM; i++) {gpio_free(led_gpios[i]);//释放GPIO口}misc_deregister(&fl210_led_dev);//注销设备}module_init(fl210_led_dev_init);module_exit(fl210_led_dev_exit);MODULE_LICENSE("GPL");MODULE_AUTHOR("");按键应用程序设计#include <stdio.h>//#include "sys/types.h"#include <sys/ioctl.h>#include <stdlib.h>#include <unistd.h>//read,write等等//#include "termios.h"//#include "sys/stat.h"#include <fcntl.h>#define LED2_ON 0x1    //命令码:如果写规范格式如:#define LED2_ON _IOR(‘L’,0,unsigned char)#define LED2_OFF 0x0    //命令码:如果写规范格式如:#define LED2_OFF _IOR(‘L’,1,unsigned char)main(int argc,char *argv[]){int fd;if ((fd=open("/dev/leds",O_RDWR /*| O_NDELAY | O_NOCTTY*/)) < 0){printf("Open Device  failed.\r\n");exit(1);}else{printf("Open Device  successed.\r\n");}if (argc<3){/* code */printf("Usage: %s <on|off num>\n",argv[0]);exit(1);}if(!strcmp(argv[1],"on"))//命令号为1{printf("led1 will on!!\n");if(ioctl(fd,LED2_ON,atoi(argv[2]))<0)//命令附加参数是atoi(argv[2]){printf("ioctl err!!\n");     }}if(!strcmp(argv[1],"off")){printf("led1 will off!!\n");if(ioctl(fd,LED2_OFF,atoi(argv[2]))<0){printf("ioctl err!!\n");}}close(fd);}/*应用层里ioctl函数的原型是:*#man ioctl *int ioctl(int d, int request, ...)*内核驱动源码里ioctl函数的原型是:*long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);*可以知道虽然应用层是可变参数...,但是实际上应用层和驱动层的ioctl函数是对应的,*所以我们知道,虽然应用层是用...,表示ioctl参数,但是我们应该明白*应用层的ioctl函数的参数最多只能有3个*/

 

 

 

 

 

 

 

 

 

 

 

 

 

 


阅读全文
0 0