嵌入式系统学习(九)-用过内核驱动操作GPIO
2016-10-01 22:40
441 查看
在本文中,采用传统的编写驱动函数的方法来实现按键驱动程序.
采用内核函数变成的方式,首先我们需要编写一个内核驱动函数,如针对按钮:key_kernel.c,源代码如下:
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/gpio.h>
#include <linux/miscdevice.h>
#include <linux/fs.h>
#include <linux/moduleparam.h>
#include <linux/slab.h>
#include <linux/cdev.h>
#include <linux/delay.h>
#include <linux/compat.h>
#include <linux/spi/spi.h>
#include <linux/spi/spidev.h>
#include <mach/platform.h>
#include <mach/devices.h>
#define OUTPUT 1
#define INPUT 0
#define HIGH 1
#define LOW 0
#define SET_VALUE 123
unsigned int GPIOC7 = PAD_GPIO_C + 7;
#define DEVICE_NAME "gpio"
static int gpio_open(struct inode *inode, struct file *file)
{
gpio_request(GPIOC7, "test");
gpio_direction_output(GPIOC7, 1);
printk("request GPIOC7\n");
return 0;
}
static int gpio_close(struct inode *inode, struct file *file)
{
printk("gpio_set_value LOW\n");
gpio_free(GPIOC7);
return 0;
}
static long gpio_key(struct file *file, unsigned int cmd)
{
if(cmd == SET_VALUE){
int ret=gpio_get_value(GPIOC7);
printk("%d\n",ret);
}
return -EMSGSIZE;
}
static struct file_operations gpio_fops = {
.owner = THIS_MODULE,
.open = gpio_open,
.release = gpio_close,
.unlocked_ioctl = gpio_key,
};
static struct miscdevice gpio_dev = {
.minor= MISC_DYNAMIC_MINOR,
.name= DEVICE_NAME,
.fops= &gpio_fops,
};
volatile unsigned * GPIOCOUT;
static int gpio_init(void){
int ret = 0;
printk("init\n");
ret = misc_register(&gpio_dev);
return ret;
}
static void gpio_exit(void){
misc_deregister(&gpio_dev);
printk("exit\n");
}
module_init(gpio_init);
module_exit(gpio_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("LML");
编写针对此函数的Makefile文件(要指定相应的linux内核):
obj-m:=key_kernel.o
mymodule-objs:=key_kernel
KDIR:=/home/sf_NanoPi2/linux-3.4.y/
MAKE:=make
# EXTRA_CFLAGS += -I$(KDIR)arch/arm/mach-s5p4418/prototype/module
default:
$(MAKE) -C $(KDIR) M=$(PWD) modules
clean:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) clean
编译内核模块,得到key_kernel.ko,并将它拷贝到Nanopi2中,安装内核模块:
这里如果安装失败,提示内核版本不对的话,要去linux-3.4.y中编译内核,并且将得到的arch/arm/boot/uImage 替换掉Nanopi的boot区的uImage.hdmi,具体如下:
如果没有报错则忽略此步骤。
接下来要写一个应用程序来调用KEY的内核函数:key_app.c
在nanopi上编译并执行,如下:
执行结果如下:
按下按钮显示0,放开按钮显示1,测试完后最好rmmod key_kernel.ko,
采用内核函数变成的方式,首先我们需要编写一个内核驱动函数,如针对按钮:key_kernel.c,源代码如下:
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/gpio.h>
#include <linux/miscdevice.h>
#include <linux/fs.h>
#include <linux/moduleparam.h>
#include <linux/slab.h>
#include <linux/cdev.h>
#include <linux/delay.h>
#include <linux/compat.h>
#include <linux/spi/spi.h>
#include <linux/spi/spidev.h>
#include <mach/platform.h>
#include <mach/devices.h>
#define OUTPUT 1
#define INPUT 0
#define HIGH 1
#define LOW 0
#define SET_VALUE 123
unsigned int GPIOC7 = PAD_GPIO_C + 7;
#define DEVICE_NAME "gpio"
static int gpio_open(struct inode *inode, struct file *file)
{
gpio_request(GPIOC7, "test");
gpio_direction_output(GPIOC7, 1);
printk("request GPIOC7\n");
return 0;
}
static int gpio_close(struct inode *inode, struct file *file)
{
printk("gpio_set_value LOW\n");
gpio_free(GPIOC7);
return 0;
}
static long gpio_key(struct file *file, unsigned int cmd)
{
if(cmd == SET_VALUE){
int ret=gpio_get_value(GPIOC7);
printk("%d\n",ret);
}
return -EMSGSIZE;
}
static struct file_operations gpio_fops = {
.owner = THIS_MODULE,
.open = gpio_open,
.release = gpio_close,
.unlocked_ioctl = gpio_key,
};
static struct miscdevice gpio_dev = {
.minor= MISC_DYNAMIC_MINOR,
.name= DEVICE_NAME,
.fops= &gpio_fops,
};
volatile unsigned * GPIOCOUT;
static int gpio_init(void){
int ret = 0;
printk("init\n");
ret = misc_register(&gpio_dev);
return ret;
}
static void gpio_exit(void){
misc_deregister(&gpio_dev);
printk("exit\n");
}
module_init(gpio_init);
module_exit(gpio_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("LML");
编写针对此函数的Makefile文件(要指定相应的linux内核):
obj-m:=key_kernel.o
mymodule-objs:=key_kernel
KDIR:=/home/sf_NanoPi2/linux-3.4.y/
MAKE:=make
# EXTRA_CFLAGS += -I$(KDIR)arch/arm/mach-s5p4418/prototype/module
default:
$(MAKE) -C $(KDIR) M=$(PWD) modules
clean:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) clean
编译内核模块,得到key_kernel.ko,并将它拷贝到Nanopi2中,安装内核模块:
这里如果安装失败,提示内核版本不对的话,要去linux-3.4.y中编译内核,并且将得到的arch/arm/boot/uImage 替换掉Nanopi的boot区的uImage.hdmi,具体如下:
如果没有报错则忽略此步骤。
接下来要写一个应用程序来调用KEY的内核函数:key_app.c
在nanopi上编译并执行,如下:
执行结果如下:
按下按钮显示0,放开按钮显示1,测试完后最好rmmod key_kernel.ko,
相关文章推荐
- 嵌入式系统学习(八)-通过sysfs(/sys/class/gpio)操作GPIO
- 嵌入式系统学习(十)-通过直接配置寄存器操作GPIO
- 内核驱动进阶班-2-1(嵌入式linux系统架构)
- 【嵌入式Linux学习七步曲之第五篇 Linux内核及驱动编程】Linux系统调用的实现机制分析
- 嵌入式学习从基础到高级概述+书籍推荐(内核驱动方向)
- 嵌入式Linux驱动学习之路(一)嵌入式系统的软硬件架构
- 移植驱动到内核学习笔记3-----LCD及输入系统
- 【嵌入式Linux学习七步曲之第五篇 Linux内核及驱动编程】Linux系统调用的实现机制分析
- 嵌入式Linux系统中对GPIO操作的方法总结
- 嵌入式学习-linux系统-lesson2-内核相关
- Linux内核与驱动开发学习总结:嵌入式中南北桥(三)
- 【嵌入式Linux学习七步曲之第五篇 Linux内核及驱动编程】详解Linux内核之双向循环链表
- 【嵌入式Linux学习七步曲之第四篇 Linux内核移植】详解Linux2.6内核中基于platform机制的驱动模型
- linux内核驱动的学习第一天——linux系统的结构
- 【嵌入式Linux学习七步曲之第五篇 Linux内核及驱动编程】揭开Linux Proc文件系统的神秘面纱
- linux 内核驱动加载过程中 向文件系统中的文件进行读写操作
- 【嵌入式Linux学习七步曲之第五篇 Linux内核及驱动编程】Oops在Linux 2.6内核+PowerPC架构下的前世今生
- 【嵌入式Linux学习七步曲之第五篇 Linux内核及驱动编程】全面解析Linux内核的同步与互斥机制--互斥篇
- linux驱动学习--第七天:第五章 Linux 文件系统与设备文件系统 之 linux文件操作
- 嵌入式Linux编译系统的设计——Bootloader, 内核,驱动,文件系统,升级镜像等自动化编译打包