跟着韦东山老师学字符设备驱动之查询方式的按键驱动程序分析
来源:互联网 发布:唐砖精校版txt下载知轩 编辑:程序博客网 时间:2024/04/28 21:07
驱动程序如下:seconddrv.c
#include<linux/module.h>
#include<linux/kernel.h>
#include<linux/fs.h>
#include<linux/init.h>
#include<linux/delay.h>
#include<asm/uaccess.h>
#include<asm/irq.h>
#include<asm/io.h>
#include<linux/device.h> //要是想使用 class_create 和 device_create和 class_destroy 和 device_unregister 需要添加这个头文件
//#include<asm-generic/gpio.h>
#include<mach/regs-gpio.h> //这两个头文件,在lesson3/lesson3.3/linux-ok6410/arch/arm/mach-s3c6400/include/mach目录下存放着。
#include<mach/hardware.h>
volatile unsigned long *gpncon ; //OK6410按键每个管脚占两位,对应的管脚为GPN0~5是 起始地址是0x7F008830
volatile unsigned long *gpndat ; //起始地址,0x7F008834,当按键被按下时,对应的键值为0,平时为高电平。
static struct class *seconddrv_class; //创建一个class 型 的类 ,这里是先定义好
static struct class_device *seconddrv_class_dev;//创建基于上面 类的 设备,这里也是定义
/*程序规划:
在open函数中配置引脚
在read中返回IO值
在init中进行寄存器映射 ,映射之后,要记得在exit函数中 取消映射
*/
static int second_drv_open(struct inode *inode,struct file *file)
{
*gpncon &= ~((0x3<<2*0) | (0x3<<2*1) | (0x3<<2*2) | (0x3<<2*3) | (0x3<<2*4) | (0x3<<2*5)); //配置GPN0~5位输入引脚,用于读取
return 0;
}
ssize_t second_drv_read(struct file *file,char __user *buf,size_t size,loff_t *ppos)
{
/* 返回6个引脚的电平数值 */
unsigned char key_vals[6];
unsigned long regval;
if(size != sizeof(key_vals))
return -EINVAL;
regval = *gpndat;
key_vals[0] = (regval & (1<<0)) ? 1 : 0; //按位与 结果为真时 取值为1 ,为假时取 0
key_vals[1] = (regval & (1<<1)) ? 1 : 0;
key_vals[2] = (regval & (1<<2)) ? 1 : 0;
key_vals[3] = (regval & (1<<3)) ? 1 : 0;
key_vals[4] = (regval & (1<<4)) ? 1 : 0;
key_vals[5] = (regval & (1<<5)) ? 1 : 0;
/*for(i=0;i<6;i++)
{
key_vals[i] = ( regval & (1 << i ) ) ? 1 : 0; //括号内为真时,输出为1,且赋值给 key_vals[i];
}*/
copy_to_user(buf,key_vals,sizeof(key_vals));
return sizeof(key_vals);
}
static ssize_t second_drv_write(struct file *file,const char __user *buf,size_t count,loff_t *ppos)
{
return 0;
}
static struct file_operations second_drv_fops = {
.owner = THIS_MODULE,
.open = second_drv_open,
.read = second_drv_read,
.write = second_drv_write,
}; //结构体中 ,使用的 逗号 “ , ” 而在结束后要加个 分号“ ; ”
int major; // 用于存储自动创建的设备号
static int second_drv_init(void)
{
major = register_chrdev(0,"seconddrv",&second_drv_fops);//注册将open和read和write函数告诉内核,通过cat proc/devices查看
seconddrv_class = class_create(THIS_MODULE,"second_drv");//创建类,类名为 second_drv 通过 cd /sys/class 查看
seconddrv_class_dev = device_create(seconddrv_class,NULL,MKDEV(major,0),NULL,"buttons"); //创建类的设备,设备名为buttons 通过cd /dev/查看
gpncon = (volatile unsigned long *)ioremap(0x7F008830,16); //用函数ioremap进行虚拟地址重映射到物理地址。
gpndat = gpncon + 1; //这里的 +1,是加unsigned long 的大小
return 0;
}
static void second_drv_exit(void)
{
unregister_chrdev(major,"seconddrv"); //卸载
device_unregister(seconddrv_class_dev); //先卸载设备
class_destroy(seconddrv_class); //在删除所创建的 类
iounmap(gpncon);
}
module_init(second_drv_init);
module_exit(second_drv_exit);
MODULE_LICENSE("GPL");
应用程序如下:secondtest.
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<stdio.h>
int main(int argc,char **argv)
{
int fd;
unsigned char key_vals[6];
int cnt = 0;
fd = open("/dev/buttons",O_RDWR); //这里打开的设备名字,/dev/buttons要和 驱动程序中一致。与类的设备名一致,通过 cd /dev查看。
if(fd<0)
printf("can not open file!\n");
while(1)
{
read(fd,key_vals,sizeof(key_vals));
if(!key_vals[0]|| !key_vals[1] || !key_vals[2] || !key_vals[3] || !key_vals[4] || !key_vals[5])
{
printf("%06d key pressed: %d %d %d %d %d %d\n", cnt++, key_vals[0], key_vals[1], key_vals[2], key_vals[3], key_vals[4], key_vals[5]);
}
}
return 0;
}
Makefie程序如下:
obj-m := seconddrv.o //生成的设备文件名
KDIR := /home/S4-ARM/lesson3/lesson3.3/linux-ok6410 //内核所在目录
all:
make -C $(KDIR) M=$(PWD) modules CROSS_COMPILE=arm-linux- ARCH=arm
//make会先进入KDIR目录执行此目录下的Makfefile程序,然后在返回PWD目录下执行自己的Makefile函数,交叉编译工具为arm-linux-。。。后面的值系统会自动的补全。。架构为arm架构
clean:
rm -f *.o *.ko *.order *.symvers
- 跟着韦东山老师学字符设备驱动之查询方式的按键驱动程序分析
- 跟着韦东山老师学习嵌入式----字符设备驱动程序之poll机制
- 字符设备驱动之按键处理一(查询方式的按键驱动程序)
- 字符设备驱动程序之查询方式的按键驱动程序
- 字符设备驱动程序之中断方式的按键驱动
- 第12课第3节 字符设备驱动程序之查询方式的按键驱动程序
- 字符设备驱动程序之按键——查询方式
- 韦东山第12课-字符设备驱动、按键查询、copy_to_user
- 字符设备驱动--查询方式的按键驱动
- JZ2440 usb设备驱动(跟着韦老师学)
- 韦东山第12课-字符设备、中断方式查询驱动
- 字符设备驱动程序之定时器防抖动-韦东山
- Linux设备驱动开发基础---字符设备驱动程序开发之基于中断的按键驱动
- 第12课第4.1节 字符设备驱动程序之中断方式的按键驱动_Linux异常处理结构
- 第12课第4.2节 字符设备驱动程序之中断方式的按键驱动_Linux中断处理结构
- 第12课第4.3节 字符设备驱动程序之中断方式的按键驱动_编写代码
- 字符设备驱动之按键处理二(中断处理的按键驱动程序)
- 嵌入式Linux驱动开发(三)——字符设备驱动之查询的方式获取按键值
- [乡土民间故事_徐苟三传奇]第四四回_赵员外苕吃假香肠
- UESTC Final Pan's prime numbers 1272 (坑)
- [乡土民间故事_徐苟三传奇]第四三回_砍棉梗姚财主认输
- [乡土民间故事_徐苟三传奇]第四五回_吃煨豆老爷“放狗屁”
- PDF 转换成JPG图
- 跟着韦东山老师学字符设备驱动之查询方式的按键驱动程序分析
- Android CardView使用详解
- [乡土民间故事_徐苟三传奇]第四六回_蠢老爷中计打财主
- Fragment常见错误
- QT QTablewidget的一个异常总结
- [乡土民间故事_徐苟三传奇]第四七回_三句半巧骂昏县官
- 常用网络管理操作
- UESTC--1262--Memory(dfs)
- Web请求的背后——计算机网络到底做了哪些事?