51Testing软件测试论坛

标题: Linux 驱动开发:中断测试示例 --- 两个测试按键示例 [打印本页]

作者: 测试积点老人    时间: 2019-1-8 17:35
标题: Linux 驱动开发:中断测试示例 --- 两个测试按键示例

示例一:
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>
复制代码







欢迎光临 51Testing软件测试论坛 (http://bbs.51testing.com/) Powered by Discuz! X3.2