• 22071.11.24


    1. #ifndef __LED_H__
    2. #define __LED_H__
    3. #define LED_ON _IOW('a',1,int)
    4. #define LED_OFF _IOW('a',0,int)
    5. typedef enum
    6. {
    7. LED1,
    8. LED2,
    9. LED3,
    10. LED4,
    11. LED5,
    12. LED6
    13. }led_t;
    14. #endif
    1. #include <stdio.h>
    2. #include <sys/types.h>
    3. #include <sys/stat.h>
    4. #include <fcntl.h>
    5. #include <errno.h>
    6. #include <unistd.h>
    7. #include <stdlib.h>
    8. #include <string.h>
    9. #include <sys/ioctl.h>
    10. #include "led.h"
    11. int main(int argc, char const *argv[])
    12. {
    13. int fd1 = -1;
    14. int fd2 = -1;
    15. int fd3 = -1;
    16. int fd4 = -1;
    17. int fd5 = -1;
    18. int fd6 = -1;
    19. int whitch;
    20. //打开6个led设备文件
    21. fd1 = open("/dev/myled0",O_RDWR);
    22. if(-1==fd1)
    23. {
    24. perror("open fd1 is error");
    25. exit(1);
    26. }
    27. fd2 = open("/dev/myled1",O_RDWR);
    28. if(-1==fd2)
    29. {
    30. perror("open fd2 is error");
    31. exit(1);
    32. }
    33. fd3 = open("/dev/myled2",O_RDWR);
    34. if(-1==fd3)
    35. {
    36. perror("open fd3 is error");
    37. exit(1);
    38. }
    39. fd4 = open("/dev/myled3",O_RDWR);
    40. if(-1==fd4)
    41. {
    42. perror("open fd4 is error");
    43. exit(1);
    44. }
    45. fd5 = open("/dev/myled4",O_RDWR);
    46. if(-1==fd5)
    47. {
    48. perror("open fd5 is error");
    49. exit(1);
    50. }
    51. fd6 = open("/dev/myled5",O_RDWR);
    52. if(-1==fd6)
    53. {
    54. perror("open fd6 is error");
    55. exit(1);
    56. }
    57. while(1)
    58. {
    59. whitch=LED1;
    60. ioctl(fd1,LED_ON,&whitch);
    61. sleep(1);
    62. ioctl(fd1,LED_OFF,&whitch);
    63. sleep(1);
    64. whitch=LED2;
    65. ioctl(fd2,LED_ON,&whitch);
    66. sleep(1);
    67. ioctl(fd2,LED_OFF,&whitch);
    68. sleep(1);
    69. whitch=LED3;
    70. ioctl(fd3,LED_ON,&whitch);
    71. sleep(1);
    72. ioctl(fd3,LED_OFF,&whitch);
    73. sleep(1);
    74. whitch=LED4;
    75. ioctl(fd4,LED_ON,&whitch);
    76. sleep(1);
    77. ioctl(fd4,LED_OFF,&whitch);
    78. sleep(1);
    79. whitch=LED5;
    80. ioctl(fd5,LED_ON,&whitch);
    81. sleep(1);
    82. ioctl(fd5,LED_OFF,&whitch);
    83. sleep(1);
    84. whitch=LED6;
    85. ioctl(fd6,LED_ON,&whitch);
    86. sleep(1);
    87. ioctl(fd6,LED_OFF,&whitch);
    88. sleep(1);
    89. }
    90. close(fd1);
    91. close(fd2);
    92. close(fd3);
    93. close(fd4);
    94. close(fd5);
    95. close(fd6);
    96. return 0;
    97. }

    1. #include <linux/init.h>
    2. #include <linux/module.h>
    3. #include <linux/of.h>
    4. #include <linux/of_gpio.h>
    5. #include <linux/gpio.h>
    6. #include <linux/cdev.h>
    7. #include <linux/fs.h>
    8. #include <linux/device.h>
    9. #include <linux/slab.h>
    10. #include "led.h"
    11. #define CNAME "myled"
    12. struct device_node *node;
    13. struct gpio_desc *gpio1;
    14. struct gpio_desc *gpio2;
    15. struct gpio_desc *gpio3;
    16. struct gpio_desc *gpio4;
    17. struct gpio_desc *gpio5;
    18. struct gpio_desc *gpio6;
    19. int ret;
    20. struct cdev* cdev; //字符设备结构体指针
    21. dev_t devno;
    22. struct class* cls;
    23. struct device* devt;
    24. #if 1
    25. unsigned int major = 0; //动态申请设备号
    26. #else
    27. unsigned int major = 500;
    28. #endif
    29. int minor = 0;
    30. const int count = 6;
    31. int mycdev_open(struct inode *inode,struct file *file)
    32. {
    33. printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
    34. return 0;
    35. }
    36. long mycdev_ioctl(struct file *file,unsigned int cmd,unsigned long arg)
    37. {
    38. int ret;
    39. int whitch;
    40. switch(cmd)
    41. {
    42. case LED_ON:
    43. ret = copy_from_user(&whitch,(void*)arg,sizeof(int));
    44. if(ret)
    45. {
    46. printk("copy from user led on...");
    47. return -EIO;
    48. }
    49. switch(whitch)
    50. {
    51. case LED1:
    52. gpiod_set_value(gpio1,1);
    53. break;
    54. case LED2:
    55. gpiod_set_value(gpio2,1);
    56. break;
    57. case LED3:
    58. gpiod_set_value(gpio3,1);
    59. break;
    60. case LED4:
    61. gpiod_set_value(gpio4,1);
    62. break;
    63. case LED5:
    64. gpiod_set_value(gpio5,1);
    65. break;
    66. case LED6:
    67. gpiod_set_value(gpio6,1);
    68. break;
    69. }
    70. break;
    71. case LED_OFF:
    72. ret = copy_from_user(&whitch,(void*)arg,sizeof(int));
    73. if(ret)
    74. {
    75. printk("copy from user led off...");
    76. return -EIO;
    77. }
    78. switch(whitch)
    79. {
    80. case LED1:
    81. gpiod_set_value(gpio1,0);
    82. break;
    83. case LED2:
    84. gpiod_set_value(gpio2,0);
    85. break;
    86. case LED3:
    87. gpiod_set_value(gpio3,0);
    88. break;
    89. case LED4:
    90. gpiod_set_value(gpio4,0);
    91. break;
    92. case LED5:
    93. gpiod_set_value(gpio5,0);
    94. break;
    95. case LED6:
    96. gpiod_set_value(gpio6,0);
    97. break;
    98. }
    99. break;
    100. }
    101. return 0;
    102. }
    103. int mycdev_close(struct inode *inode,struct file *file)
    104. {
    105. printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
    106. return 0;
    107. }
    108. const struct file_operations fops = {
    109. .open = mycdev_open,
    110. .unlocked_ioctl = mycdev_ioctl,
    111. .release = mycdev_close,
    112. };
    113. //进出口
    114. static int __init mycdev_init(void)
    115. {
    116. int i;
    117. int error;
    118. cdev = cdev_alloc();
    119. if(NULL==cdev)
    120. {
    121. printk("cdev alloc is error...\n");
    122. error = -EIO;
    123. goto ERR1;
    124. }
    125. cdev_init(cdev,&fops);
    126. if(major>0)
    127. {
    128. //静态指定设备号
    129. error = register_chrdev_region(MKDEV(major,minor),count,CNAME);
    130. if(error)
    131. {
    132. printk("register chrdev region is error ...\n");
    133. error = -ENOMEM;
    134. goto ERR2;
    135. }
    136. }
    137. else
    138. {
    139. //动态申请设备号
    140. error = alloc_chrdev_region(&devno,0,count,CNAME);
    141. if(error)
    142. {
    143. printk("alloc chadev region is error ...\n");
    144. error = -ENOMEM;
    145. goto ERR2;
    146. }
    147. major = MAJOR(devno);
    148. minor = MINOR(devno);
    149. }
    150. error = cdev_add(cdev,MKDEV(major,minor),count);
    151. if(error)
    152. {
    153. printk("cdev add is error...\n");
    154. error = -EIO;
    155. goto ERR3;
    156. }
    157. //自动创建设备节点
    158. cls = class_create(THIS_MODULE,CNAME);
    159. if(IS_ERR(cls))
    160. {
    161. printk("class create is error ...\n");
    162. error = PTR_ERR(cls);
    163. goto ERR4;
    164. }
    165. for(i=0;i<count;i++)
    166. {
    167. devt = device_create(cls,NULL,MKDEV(major,i),NULL,"myled%d",i);
    168. if(IS_ERR(devt))
    169. {
    170. printk("device create is error ...\n");
    171. error = PTR_ERR(devt);
    172. goto ERR5;
    173. }
    174. }
    175. node=of_find_node_by_name(NULL,"myleds");
    176. if(node==NULL)
    177. {
    178. printk("find node error\n");
    179. return -EFAULT;
    180. }
    181. printk("find node success\n");
    182. //获取并申请gpio编号
    183. gpio1 = gpiod_get_from_of_node(node,"myled1",0,GPIOD_OUT_LOW,NULL);
    184. if(IS_ERR(gpio1))
    185. {
    186. printk("get gpio1 error\n");
    187. return PTR_ERR(gpio1);
    188. }
    189. gpiod_direction_output(gpio1,0);
    190. gpio2 = gpiod_get_from_of_node(node,"myled2",0,GPIOD_OUT_LOW,NULL);
    191. if(IS_ERR(gpio2))
    192. {
    193. printk("get gpio2 error\n");
    194. return PTR_ERR(gpio2);
    195. }
    196. gpiod_direction_output(gpio2,0);
    197. gpio3 = gpiod_get_from_of_node(node,"myled3",0,GPIOD_OUT_LOW,NULL);
    198. if(IS_ERR(gpio3))
    199. {
    200. printk("get gpio3 error\n");
    201. return PTR_ERR(gpio3);
    202. }
    203. gpiod_direction_output(gpio3,0);
    204. gpio4 = gpiod_get_from_of_node(node,"myled4",0,GPIOD_OUT_LOW,NULL);
    205. if(IS_ERR(gpio4))
    206. {
    207. printk("get gpio4 error\n");
    208. return PTR_ERR(gpio4);
    209. }
    210. gpiod_direction_output(gpio4,0);
    211. gpio5 = gpiod_get_from_of_node(node,"myled5",0,GPIOD_OUT_LOW,NULL);
    212. if(IS_ERR(gpio5))
    213. {
    214. printk("get gpio5 error\n");
    215. return PTR_ERR(gpio5);
    216. }
    217. gpiod_direction_output(gpio5,0);
    218. gpio6 = gpiod_get_from_of_node(node,"myled6",0,GPIOD_OUT_LOW,NULL);
    219. if(IS_ERR(gpio6))
    220. {
    221. printk("get gpio6 error\n");
    222. return PTR_ERR(gpio6);
    223. }
    224. gpiod_direction_output(gpio6,0);
    225. return 0;
    226. //跳转接口
    227. ERR5:
    228. for(--i;i>=0;i--)
    229. {
    230. device_destroy(cls,MKDEV(major,i));
    231. }
    232. class_destroy(cls);
    233. ERR4:
    234. cdev_del(cdev);
    235. ERR3:
    236. unregister_chrdev_region(MKDEV(major,minor),count);
    237. ERR2:
    238. kfree(cdev);
    239. ERR1:
    240. return -EIO;
    241. }
    242. static void __exit mycdev_exit(void)
    243. {
    244. int i;
    245. //注销
    246. gpiod_set_value(gpio1,0);
    247. gpiod_set_value(gpio2,0);
    248. gpiod_set_value(gpio3,0);
    249. gpiod_set_value(gpio4,0);
    250. gpiod_set_value(gpio5,0);
    251. gpiod_set_value(gpio6,0);
    252. gpiod_put(gpio1);
    253. gpiod_put(gpio2);
    254. gpiod_put(gpio3);
    255. gpiod_put(gpio4);
    256. gpiod_put(gpio5);
    257. gpiod_put(gpio6);
    258. //1。销毁设备节点信息
    259. for(i=0;i<count;i++)
    260. {
    261. device_destroy(cls,MKDEV(major,i));
    262. }
    263. //2.销毁目录信息
    264. class_destroy(cls);
    265. //3.驱动的注销
    266. cdev_del(cdev);
    267. //4.销毁设备号
    268. unregister_chrdev_region(MKDEV(major,minor),count);
    269. //5.释放cdev结构体
    270. kfree(cdev);
    271. }
    272. module_init(mycdev_init);
    273. module_exit(mycdev_exit);
    274. MODULE_LICENSE("GPL");

     

     

  • 相关阅读:
    达梦、Oracle、PostgreSQL查询全部表备注,表字段,全部字段备注,全部索引,全部字段类型
    iSpring SDK 全球领先 iSpring SDK PPT TO H5
    徐州存储服务器会应用在哪些场景?
    Django笔记十四之统计总数、最新纪录和空值判断等功能
    vue el-dialog弹出框自定义指令实现拖拽改变位置-宽度-高度
    Bioinformatics202207 | CD-MVGNN+:基于交叉依赖图神经网络的分子性质预测
    9、【办公自动化】Python实现Word文件的批量操作
    酒店数字化转型,就从这4步开始
    minio搭建文件存储服务
    Linux 操作另一台服务器
  • 原文地址:https://blog.csdn.net/brightmante/article/details/128025409