51Testing软件测试论坛

 找回密码
 (注-册)加入51Testing

QQ登录

只需一步,快速开始

微信登录,快人一步

手机号码,快捷登录

查看: 1213|回复: 0
打印 上一主题 下一主题

[转贴] Linux 驱动开发:中断测试示例 --- 两个测试按键示例

[复制链接]
  • TA的每日心情
    擦汗
    半小时前
  • 签到天数: 533 天

    连续签到: 3 天

    [LV.9]测试副司令

    跳转到指定楼层
    1#
    发表于 2019-1-8 17:35:38 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

    示例一:
    1、驱动代码

    1. #include <linux/module.h>
    2. #include <linux/kernel.h>
    3. #include <linux/fs.h>
    4. #include <linux/init.h>
    5. #include <linux/delay.h>
    6. #include <linux/platform_device.h>
    7. #include <linux/cdev.h>
    8. #include <linux/miscdevice.h>
    9. #include <linux/sched.h>
    10. #include <linux/gpio.h>

    11. #define DEVICE_NAME     "buttons"

    12. struct button_irq_desc {
    13. int irq;
    14. int pin;
    15. int pin_setting;
    16. int number;
    17. char *name;
    18. };

    19. static struct button_irq_desc button_irqs [] = {
    20. {IRQ_EINT8 , S3C2410_GPG(0) ,  S3C2410_GPG0_EINT8  , 0, "KEY0"},
    21. {IRQ_EINT11, S3C2410_GPG(3) ,  S3C2410_GPG3_EINT11 , 1, "KEY1"},
    22. {IRQ_EINT13, S3C2410_GPG(5) ,  S3C2410_GPG5_EINT13 , 2, "KEY2"},
    23. {IRQ_EINT14, S3C2410_GPG(6) ,  S3C2410_GPG6_EINT14 , 3, "KEY3"},
    24. {IRQ_EINT15, S3C2410_GPG(7) ,  S3C2410_GPG7_EINT15 , 4, "KEY4"},
    25. {IRQ_EINT19, S3C2410_GPG(11),  S3C2410_GPG11_EINT19, 5, "KEY5"},
    26. };
    27. static volatile char key_values [] = {'0', '0', '0', '0', '0', '0'};

    28. static DECLARE_WAIT_QUEUE_HEAD(button_waitq);

    29. static volatile int ev_press = 0;


    30. static irqreturn_t buttons_interrupt(int irq, void *dev_id)
    31. {
    32. struct button_irq_desc *button_irqs = (struct button_irq_desc *)dev_id;
    33. int down;

    34. // udelay(0);
    35. down = !s3c2410_gpio_getpin(button_irqs->pin);

    36. if (down != (key_values[button_irqs->number] & 1)) { // Changed

    37. key_values[button_irqs->number] = '0' + down;

    38. ev_press = 1;
    39. wake_up_interruptible(&button_waitq);
    40. }

    41. return IRQ_RETVAL(IRQ_HANDLED);
    42. }


    43. static int s3c24xx_buttons_open(struct inode *inode, struct file *file)
    44. {
    45. int i;
    46. int err = 0;

    47. for (i = 0; i < sizeof(button_irqs)/sizeof(button_irqs[0]); i++) {
    48. if (button_irqs[i].irq < 0) {
    49. continue;
    50. }
    51. err = request_irq(button_irqs[i].irq, buttons_interrupt, IRQ_TYPE_EDGE_BOTH,
    52. button_irqs[i].name, (void *)&button_irqs[i]);
    53. if (err)
    54. break;
    55. }

    56. if (err) {
    57. i--;
    58. for (; i >= 0; i--) {
    59. if (button_irqs[i].irq < 0) {
    60. continue;
    61. }
    62. disable_irq(button_irqs[i].irq);
    63. free_irq(button_irqs[i].irq, (void *)&button_irqs[i]);
    64. }
    65. return -EBUSY;
    66. }

    67. ev_press = 1;

    68. return 0;
    69. }


    70. static int s3c24xx_buttons_close(struct inode *inode, struct file *file)
    71. {
    72. int i;

    73. for (i = 0; i < sizeof(button_irqs)/sizeof(button_irqs[0]); i++) {
    74. if (button_irqs[i].irq < 0) {
    75. continue;
    76. }
    77. free_irq(button_irqs[i].irq, (void *)&button_irqs[i]);
    78. }

    79. return 0;
    80. }


    81. static int s3c24xx_buttons_read(struct file *filp, char __user *buff, size_t count, loff_t *offp)
    82. {
    83. unsigned long err;

    84. if (!ev_press) {
    85. if (filp->f_flags & O_NONBLOCK)
    86. return -EAGAIN;
    87. else
    88. wait_event_interruptible(button_waitq, ev_press);
    89. }

    90. ev_press = 0;

    91. err = copy_to_user(buff, (const void *)key_values, min(sizeof(key_values), count));

    92. return err ? -EFAULT : min(sizeof(key_values), count);
    93. }

    94. static unsigned int s3c24xx_buttons_poll( struct file *file, struct poll_table_struct *wait)
    95. {
    96. unsigned int mask = 0;
    97. poll_wait(file, &button_waitq, wait);
    98. if (ev_press)
    99. mask |= POLLIN | POLLRDNORM;
    100. return mask;
    101. }


    102. static struct file_operations dev_fops = {
    103. .owner   =   THIS_MODULE,
    104. .open    =   s3c24xx_buttons_open,
    105. .release =   s3c24xx_buttons_close,
    106. .read    =   s3c24xx_buttons_read,
    107. .poll    =   s3c24xx_buttons_poll,
    108. };

    109. static int __init dev_init(void)
    110. {
    111. int ret;

    112. ret = misc_register(&misc);

    113. printk (DEVICE_NAME"\tinitialized\n");

    114. return ret;
    115. }

    116. static void __exit dev_exit(void)
    117. {
    118. misc_deregister(&misc);
    119. }

    120. module_init(dev_init);
    121. module_exit(dev_exit);
    122. MODULE_LICENSE("GPL");
    123. MODULE_AUTHOR("FriendlyARM Inc.");
    复制代码

    2、测试代码

    1. #include <stdio.h>
    2. #include <stdlib.h>
    3. #include <unistd.h>
    4. #include <sys/ioctl.h>
    5. #include <sys/types.h>
    6. #include <sys/stat.h>
    7. #include <fcntl.h>
    8. #include <sys/select.h>
    9. #include <sys/time.h>
    10. #include <errno.h>

    11. int main(void)
    12. {
    13. int buttons_fd;
    14. char buttons[6] = {'0', '0', '0', '0', '0', '0'};

    15. for (;;) {
    16. char current_buttons[6];
    17. int count_of_changed_key;
    18. int i;
    19. if (read(buttons_fd, current_buttons, sizeof current_buttons) != sizeof current_buttons) {
    20. perror("read buttons:");
    21. exit(1);
    22. }

    23. printf("%skey %d is %s", count_of_changed_key? ", ": "", i+1, buttons[i] == '0' ? "up" : "down");
    24. count_of_changed_key++;
    25. }
    26. }
    27. if (count_of_changed_key) {
    28. printf("\n");
    29. }


    30. }

    31. close(buttons_fd);
    32. return 0;
    33. }
    复制代码

    示例二:
    1、驱动程序

    1. #include <linux/module.h>
    2. #include <linux/kernel.h>
    3. #include <linux/fs.h>
    4. #include <linux/init.h>
    5. #include <linux/delay.h>
    6. #include <linux/poll.h>
    7. #include <linux/irq.h>
    8. #include <asm/irq.h>
    9. #include <linux/interrupt.h>
    10. #include <asm/uaccess.h>
    11. #include <linux/miscdevice.h>
    12. #include <linux/sched.h>
    13. #include <linux/gpio.h>

    14. #define DEVICE_NAME     "buttons2"

    15. struct button_irq_desc {
    16. int irq;
    17. int pin;
    18. int number;
    19. char *name;
    20. };

    21. static struct button_irq_desc button_irqs [] = {
    22. {IRQ_EINT8 , S3C2410_GPG(0) , 0, "KEY0"},
    23. {IRQ_EINT11, S3C2410_GPG(3) , 1, "KEY1"},
    24. {IRQ_EINT13, S3C2410_GPG(5) , 2, "KEY2"},
    25. {IRQ_EINT14, S3C2410_GPG(6) , 3, "KEY3"},
    26. {IRQ_EINT15, S3C2410_GPG(7) , 4, "KEY4"},
    27. {IRQ_EINT19, S3C2410_GPG(11), 5, "KEY5"},
    28. };
    29. static volatile int key_values [] = {0, 0, 0, 0, 0, 0, 0};

    30. static DECLARE_WAIT_QUEUE_HEAD(button_waitq);

    31. static volatile int ev_press = 0;


    32. static irqreturn_t buttons_interrupt(int irq, void *dev_id)
    33. {
    34. struct button_irq_desc *button_irqs = (struct button_irq_desc *)dev_id;
    35. int down;

    36. // udelay(0);
    37. down = !s3c2410_gpio_getpin(button_irqs->pin);

    38. if (down) { // Changed
    39. key_values[button_irqs->number + 1] = key_values[button_irqs->number + 1] + 1;
    40. key_values[0] = key_values[0] + 1;

    41. ev_press = 1;
    42. wake_up_interruptible(&button_waitq);
    43. }

    44. return IRQ_RETVAL(IRQ_HANDLED);
    45. }


    46. static int s3c24xx_buttons_open(struct inode *inode, struct file *file)
    47. {
    48. int i;
    49. int err = 0;

    50. if (err) {
    51. i--;
    52. for (; i >= 0; i--) {
    53. if (button_irqs[i].irq < 0) {
    54. continue;
    55. }
    56. disable_irq(button_irqs[i].irq);
    57. free_irq(button_irqs[i].irq, (void *)&button_irqs[i]);
    58. }
    59. return -EBUSY;
    60. }

    61. ev_press = 1;

    62. return 0;
    63. }


    64. static int s3c24xx_buttons_close(struct inode *inode, struct file *file)
    65. {
    66. int i;

    67. for (i = 0; i < sizeof(button_irqs)/sizeof(button_irqs[0]); i++) {
    68. if (button_irqs[i].irq < 0) {
    69. continue;
    70. }
    71. free_irq(button_irqs[i].irq, (void *)&button_irqs[i]);
    72. }

    73. return 0;
    74. }


    75. static int s3c24xx_buttons_read(struct file *filp, char __user *buff, size_t count, loff_t *offp)
    76. {
    77. unsigned long err;

    78. if (!ev_press) {
    79. if (filp->f_flags & O_NONBLOCK)
    80. return -EAGAIN;
    81. else
    82. wait_event_interruptible(button_waitq, ev_press);
    83. }

    84. ev_press = 0;

    85. err = copy_to_user(buff, (const void *)key_values, min(sizeof(key_values), count));

    86. return err ? -EFAULT : min(sizeof(key_values), count);
    87. }

    88. static unsigned int s3c24xx_buttons_poll( struct file *file, struct poll_table_struct *wait)
    89. {
    90. unsigned int mask = 0;
    91. poll_wait(file, &button_waitq, wait);
    92. if (ev_press)
    93. mask |= POLLIN | POLLRDNORM;
    94. return mask;
    95. }


    96. static struct file_operations dev_fops = {
    97. .owner   =   THIS_MODULE,
    98. .open    =   s3c24xx_buttons_open,
    99. .release =   s3c24xx_buttons_close,
    100. .read    =   s3c24xx_buttons_read,
    101. .poll    =   s3c24xx_buttons_poll,
    102. };

    103. static struct miscdevice misc = {
    104. .minor = MISC_DYNAMIC_MINOR,
    105. .name = DEVICE_NAME,
    106. .fops = &dev_fops,
    107. };

    108. static int __init dev_init(void)
    109. {
    110. int ret;

    111. ret = misc_register(&misc);

    112. printk (DEVICE_NAME"\tinitialized\n");

    113. return ret;
    114. }

    115. static void __exit dev_exit(void)
    116. {
    117. misc_deregister(&misc);
    118. }

    119. module_init(dev_init);
    120. module_exit(dev_exit);
    121. MODULE_LICENSE("GPL");
    122. MODULE_AUTHOR("FriendlyARM Inc.");
    复制代码

    2、测试程序

    1. <p style="box-sizing: inherit; margin-top: 16px; margin-bottom: 14px; line-height: 28px;">#include <stdio.h>
    2. #include <stdlib.h>
    3. #include <unistd.h>
    4. #include <sys/ioctl.h>
    5. #include <sys/types.h>
    6. #include <sys/stat.h>
    7. #include <fcntl.h>
    8. #include <sys/select.h>
    9. #include <sys/time.h>
    10. #include <errno.h>

    11. int main(void)
    12. {
    13. int buttons_fd;
    14. int total_buttons_click = 0;

    15. buttons_fd = open("/dev/buttons2", 0);
    16. if (buttons_fd < 0) {
    17. perror("open device buttons");
    18. exit(1);
    19. }

    20. int i;
    21. if (read(buttons_fd, current_buttons, sizeof current_buttons) != sizeof current_buttons) {
    22. perror("read buttons:");
    23. exit(1);
    24. }

    25. if (total_buttons_click < current_buttons[0]) {
    26. total_buttons_click = current_buttons[0];
    27. printf("total: %d\t key1: %d\t key2: %d\t key3: %d\t key4: %d\t key5: %d\t key6: %d \n"
    28. , current_buttons[0], current_buttons[1], current_buttons[2]
    29. , current_buttons[3], current_buttons[4], current_buttons[5]
    30. , current_buttons[6]);
    31. }

    32. }

    33. close(buttons_fd);
    34. return 0;
    35. }</p><p style="box-sizing: inherit; margin-top: 16px; margin-bottom: 14px; line-height: 28px; color: rgb(61, 70, 77); font-family: " pingfang="" sc",="" stheiti,="" "lantinghei="" "open="" sans",="" arial,="" "hiragino="" sans="" gb",="" "microsoft="" yahei",="" "wenquanyi="" micro="" hei",="" simsun,="" sans-serif;="" font-size:="" 16px;"=""></p>
    复制代码


    分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
    收藏收藏
    回复

    使用道具 举报

    本版积分规则

    关闭

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

    小黑屋|手机版|Archiver|51Testing软件测试网 ( 沪ICP备05003035号 关于我们

    GMT+8, 2024-11-28 10:12 , Processed in 0.064560 second(s), 23 queries .

    Powered by Discuz! X3.2

    © 2001-2024 Comsenz Inc.

    快速回复 返回顶部 返回列表