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
阅读(797) | 评论(0) | 转发(0) |