• 基于gpio的子系统编写led的驱动和应用程序测试


    myled.c

    1. #include
    2. #include
    3. #include
    4. #include
    5. #include
    6. #include
    7. #include
    8. #include
    9. #include
    10. #define LED_ON _IOW('l',1,int)
    11. #define LED_OFF _IOW('l',0,int)
    12. int major;
    13. struct class *cls;
    14. struct device *dev;
    15. struct device_node *dnode;
    16. struct gpio_desc *gpiono0,*gpiono1,*gpiono2;
    17. char kbuf[128]={0};
    18. int mycdev_open(struct inode *inode,struct file *file)
    19. {
    20. printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
    21. return 0;
    22. }
    23. long mycdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
    24. {
    25. switch (cmd)
    26. {
    27. case LED_ON: // 开灯
    28. gpiod_set_value(gpiono0,1);
    29. gpiod_set_value(gpiono1,1);
    30. gpiod_set_value(gpiono2,1);
    31. break;
    32. case LED_OFF: // 关灯
    33. gpiod_set_value(gpiono0,0);
    34. gpiod_set_value(gpiono1,0);
    35. gpiod_set_value(gpiono2,0);
    36. break;
    37. }
    38. return 0;
    39. }
    40. int mycdev_close(struct inode *inode,struct file *file)
    41. {
    42. printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
    43. return 0;
    44. }
    45. //定义一个操作方法结构体对象并且初始化
    46. struct file_operations fops = {
    47. .open=mycdev_open,
    48. .unlocked_ioctl = mycdev_ioctl,
    49. .release=mycdev_close,
    50. };
    51. static int __init mycdev_init(void)
    52. {
    53. //字符设备驱动注册
    54. major = register_chrdev(0,"myled",&fops);
    55. if(major < 0)
    56. {
    57. printk("字符设备驱动注册失败\n");
    58. return major;
    59. }
    60. printk("字符设备驱动注册成功:major=%d\n",major);
    61. //向上提交目录
    62. cls = class_create(THIS_MODULE,"myled");
    63. if(IS_ERR(cls))
    64. {
    65. printk("向上提交目录失败\n");
    66. return -PTR_ERR(cls);
    67. }
    68. printk("向上提交目录成功\n");
    69. //向上提交设备节点的信息
    70. int i;
    71. for(i=0;i<3;i++)
    72. {
    73. dev=device_create(cls,NULL,MKDEV(major,i),NULL,"myled%d",i);
    74. if(IS_ERR(dev))
    75. {
    76. printk("向上提交设备节点的信息失败\n");
    77. return -PTR_ERR(dev);
    78. }
    79. }
    80. printk("向上提交设备节点信息成功\n");
    81. //解析LED的设备树节点
    82. dnode=of_find_node_by_path("/myled");
    83. if(dnode==NULL)
    84. {
    85. printk("解析设备树节点失败\n");
    86. return -ENXIO;
    87. }
    88. printk("解析GPIO信息成功\n");
    89. //申请gpio对象
    90. gpiono0=gpiod_get_from_of_node(dnode,"led1-gpio",0,GPIOD_OUT_LOW,NULL);
    91. gpiono1=gpiod_get_from_of_node(dnode,"led2-gpio",0,GPIOD_OUT_LOW,NULL);
    92. gpiono2=gpiod_get_from_of_node(dnode,"led3-gpio",0,GPIOD_OUT_LOW,NULL);
    93. if(IS_ERR(gpiono0) || IS_ERR(gpiono1) ||IS_ERR(gpiono2))
    94. {
    95. printk("申请gpio对象失败\n");
    96. return -ENXIO;
    97. }
    98. printk("申请gpio信息对象成功\n");
    99. return 0;
    100. }
    101. static void __exit mycdev_exit(void)
    102. {
    103. //销毁设备节点信息
    104. int i;
    105. for(i=0;i<3;i++)
    106. {
    107. device_destroy(cls,MKDEV(major,i));
    108. }
    109. //销毁目录信息
    110. class_destroy(cls);
    111. //注销字符设备驱动
    112. unregister_chrdev(major,"myled");
    113. //灭灯
    114. gpiod_set_value(gpiono0,0);
    115. gpiod_set_value(gpiono1,0);
    116. gpiod_set_value(gpiono2,0);
    117. //释放gpio编号
    118. gpiod_put(gpiono0);
    119. gpiod_put(gpiono2);
    120. gpiod_put(gpiono1);
    121. }
    122. module_init(mycdev_init);
    123. module_exit(mycdev_exit);
    124. MODULE_LICENSE("GPL");

    app.c

    1. #include
    2. #include
    3. #include
    4. #include
    5. #include
    6. #include
    7. #include
    8. #include
    9. #define LED_ON _IOW('l',1,int)
    10. #define LED_OFF _IOW('l',0,int)
    11. int main(int argc, const char *argv[])
    12. {
    13. int fd,a;
    14. char buf[128]={0};
    15. // 打开设备节点
    16. fd = open("/dev/myled0", O_RDWR);
    17. if (fd < 0)
    18. {
    19. printf("设备文件打开失败\n");
    20. exit(-1);
    21. }
    22. while(1)
    23. {
    24. printf("亲输入对LED灯的控制:1(开灯)0(关灯)\n");
    25. scanf("%d",&a);
    26. switch(a)
    27. {
    28. case 1:
    29. ioctl(fd,LED_ON);
    30. break;
    31. case 0:
    32. ioctl(fd,LED_OFF);
    33. }
    34. }
    35. close(fd);
    36. return 0;
    37. }

  • 相关阅读:
    Web前端培训:确保项目成功的10大Web开发框架
    代码随想录算法训练营 day56|583. 两个字符串的删除操作、72. 编辑距离
    MySQL 存储过程创建指定表结构
    RabbitMQ详解(上)
    杭电多校-Shortest Path in GCD Graph-(二进制容斥+优化)
    求10的阶乘之和
    5+非肿瘤分析,分型+WGCNA+机器学习筛选相关基因
    蓝牙芯片香薰机智能化方案
    现代循环神经网络 - 机器翻译与数据集
    Jenkins用户权限配置 (三)
  • 原文地址:https://blog.csdn.net/m0_59343476/article/details/132996459