Chinaunix首页 | 论坛 | 博客
  • 博客访问: 216617
  • 博文数量: 88
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 555
  • 用 户 组: 普通用户
  • 注册时间: 2013-09-03 13:08
个人简介

失意高调,得意低调

文章分类

全部博文(88)

文章存档

2021年(3)

2020年(2)

2018年(2)

2017年(3)

2016年(6)

2015年(19)

2014年(32)

2013年(21)

我的朋友

分类: LINUX

2014-01-14 18:35:51

GPIO的驱动,结合网上资料,终于实现了。
第一个驱动,MART下 20140114



先介绍一下文件结构:


驱动部分:


gpio_3715.c


Makefile (在内核外部编译,所以需要Makefile,指定内核路径信息)


make.sh (自己写的make执行命令,主要是执行命令的时候输入平台信息和工具链信息)


APP部分:


app_3715_gpio.c
测试程序,每3秒gpio10电平变换一次,死循环


Makefile  (指定编译器,生成可执行程序)


驱动实现功能:


实现gpio10引脚的输出功能,可控制。应用测试程序中做具体控制。


以下是文件内容:


—————————————————————————————————————————————————————————————————————————————


//gpio_3715.c(驱动文件)


#include
#include
#include
#include
#define GPIO_MAJOR 251  //?????????????????  主设备号的用法,可能和其它设备冲突么
#define DEVICE_NAME "gpio_3715"
//---------------------------------------------------------------------------------------------------------------
static int gpio_open(struct inode *inode,struct file *file)
{
        printk("gpio 3715 open successfully !\n");
        return 0;
}
//-----------------------------------------------------------------------------------------------------------------
static int gpio_close(struct inode *inode,struct file *file)
{
gpio_free(10);
        printk("gpio 3715 release successfully !\n");
return 0;
}
//---------------------------------------------------------------------------------------------------------------
//??????????????  读取io电平
static ssize_t  gpio_read(struct file *file,char __user *buf, size_t count,loff_t *offset)
{




                int i;
                i = gpio_get_value(10);
//                if(1 == i)
//                        copy_to_user("HIGH",buf,sizeof(buf));
//                else
//                        copy_to_user("LOW",buf,sizeof(buf));
                *buf = i;   //????  自己修改 能否成功
                return 0;
}
//------------------------------------------------------------------------------------------------------------------
static int gpio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
int ret = -1;


ret = gpio_request(10,"enable gpio10");            //?????? enable gpio10 is what
//request gpio 10


printk("request back code is %d\n",ret);




ret = -1 ;
        ret = gpio_direction_output(10,1);
printk("output set back code is %d\n",ret);
        
switch(cmd)
        {
                case 0:
                        printk("success0\n");
                        gpio_set_value(10,0);
                        return 0;
                case 1:
                        printk("success1\n");
                        gpio_set_value(10,1);
                        return 0;
                default:
                        printk("No operations!\n");
                        return -1;
        }
}




//-----------------------------------------------------------------------------------------------------------------
static const struct file_operations gpio_ops = {
        .owner = THIS_MODULE,
        .open = gpio_open,
        .read = gpio_read,
.unlocked_ioctl = gpio_ioctl, 
.release = gpio_close,
};
//--------------------------------------------------------------------------------------------------------------
static struct cdev omap3715_gpio_cdev;


static struct dev_t dev;


static int __init omap3gpio_init(void)
{
//dev_t dev;
        int ret = 0;
//unsigned int reg_data;
//unsigned int *core_addr ;




printk("Registering GPIO_3715 Device...\n------>\n");




//core_addr = ioremap(0x48002A18,4);                    //????????????????????  映射虚拟地址




//__raw_writel(0x00040000,core_addr);                   //????????????????????  设置寄存器的值




gpio_request(10, "enable gpio10");
gpio_direction_output(10, 0);
gpio_set_value(10, 1);


//dev = 0 ;
//dev = MKDEV(GPIO_MAJOR,0);                             //????????????????????






        //ret = register_chrdev_region(dev,1,DEVICE_NAME);     //????????????????????           
        ret = alloc_chrdev_region(&dev,0,1,DEVICE_NAME);
        
        if(ret)
        {
                printk(KERN_WARNING"gpio register_chrdev faild\n");
                return ret;
        }




        printk(KERN_WARNING"gpio register_chrdev success\n");


cdev_init(&omap3715_gpio_cdev,&gpio_ops);              //????????????????????
omap3715_gpio_cdev.ops = &gpio_ops ;
omap3715_gpio_cdev.owner = THIS_MODULE ;




ret = cdev_add(&omap3715_gpio_cdev,dev,1);             //????????????????????


printk("gpio_3715 is installed ! \n");
        return 0;
}
//---------------------------------------------------------------------------------------------------------------------
static void __exit omap3gpio_exit(void) 
{
//unregister_chrdev_region(MKDEV(GPIO_MAJOR,0),1);
unregister_chrdev_region(dev,1);
cdev_del(&omap3715_gpio_cdev);
printk("you have uninstalled the gpio_3715 .\n");
}        




module_init(omap3gpio_init);
module_exit(omap3gpio_exit);
//MODULE_AUTHOR("Seed txyugood");
//MODULE_DESCRIPTION("omap3gpio  driver");
MODULE_LICENSE("GPL");
____________________________________________________________________________________________________________________________________


// Makefile(驱动部分)


KERNELDIR = /3715/linux/source/linux-03.00.01.06/
PWD := $(shell pwd) 
all:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules      




obj-m := gpio_3715.o




clean:
rm -rf *.o *.order *.mod.* *.symvers 
distclean:
rm -rf *.o *.ko *.order *.mod.* *.symvers


—————————————————————————————————————————————————————————————————————————————


// make.sh(驱动部分编译命令脚本)


#!/bin/bash
make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi-
make clean


—————————————————————————————————————————————————————————————————————————————


//app_3715_gpio.c (测试程序)


#include
#include
#include
#include
#include
#include
#include
#include
#define IOCLEAR  0
#define IOWRITE 1
#define NOKEY 0
int main(int argc, char *argv[])
{
int i, fd; 
printf("\nstart  gpio_3715 test\n\n");




fd = open("/dev/gpio_3715", O_RDWR);
printf("fd = %d\n",fd);




if(fd==-1)
{
        printf("can not open gpio_3715 device\n");
}  
else
{
        while(1)
        { 
            ioctl(fd,0);
    sleep(3);
            ioctl(fd,1);      
  sleep(3);
        }
      }


close(fd);


return 0;
}


—————————————————————————————————————————————————————————————————————————————


// Makefile (应用程序)


#CC = /usr/local/arm/4.2.2-eabi/usr/bin/arm-linux-gcc
CC = arm-none-linux-gnueabi-gcc
#CFLAGS= -I/home/urbetter-linux2.6.28-v1.0/kernel/include -Wall
#CFLAGS= -I/home/fang/linux/linux_kernel/linux2.6.28/kernel/urbetter-linux2.6.28-v1.0/include -Wall
CFLAGS= -I/3715/linux/source/linux-03.00.01.06/include -Wall
app_3715_gpio:app_3715_gpio.c
$(CC) -o app_3715_gpio app_3715_gpio.c
clean:
rm -f *.o app_3715_gpio


—————————————————————————————————————————————————————————————————————————————


编译好驱动和应用程序后,分别得到gpio_3715.ko和app_3713_gpio ,


(1) 将gpio_3715.ko利用insmod命令加载进内核:


insmod gpio_3715.ko


如果加载成功,会提示成功信息。


查看设备ID


cat /proc/devices


(2) 创建设备


mknod gpio_3715 c ID 0


(3) 改变应用程序权限并执行


chmod 777 app-3715_gpio  


./app-3715_gpio
阅读(740) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~