这里面我们需要完成用按键去控制一个灯。

我们需要的硬件包括:

按键

1. ENT0 :    GPF0

2. EINT2:    GPF2

3. EINT11:  GPG3

led灯:

LED1:GPF4

LED2: GPF5

LED4: GPF6

思路就是 按下一个按键 则 对应的灯会亮。

那么在程序里面的思路是:

1、测试程序会一直读IO口的状态,当有按键被按下的时候则去判断是哪个按键按下 并且开启指定的灯。

 

 

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/irq.h>
#include <asm/uaccess.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <asm/arch/regs-gpio.h>
#include <asm/hardware.h>
#include <linux/poll.h>


static struct class *forthdrv_class;
static struct class_device    *forthdrv_class_dev;

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

volatile unsigned long *gpgcon = NULL;
volatile unsigned long *gpgdat = NULL;    //this is for key


/*
1. ENT0 :    GPF0

2. EINT2:    GPF2

3. EINT11:  GPG3

led�ƣ�

LED1��GPF4

LED2�� GPF5

LED4�� GPF6

*/


static int forth_drv_open(struct inode *inode, struct file *file)
{
 //  printk("this is the open function\r\n");
  /*
     The task needs to do in open function
     1. initialize lcd and key GPIO
  
  */
   *gpfcon |= (1<<12) | (0x01<<10) | (0x01 << 8);   //this is for led intialization
   *gpfcon &= ~((1<<0) | (1<<1) |(1<<5) | (1<<4) | (1<<7) | (1<<6));  //this is for the key GPIO initialization
   
   *gpgcon &= ~((1<<23) | (1<<22));
   *gpgcon &= ~((1<<7)  | (1<<6));
   return 0;
}

ssize_t  forth_drv_write (struct file *file, const char __user *buf, size_t count, loff_t *ppos)
{/*
   int val;
   copy_from_user(&val, buf, count);

   if(val == 1)
       {
      *gpfdat &= ~((1<<4) | (1<<5) | (1<<6));

    }
   else
       {
        *gpfdat |= (1<<4) | (1<<5) | (1<<6);

    }
    */
  return 0;
}


ssize_t forth_drv_read(struct file *file, char __user *buf, size_t size, loff_t *ppos)
{
    unsigned char key_val[4];
    int regval;

     regval = *gpfdat;
     key_val[0] = (regval & (1<<0)) ? 1 : 0;
     key_val[1] = (regval & (1<<2)) ? 1 : 0;

     regval = *gpgdat;
     key_val[2] = (regval & (1<<3)) ? 1 : 0;
     key_val[3] = (regval & (1<<11)) ? 1 : 0;

     copy_to_user(buf, key_val, sizeof(key_val));

     

//    printk("this is the read function\r\n");
    
    
    return sizeof(key_val);
}







static struct file_operations sencod_drv_fops = {
    .owner   =  THIS_MODULE,    /* ����һ���꣬�������ģ��ʱ�Զ�������__this_module���� */
    .open    =  forth_drv_open,     
    .read     =    forth_drv_read,       //�������� ���Ƕ���������ֵ֮�� ������Ҫ����һ��д�ĺ�����֪ͨ�ں˿��ƵƵ�����
    .write   =  forth_drv_write,  //�������� ������Ҫд��֪ͨ������ĺ�����
    
};


int major;
static int forth_drv_init(void)
{
    major = register_chrdev(0, "forth_drv", &sencod_drv_fops);   //注册一个设备

    forthdrv_class = class_create(THIS_MODULE, "forth_drv");     //生成一个class类型

    forthdrv_class_dev = class_device_create(forthdrv_class, NULL, MKDEV(major, 0), NULL, "buttons"); /* /dev/buttons */
    /*把这个class类型创建出来 并且给一个主设备号*/
    
       /*initialize the GPIO pin here */
    gpfcon = ioremap(0x56000050, 16);    //remap the IO address to virsual linux address
    gpfdat = gpfcon + 1;

    gpgcon = ioremap(0x56000060, 16);    //this is for key
    gpgdat = gpgcon + 1;
    
    return 0;
}

static void forth_drv_exit(void)
{
    unregister_chrdev(major, "forth_drv");
    iounmap(gpfcon);
    iounmap(gpgcon);
    class_destroy(forthdrv_class);
    
}


module_init(forth_drv_init);

module_exit(forth_drv_exit);

MODULE_LICENSE("GPL");

首先我们来看这个程序,我们是从read函数中读取的所有的按键的状态,其中这个read函数就是对应到我们APP的read函数中的。

我们在read中进行了多按键的读取,其中函数

copy_to_user(buf, key_val, sizeof(key_val));是把数据从内核中读出 然后给到APP里面来。
我们的测试程序如下:
 #include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <unistd.h>
#include <fcntl.h>



/*
1. ENT0 :    GPF0

2. EINT2:    GPF2

3. EINT11:  GPG3

4. EINT19:  GPG11

led�ƣ�

LED1��GPF4

LED2�� GPF5

LED4�� GPF6

*/


int fd;
int val;
unsigned char key_val[4] = {0};
int main(int argc, char **argv)
{
    int flags;
    fd = open("/dev/buttons", O_RDWR);
    if (fd < 0)
    {
        printf("can't open!\n");
        return -1;
    }
    while(1)
    {
     read(fd,key_val, sizeof(key_val));
     if(!key_val[0] || !key_val[1] || !key_val[2] || !key_val[3])
         {

          printf("GPF0 = %d, GPF1= %d, GPF3= %d\n  GPG11= %d", key_val[0], key_val[1], key_val[2], key_val[3]);

        }



    }
    return 0;
    
}

 

不过这种情况情况下 我们的程序占用CPU太多,因为是不断的查询

 

 所以 我们需要用中断的方式来重新处理这个函数

posted on 2020-12-27 09:52  闲云潭影  阅读(314)  评论(0编辑  收藏  举报