button_drv.c驱动文件:

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <asm/io.h>           //包含iomap函数iounmap函数
#include <asm/uaccess.h>         //包含copy_from_user函数
#include <linux/device.h>        //包含class类相关的处理函数
#include <linux/fs.h>           //包含file_operations结构体

#define DRIVER_NAME "button_drv"
#define DEVICE_NAME "button_dev"

int major;

static struct class *buttondrv_class;
static struct class_device *buttondrv_class_dev;

volatile unsigned long *gpfcon = NULL;
volatile unsigned long *gpfdat = NULL;
volatile unsigned long *gpgcon = NULL;
volatile unsigned long *gpgdat = NULL;

static int button_drv_open(struct inode *inode, struct file *file)
{
  *gpfcon &= ~((0x3<<(0*2)) | (0x3<<(2*2)));
  *gpgcon &= ~((0x3<<(3*2)) | (0x3<<(11*2)));
  return 0;
}

static int button_drv_read(struct file * file, char __user * userbuf, size_t count, loff_t * off)
{
  int ret;
  unsigned char keyVal[4];
  unsigned long keyVals;

  if(count!=sizeof(keyVal))
  {
    printk("button_drv_read error 1 \n");
  }

  keyVals = *gpfdat;
  keyVal[0] = ((keyVals>>0) & 1);
  keyVal[1] = ((keyVals>>2) & 1);
  keyVals = *gpgdat;
  keyVal[2] = ((keyVals>>3) & 1);
  keyVal[3] = ((keyVals>>11) & 1);
  
  ret = copy_to_user(userbuf, keyVal, sizeof(keyVal));
  if(ret<0)
  {
    printk("button_drv_read error 2 \n");
  }

  return sizeof(keyVal);
}

static struct file_operations button_drv_fops = {
  .owner = THIS_MODULE,
  .open = button_drv_open,
  .read = button_drv_read,
};

static int button_drv_init(void)
{
  major = register_chrdev(0, DRIVER_NAME, &button_drv_fops);

  buttondrv_class = class_create(THIS_MODULE, DEVICE_NAME);
  buttondrv_class_dev = class_device_create(buttondrv_class, NULL, MKDEV(major, 0), NULL, DEVICE_NAME);

  gpfcon = (volatile unsigned long *)ioremap(0x56000050, 16);
  gpfdat = gpfcon + 1;
  gpgcon = (volatile unsigned long *)ioremap(0x56000060, 16);
  gpgdat = gpgcon + 1;
  return 0;
}

static void button_drv_exit(void)
{
  unregister_chrdev(major, DRIVER_NAME);
  class_device_unregister(buttondrv_class_dev);
  class_destroy(buttondrv_class);
  iounmap(gpfcon);
  iounmap(gpgcon);
}

module_init(button_drv_init);
module_exit(button_drv_exit);

MODULE_LICENSE("GPL");

Makefile文件:

obj-m += button_drv.o

KERN_DIR = /work/system/linux-2.6.22.6

all:
make -C $(KERN_DIR) M=`pwd` modules
clean:
rm -rf *.o *.ko *.order *.symvers *.mod.c

button_app.c文件:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>

int main(int argc, char **argv)
{
  int fd;
  int val;
  char *filename;
  unsigned char keyVal[4];

  filename = argv[1];
  fd = open(filename, O_RDWR);
  if(fd<0)
  {
    printf("can not open \n");
  }

  while(1)
  {
    read(fd, keyVal, sizeof(keyVal));
    if(!keyVal[0] || !keyVal[1] || !keyVal[2] || !keyVal[3])
    {
      printf("key pressed %d %d %d %d \n", keyVal[0], keyVal[1], keyVal[2], keyVal[3]);
    }
  }

  return 0;
}

编译生成button_drv.ko文件和button_app文件,运行:./button_app /dev/button_dev

Linux 驱动——Button驱动1的更多相关文章

  1. Linux 驱动——Button驱动7(Timer)消抖

    button_drv.c驱动文件: #include <linux/module.h>#include <linux/kernel.h>#include <linux/f ...

  2. Linux 驱动——Button驱动6(mutex、NBLOCK、O_NONBLOCK)互斥信号量、阻塞、非阻塞

    button_drv.c驱动文件: #include <linux/module.h>#include <linux/kernel.h>#include <linux/f ...

  3. Linux 驱动——Button驱动5(atomic)原子量

    button_drv.c驱动文件: #include <linux/module.h>#include <linux/kernel.h>#include <linux/f ...

  4. Linux 驱动——Button驱动4(fasync)异步通知

    button_drv.c驱动文件: #include <linux/module.h>#include <linux/kernel.h>#include <linux/f ...

  5. Linux 驱动——Button驱动3(poll机制)

    button_drv.c驱动文件: #include <linux/module.h>#include <linux/kernel.h>#include <linux/f ...

  6. Linux 驱动——Button驱动2

    button_drv.c驱动文件: #include <linux/module.h>#include <linux/kernel.h>#include <linux/f ...

  7. Linux GPIO键盘驱动开发记录_OMAPL138

    Linux GPIO键盘驱动开发记录_OMAPL138 Linux基本配置完毕了,这几天开始着手Linux驱动的开发,从一个最简单的键盘驱动开始,逐步的了解开发驱动的过程有哪些.看了一下Linux3. ...

  8. linux块设备驱动之实例

    1.注册:向内核注册个块设备驱动,其实就是用主设备号告诉内核这个代表块设备驱动 sbull_major  =  register_blkdev(sbull_major, "sbull&quo ...

  9. Linux 视频设备驱动V4L2最常用的控制命令

    http://blog.csdn.net/shaolyh/article/details/6583226 Linux 视频设备驱动V4L2最常用的控制命令使用说明(1.02) 命令 功能 VIDIOC ...

随机推荐

  1. CF #552(div3)F 背包问题

    题目链接:http://codeforces.com/contest/1154/problem/F 题意:一个商店有n个物品,每个物品只能买一次,同时有m种优惠,即一次买够x件后,这x件中最便宜的k件 ...

  2. Apache 如何设置默认首页文档?

    在你安装后的Apache目录下,有一个conf目录,在这个目录里,有一个"httpd.conf"文件.我们要做的,就是修改这个文件. 在这个文件里,凡是以"#" ...

  3. Vue2全家桶之二:vue-router(路由)详细教程,看这个就够了

     作者:东西里本文转载于:https://www.jianshu.com/p/514c7588e877来源:简书 转载仅供自己日后看方便.  由于Vue在开发时对路由支持的不足,于是官方补充了vue- ...

  4. HCharts随笔之简单入门

    此处可以对比我的另一个Echars简单入门 直接上源码 <!DOCTYPE html> <html> <head> <meta http-equiv=&quo ...

  5. vbs中对excel的常用操作

    使用QTP自动化测试中,用到对excel的读写操作,这里把一些常用对excel操作的方法进行了归纳,总结.(对excel格式设置的常用操作这里没有进行总结.) Function DataToExcel ...

  6. 收藏的博客 -- Qt/C++学习

    Qt Creator环境: 使用Qt Creator作为Linux IDE,代替Vim:实现两台Linux电脑远程部署和调试(一台电脑有桌面系统,一台电脑无桌面系统) 使用Qt Creator作为Li ...

  7. 遇到的有关iframe的滚动条问题

    今天才发现一个简单有趣的问题,有关iframe的: <div style="height: 800px;overflow: auto;"> <iframe src ...

  8. 在电脑端同时安装Python2,Python3

    参考文档:http://www.cnblogs.com/zhengyihan1216/p/6011640.html 重点: 1.安装路径最好在一起,方便管理 2.安装路径下不建议有空格 3.Pytho ...

  9. As The End of The Year Approaches,The Weighted Blanket Season Begins

    Weight blankets are well known for anxiety, insomnia, depression and so on. It is physical therapy, ...

  10. Spring-----入门

    Spring 入门 一.首先导入核心jar包 commons-logging-1.1.3.jar                 日志        spring-beans-4.2.4.RELEAS ...