查看: 256|回复: 0

【米尔MYD-C8MMX开发板】+ 7、key按键linux驱动程序

[复制链接]

主题

好友

1万

积分

版主

  • TA的每日心情
    开心
    1 分钟前
  • 签到天数: 524 天

    连续签到: 7 天

    [LV.9]以坛为家II

    发表于 2020-6-24 17:21:46 |显示全部楼层
       
        这节来学习下按键输入的linux驱动程序。


        一、硬件电路


        按键使用IO口是GPIO3_IO19。
        1003.png

          1004.png





        二、驱动程序


        2.1、dts文件定义
        设备树文件/MYIR-i.MX8MM-Linux/arch/arm64/boot/dts/freescale/myb-fsl-imx8mm-evk.dts有关按键接口定义
           1001.png

          1002.png
      

         
        2.2、驱动程序


        userkey.c
    1. <font size="3">#include <linux/types.h>
    2. #include <linux/kernel.h>
    3. #include <linux/delay.h>
    4. #include <linux/ide.h>
    5. #include <linux/init.h>
    6. #include <linux/module.h>
    7. #include <linux/errno.h>
    8. #include <linux/gpio.h>
    9. #include <linux/cdev.h>
    10. #include <linux/device.h>
    11. #include <linux/of.h>
    12. #include <linux/of_address.h>
    13. #include <linux/of_gpio.h>
    14. #include <asm/uaccess.h>
    15. #include <asm/io.h>

    16. #define KEY0VAL                                0xF0                 
    17. #define INVAKEY                           0x00

    18. #define KEY_CNT                                1
    19. #define KEY_NAME                        "userkey"                  

    20. struct userkey_dev
    21. {
    22.         dev_t devid;                        
    23.         struct cdev cdev;                 
    24.         struct class *class;         
    25.         struct device *device;
    26.         int major;                                 
    27.         int minor;                                 
    28.         struct device_node        *nd;  
    29.         int key_gpio;               
    30.         atomic_t keyval;         
    31. };

    32. struct userkey_dev userkey;         
    33. //key open
    34. static int key_open(struct inode *inode, struct file *filp)
    35. {
    36.         filp->private_data = &userkey;
    37.         return 0;
    38. }
    39. //key read
    40. static ssize_t key_read(struct file *filp, char __user *buf, size_t cnt, loff_t *offt)
    41. {
    42.         int sta=0;
    43.         unsigned char val;
    44.         struct userkey_dev *dev = filp->private_data;
    45.         {
    46.                 if(gpio_get_value(dev->key_gpio)==0)
    47.                 {
    48.                         while (!gpio_get_value(dev->key_gpio));
    49.                         atomic_set(&dev->keyval, KEY0VAL);
    50.                 }
    51.                 else
    52.                 {
    53.                         atomic_set(&dev->keyval,INVAKEY);
    54.                 }
    55.                 val=atomic_read(&dev->keyval);
    56.                 sta= copy_to_user(buf, &val, sizeof(val));
    57.                 return sta;
    58.         };
    59.         return 0;
    60. }

    61. //fops
    62. static struct file_operations userkey_fops = {
    63.         .owner = THIS_MODULE,
    64.         .open = key_open,
    65.         .read = key_read,
    66. };
    67. //led init
    68. static int __init ourkey_init(void)
    69. {
    70.         int ret = 0;

    71.         atomic_set(&userkey.keyval,INVAKEY);

    72.         userkey.nd = of_find_node_by_path("/gpio-keys/user");
    73.         if(userkey.nd == NULL)
    74.         {
    75.                 printk("userkey node not find!\r\n");
    76.                 return -EINVAL;
    77.         }
    78.         else
    79.         {
    80.                 printk("userkey node find!\r\n");
    81.         }
    82.         
    83.         userkey.key_gpio = of_get_named_gpio(userkey.nd, "gpios", 0);
    84.         if(userkey.key_gpio < 0)
    85.         {
    86.                 printk("can't get usergpio\r\n");
    87.                 return -EINVAL;
    88.         }
    89.         printk("key_gpio=%d\r\n",userkey.key_gpio);

    90.         gpio_request(userkey.key_gpio, "key0");
    91.         ret = gpio_direction_input(userkey.key_gpio);
    92.         if(ret < 0)
    93.         {
    94.                 printk("can't set userkey!\r\n");
    95.         }

    96.         if (userkey.major)
    97.         {               
    98.                 userkey.devid = MKDEV(userkey.major, 0);
    99.                 register_chrdev_region(userkey.devid, KEY_CNT, KEY_NAME);
    100.         }
    101.         else
    102.         {                                                
    103.                 alloc_chrdev_region(&userkey.devid, 0, KEY_CNT, KEY_NAME);        
    104.                 userkey.major = MAJOR(userkey.devid);        
    105.                 userkey.minor = MINOR(userkey.devid);        
    106.         }
    107.         printk("userkey major=%d,minor=%d\r\n",userkey.major, userkey.minor);        
    108.         
    109.         //cdev
    110.         userkey.cdev.owner = THIS_MODULE;
    111.         cdev_init(&userkey.cdev, &userkey_fops);
    112.         cdev_add(&userkey.cdev, userkey.devid, KEY_CNT);
    113.         userkey.class = class_create(THIS_MODULE, KEY_NAME);
    114.         if (IS_ERR(userkey.class))
    115.         {
    116.                 return PTR_ERR(userkey.class);
    117.         }

    118.         userkey.device = device_create(userkey.class, NULL, userkey.devid, NULL, KEY_NAME);
    119.         if (IS_ERR(userkey.device))
    120.         {
    121.                 return PTR_ERR(userkey.device);
    122.         }
    123.         return 0;
    124. }
    125. //led exit
    126. static void __exit ourkey_exit(void)
    127. {
    128.         cdev_del(&userkey.cdev);
    129.         unregister_chrdev_region(userkey.devid, KEY_CNT);  

    130.         device_destroy(userkey.class, userkey.devid);
    131.         class_destroy(userkey.class);
    132. }
    133. module_init(ourkey_init);
    134. module_exit(ourkey_exit);
    135. MODULE_LICENSE("GPL");
    136. MODULE_AUTHOR("author");
    137. </font>
    复制代码
            2.3、Makefile文件   
    1. <font size="3">KERNELDIR :=  /opt/04-Sources/MYIR-i.MX8MM-Linux
    2. CURRENT_PATH := $(shell pwd)

    3. obj-m := userkey.o

    4. build: kernel_modules

    5. kernel_modules:
    6.         $(MAKE) -C $(KERNELDIR) M=$(CURRENT_PATH) modules

    7. clean:
    8.         $(MAKE) -C $(KERNELDIR) M=$(CURRENT_PATH) clean</font>
    复制代码

         2.4、编译程序后


        生成userkey.ko文件
        1005.png

       
        三、应用程序
       
        3.1、userkeyApp.c
       
    1. <font size="3">#include <stdio.h>
    2. #include <unistd.h>
    3. #include <sys/types.h>
    4. #include <sys/stat.h>
    5. #include <fcntl.h>
    6. #include <stdlib.h>
    7. #include <string.h>

    8. #define KEY0VAL         0xf0
    9. #define INVAKEY                0x00

    10. int main(int argc, char *argv[])
    11. {
    12.         int fd, retvalue;
    13.         char *filename;
    14.         unsigned char keyval;
    15.         
    16.         if(argc != 2)
    17.         {
    18.                 printf("Error Usage!\r\n");
    19.                 return -1;
    20.         }

    21.         filename = argv[1];

    22.         fd = open(filename, O_RDWR);
    23.         if(fd < 0)
    24.         {
    25.                 printf("file %s open failed!\r\n", argv[1]);
    26.                 return -1;
    27.         }

    28.         printf("please input key \r\n");
    29.         for(;;)
    30.         {
    31.                 read(fd, &keyval, sizeof(keyval));
    32.                 if(keyval == KEY0VAL)
    33.                 {
    34.                         printf("KEY press, value= %#x\r\n",keyval);
    35.                 }
    36.         }
    37.         
    38.         retvalue = close(fd);
    39.         if(retvalue < 0)
    40.         {
    41.                 printf("file %s close failed!\r\n", argv[1]);
    42.                 return -1;
    43.         }
    44.         return 0;
    45. }
    46. </font>
    复制代码

        3.2、Makefile
       
    1. <font size="3">include ../env.mk
    2. TARGET = userkeyledApp
    3. SRC =  $(TARGET).c
    4. OBJS = $(patsubst %.c ,%.o ,$(SRC))
    5. .PHONY: all
    6. all: $(TARGET)
    7. $(TARGET) : $(OBJS)
    8.         $(CC) -o $@ $^
    9. %.o : %.c
    10.         $(CC) -c [        DISCUZ_CODE_151        ]lt; -o $@
    11. clean:
    12.         $(RM) *.o $(TARGET)</font>
    复制代码


        3.3、编译程序


        编译后生成userkeyApp
        1006.png

       
        四、测试程序


        4.1、将上面编译生成的两个文件拷贝到开发板 /opt目录下,
        执行命令:
        > insmod userkay.ko
        > ./userkeyApp /dev/userkey


        4.2、运行结果


        按下按键一次,打印一帧数据。
        1007.png

       
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    关闭

    站长推荐上一条 /5 下一条



    手机版|电路城

    GMT+8, 2020-7-12 10:01 , Processed in 0.067039 second(s), 13 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz!

    返回顶部