加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Linux > 正文

Linux 驱动——Button驱动1

发布时间:2020-12-14 02:03:47 所属栏目:Linux 来源:网络整理
导读: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

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,courier; font-size: 18px;">   .read = button_drv_read,courier; font-size: 18px;">};

?

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),DEVICE_NAME);

?

  gpfcon = (volatile unsigned long *)ioremap(0x56000050,16);
  gpfdat = gpfcon + 1;
  gpgcon = (volatile unsigned long *)ioremap(0x56000060,courier; font-size: 18px;">   gpgdat = gpgcon + 1;
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,courier; font-size: 18px;">     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]);
    }
  }

}

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读