• platform


    1. #include <linux/init.h>
    2. #include <linux/module.h>
    3. #include <linux/platform_device.h>
    4. #include <linux/mod_devicetable.h>
    5. #include <linux/of.h>
    6. #include <linux/of_gpio.h>
    7. #include <linux/of_irq.h>
    8. #include <linux/interrupt.h>
    9. #include <linux/uaccess.h>
    10. #define CNAME "platform_irq_led"
    11. int major;
    12. struct class *cls;
    13. struct device *dev;
    14. wait_queue_head_t wq;
    15. unsigned int condition=0;
    16. unsigned int status=0;
    17. struct gpio_desc *desc;
    18. unsigned int irqno;
    19. irqreturn_t irq_led_handle(int irq, void *dev)
    20. {
    21. status = gpiod_get_value(desc);
    22. status = !status;
    23. gpiod_set_value(desc,status);
    24. condition=1;
    25. wake_up_interruptible(&wq);
    26. return IRQ_HANDLED;
    27. }
    28. int irq_led_open(struct inode *inode, struct file *file)
    29. {
    30. printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
    31. return 0;
    32. }
    33. ssize_t irq_led_read(struct file *file,
    34. char __user *ubuf, size_t size, loff_t *offs)
    35. {
    36. int ret;
    37. printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
    38. if(file->f_flags & O_NONBLOCK){
    39. //非阻塞
    40. return -EINVAL;
    41. }else{
    42. //阻塞
    43. ret = wait_event_interruptible(wq,condition);
    44. if(ret < 0){
    45. printk("receive signal....\n");
    46. return ret;
    47. }
    48. }
    49. //将数据拷贝到用户空间
    50. if(size > sizeof(status)) size = sizeof(status);
    51. ret = copy_to_user(ubuf,(void *)&status,size);
    52. if(ret){
    53. printk("copy data to user error\n");
    54. return -EIO;
    55. }
    56. //4.将条件清零
    57. condition = 0;
    58. return size;
    59. }
    60. int irq_led_close(struct inode *inode, struct file *file)
    61. {
    62. printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
    63. return 0;
    64. }
    65. struct file_operations fops = {
    66. .open = irq_led_open,
    67. .read = irq_led_read,
    68. .release = irq_led_close,
    69. };
    70. int pdrv_probe(struct platform_device* pdev) //在进入probe函数的时候节点已经被放在pdev->dev.of_node中了
    71. {
    72. int ret;
    73. //1.注册字符设备驱动
    74. major = register_chrdev(0,CNAME,&fops);
    75. if(major < 0){
    76. printk("register char device driver error\n");
    77. ret = major;
    78. goto ERR1;
    79. }
    80. //2.创建设备节点
    81. cls = class_create(THIS_MODULE,CNAME);
    82. if(IS_ERR(cls)){
    83. printk("class create error\n");
    84. ret = PTR_ERR(cls);
    85. goto ERR2;
    86. }
    87. dev = device_create(cls,NULL,MKDEV(major,0),NULL,CNAME);
    88. if(IS_ERR(dev)){
    89. printk("device create error\n");
    90. ret = PTR_ERR(dev);
    91. goto ERR3;
    92. }
    93. //3.初始化等待队列头
    94. init_waitqueue_head(&wq);
    95. desc = gpiod_get_from_of_node(pdev->dev.of_node,"led1",0,GPIOD_OUT_LOW,NULL);
    96. if(IS_ERR(desc)){
    97. printk("get gpiod error\n");
    98. ret = PTR_ERR(desc);
    99. goto ERR4;
    100. }
    101. irqno = platform_get_irq(pdev,0); //获取中断的信息
    102. if(irqno < 0){
    103. printk("get irq resource error\n");
    104. ret = irqno;
    105. goto ERR5;
    106. }
    107. ret = request_irq(irqno,irq_led_handle,IRQF_TRIGGER_FALLING,CNAME,NULL);
    108. if(ret){
    109. printk("request irq error\n");
    110. goto ERR5;
    111. }
    112. return 0;
    113. ERR5:
    114. gpiod_put(desc);
    115. ERR4:
    116. device_destroy(cls,MKDEV(major,0));
    117. ERR3:
    118. class_destroy(cls);
    119. ERR2:
    120. unregister_chrdev(major,CNAME);
    121. ERR1:
    122. return ret;
    123. }
    124. int pdrv_remove(struct platform_device* pdev)
    125. {
    126. printk("%s:%d\n", __func__, __LINE__);
    127. free_irq(irqno,NULL);
    128. gpiod_put(desc);
    129. device_destroy(cls,MKDEV(major,0));
    130. class_destroy(cls);
    131. unregister_chrdev(major,CNAME);
    132. return 0;
    133. }
    134. struct of_device_id oftable[] = {
    135. {.compatible = "hqyj,platform",},
    136. {/*end*/},
    137. };
    138. struct platform_driver pdrv = {
    139. .probe = pdrv_probe,
    140. .remove = pdrv_remove,
    141. .driver = {
    142. .name = "hahaha",
    143. .of_match_table = oftable,
    144. },
    145. };
    146. //这个宏能够实现入口,出口,注册,注销的过程
    147. module_platform_driver(pdrv);
    148. MODULE_LICENSE("GPL");
    1. #include <head.h>
    2. int main(int argc, const char* argv[])
    3. {
    4. int fd;
    5. int status;
    6. if ((fd = open("/dev/platform_irq_led", O_RDWR)) == -1) {
    7. perror("open error");
    8. exit(EXIT_FAILURE);
    9. }
    10. while (1) {
    11. read(fd, &status, sizeof(status));
    12. printf("status = %d\n", status);
    13. }
    14. close(fd);
    15. return 0;
    16. }

  • 相关阅读:
    C++项目开发编译踩坑记录
    官方Redis视图化工具Redisinsight
    【OpenCV】红绿灯检测C++Demo实现
    ILRuntime1.安装
    linux查看文件内容命令more/less/cat/head/tail/grep
    vue中如何全屏显示系统内容
    软件测试/测试开发丨Python异常处理 学习笔记
    软考高级信息系统项目管理师系列论文三:论信息系统项目的进度管理
    GitHub SSH免密登录
    用Vue写教务系统学生管理
  • 原文地址:https://blog.csdn.net/Kukuderener/article/details/133103193