跟着韦东山老师学字符设备驱动之查询方式的按键驱动程序分析

来源:互联网 发布:唐砖精校版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







1 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 a2驾照扣10分怎么办 驾驶证强制降级没给驾驶证怎么办 6P升11.2卡了怎么办 b2驾照记满12分怎么办 c1驾驶证没分了怎么办 驾照扣了15分怎么办 驾驶证暂扣六个月后怎么办 醉驾交警不通知怎么办 参军后地方驾驶证年审怎么办 军人驾驶证到期身份证注销了怎么办 资格证脱审30天怎么办 驾驶证c证扣6分怎么办 驾照被扣了9分怎么办 驾驶证被扣了9分怎么办 a2驾驶本扣3分怎么办 c1e没过扣了满分怎么办 c1一下扣12分怎么办 换证体检过不了怎么办 唐山驾驶本到期换本怎么办 北京居住证变更地址了怎么办 眼睛弱视驾驶证换证不了怎么办? 驾照的分扣完了怎么办 驾照被扣了3分怎么办 交警扣了行驶证怎么办 报考驾照时手机号录错怎么办 摩托车被交警队拖走怎么办 汽车牌照被偷了怎么办 代理品牌个体工商营业证怎么办 2地交社保怎么办退休 驾驶证脱审3月怎么办 a1一次性扣12分怎么办 驾照在外地掉了怎么办 在外市考的驾照怎么办 驾照过期3个月怎么办 驾照过期6个月怎么办 b本扣分了6分怎么办 b2驾照提前换证有扣分怎么办 酒驾驾驶证被扣怎么办 驾驶证被扣了分怎么办 c1驾照扣了12分怎么办 结婚证丢了怎么办离婚手续