• 底层驱动day8作业


    代码:

    1. //驱动程序
    2. #include<linux/init.h>
    3. #include<linux/module.h>
    4. #include<linux/of.h>
    5. #include<linux/of_gpio.h>
    6. #include<linux/gpio.h>
    7. #include<linux/timer.h>
    8. struct device_node *dnode;
    9. //unsigned int gpiono;
    10. char kbuf[128] = {0};
    11. //定义定时器对象
    12. struct timer_list mytimer;
    13. struct gpio_desc *gpiono;
    14. int major;
    15. struct class *cls;
    16. struct device *dev;
    17. int mycdev_open(struct inode *inode, struct file *file)
    18. {
    19. printk("%s:%s:%d\n", __FILE__, __func__, __LINE__);
    20. return 0;
    21. }
    22. ssize_t mycdev_write(struct file *file, const char *ubuf, size_t size, loff_t *lof)
    23. {
    24. printk("%s:%s:%d\n", __FILE__, __func__, __LINE__);
    25. int ret=copy_from_user(kbuf,ubuf,size);
    26. if(ret)
    27. {
    28. printk("copy_from_user filed\n");
    29. return -EIO;
    30. }
    31. printk("%d\n",kbuf[0] - 48);
    32. gpiod_set_value(gpiono,kbuf[0] - 48);
    33. return 0;
    34. }
    35. int mycdev_close(struct inode *inode, struct file *file)
    36. {
    37. printk("%s:%s:%d\n", __FILE__, __func__, __LINE__);
    38. return 0;
    39. }
    40. // 定义操作方法结构体变量并赋值
    41. struct file_operations fops = {
    42. .open = mycdev_open,
    43. .write = mycdev_write,
    44. .release = mycdev_close,
    45. };
    46. void handler(struct timer_list *timer)
    47. {
    48. printk("hello world\n");
    49. mod_timer(timer,jiffies + 5 * HZ);
    50. }
    51. static int __init mycdev_init(void)
    52. {
    53. dnode = of_find_node_by_path("/myled");
    54. if(NULL == dnode)
    55. {
    56. printk("解析设备节点信息失败\n");
    57. return -ENXIO;
    58. }
    59. //获取LED1 GPIO编号
    60. gpiono = gpiod_get_from_of_node(dnode,"led1-gpio",0,GPIOD_OUT_LOW,NULL);
    61. if(IS_ERR(gpiono))
    62. {
    63. printk("申请gpio信息失败\n");
    64. return -PTR_ERR(gpiono);
    65. }
    66. //初始化定时器对象
    67. timer_setup(&mytimer,handler,0);
    68. mytimer.expires = jiffies + HZ;
    69. //注册定时器
    70. add_timer(&mytimer);
    71. major = register_chrdev(0, "mychrdev", &fops);
    72. if (major < 0)
    73. {
    74. printk("字符设备驱动注册失败\n");
    75. return major;
    76. }
    77. printk("字符设备驱动注册成功:major=%d\n", major);
    78. // 向上提交目录
    79. cls = class_create(THIS_MODULE, "mychrdev");
    80. if (IS_ERR(cls))
    81. {
    82. printk("向上提交目录失败\n");
    83. return -PTR_ERR(cls);
    84. }
    85. printk("向上提交目录成功\n");
    86. // 向上提交设备节点信息
    87. int i; // 向上提交三次设备节点信息
    88. for (i = 0; i < 3; i++)
    89. {
    90. dev = device_create(cls, NULL, MKDEV(major, i), NULL, "myled%d", i);
    91. if (IS_ERR(dev))
    92. {
    93. printk("向上提交设备节点失败\n");
    94. return -PTR_ERR(dev);
    95. }
    96. }
    97. printk("向上提交设备节点成功\n");
    98. return 0;
    99. }
    100. static void __exit mycdev_exit(void)
    101. {
    102. del_timer(&mytimer);
    103. //gpio_free(gpiono);
    104. gpiod_put(gpiono);
    105. // 销毁设备节点信息
    106. int i;
    107. for (i = 0; i < 3; i++)
    108. {
    109. device_destroy(cls, MKDEV(major, i));
    110. }
    111. // 销毁目录
    112. class_destroy(cls);
    113. // 注销字符设备驱动
    114. unregister_chrdev(major, "mychrdev");
    115. }
    116. module_init(mycdev_init);
    117. module_exit(mycdev_exit);
    118. MODULE_LICENSE("GPL");
    1. //应用程序
    2. #include
    3. #include
    4. #include
    5. #include
    6. #include
    7. #include
    8. #include
    9. #include
    10. int main(int argc, char const *argv[])
    11. {
    12. char buf[128] = {0};
    13. int fd = open("/dev/myled0",O_RDWR);
    14. while(1)
    15. {
    16. printf("请输入>>>");
    17. scanf("%s",buf);
    18. write(fd,buf,1);
    19. }
    20. return 0;
    21. }

     实验现象

     

  • 相关阅读:
    C++-map和set
    云原生爱好者周刊:电子书《可观测性工程》开放下载 | 2022-08-01
    2023年安全员-C证证模拟考试题库及安全员-C证理论考试试题
    IOS课程笔记[4-5] 计算器实现与更换主题 的使用
    java版工程管理系统Spring Cloud+Spring Boot+Mybatis实现工程管理系统源码
    文案配音软件哪个好?(适合新手使用)
    【矩阵论】4. 矩阵运算——广义逆——加号逆应用
    vue实战-产品详情页(轮播图、放大镜)
    C# WPF入门学习番外篇(二) —— C# WPF使用数据库创建注册登录界面
    【2024年最新】NodeMCU-ESP8266刷AT固件教程——适用于esp-12E和esp-12F
  • 原文地址:https://blog.csdn.net/a136630108/article/details/134088508