国产毛片a精品毛-国产毛片黄片-国产毛片久久国产-国产毛片久久精品-青娱乐极品在线-青娱乐精品

迅為i.MX6ULL終結者設備樹下的Platform驅動實驗程序編寫

發布時間:2020-12-31 11:17    發布者:就是塔塔
文章目錄
  • 1 修改設備樹文件
  • 2 platform驅動程序
  • 3 應用測試程序

1 修改設備樹文件

設備樹文件可以直接使用第三十五章中添加的gpioled子節點即可,不用重復添加。

2 platform驅動程序

本實驗例程路徑:i.MX6UL終結者光盤資料/06_Linux驅動例程/15_gpioled_dts
創建led_driver.c文件,具體內容如下:

  1.   1 #include
  2.   2 #include
  3.   3 #include
  4.   4 #include
  5.   5 #include
  6.   6 #include
  7.   7 #include
  8.   8 #include
  9.   9 #include
  10. 10 #include
  11. 11 #include
  12. 12 #include
  13. 13 #include
  14. 14 #include
  15. 15 #include
  16. 16 #include
  17. 17 #include
  18. 18 #include
  19. 19 #include
  20. 20 #include
  21. 21 #include
  22. 22 #include
  23. 23
  24. 24 #define LEDDEV_CNT              1                    /* 設備號長度   */
  25. 25 #define LEDDEV_NAME             "dtsplatled"    /* 設備名字     */
  26. 26 #define LEDOFF                  0
  27. 27 #define LEDON                   1
  28. 28
  29. 29 /* leddev設備結構體 */
  30. 30 struct leddev_dev{
  31. 31         dev_t devid;                            /* 設備號       */
  32. 32         struct cdev cdev;                       /* cdev         */
  33. 33         struct class *class;            /* 類           */
  34. 34         struct device *device;          /* 設備 */
  35. 35         int major;                     /* 主設備號     */
  36. 36         struct device_node *node;       /* LED設備節點 */
  37. 37         int led0;                      /* LED燈GPIO標號 */
  38. 38 };
  39. 39
  40. 40 struct leddev_dev leddev;               /* led設備 */
  41. 41
  42. 42 /*
  43. 43  * @description         : LED打開/關閉
  44. 44  * @param - sta         : LEDON(0) 打開LED,LEDOFF(1) 關閉LED
  45. 45  * @return                      : 無
  46. 46  */
  47. 47 void led0_switch(u8 sta)
  48. 48 {
  49. 49         if (sta == LEDON )
  50. 50                 gpio_set_value(leddev.led0, 0);
  51. 51         else if (sta == LEDOFF)
  52. 52                 gpio_set_value(leddev.led0, 1);
  53. 53 }
  54. 54
  55. 55 /*
  56. 56  * @description         : 打開設備
  57. 57  * @param - inode       : 傳遞給驅動的inode
  58. 58  * @param - filp        : 設備文件,file結構體有個叫做private_data的成員變量
  59. 59  * 一般在open的時候將private_data指向設備結構體。
  60. 60  * @return                      : 0 成功;其他 失敗
  61. 61  */
  62. 62 static int led_open(struct inode *inode, struct file *filp)
  63. 63 {
  64. 64         filp->private_data = &leddev; /* 設置私有數據  */
  65. 65         return 0;
  66. 66 }
  67. 67
  68. 68 /*
  69. 69  * @description         : 向設備寫數據
  70. 70  * @param - filp        : 設備文件,表示打開的文件描述符
  71. 71  * @param - buf         : 要寫給設備寫入的數據
  72. 72  * @param - cnt         : 要寫入的數據長度
  73. 73  * @param - offt        : 相對于文件首地址的偏移
  74. 74  * @return                      : 寫入的字節數,如果為負值,表示寫入失敗
  75. 75  */
  76. 76 static ssize_t led_write(struct file *filp, const char __user *buf, size_t cnt, loff_t *offt)
  77. 77 {
  78. 78         int retvalue;
  79. 79         unsigned char databuf[2];
  80. 80         unsigned char ledstat;
  81. 81
  82. 82         retvalue = copy_from_user(databuf, buf, cnt);
  83. 83         if(retvalue < 0) {
  84. 84
  85. 85                 printk("kernel write failed!\r\n");
  86. 86                 return -EFAULT;
  87. 87         }
  88. 88
  89. 89         ledstat = databuf[0];
  90. 90         if (ledstat == LEDON) {
  91. 91                 led0_switch(LEDON);
  92. 92         } else if (ledstat == LEDOFF) {
  93. 93                 led0_switch(LEDOFF);
  94. 94         }
  95. 95         return 0;
  96. 96 }
  97. 97
  98. 98 /* 設備操作函數 */
  99. 99 static struct file_operations led_fops = {
  100. 100         .owner = THIS_MODULE,
  101. 101         .open = led_open,
  102. 102         .write = led_write,
  103. 103 };
  104. 104
  105. 105 /*
  106. 106  * @description         : flatform驅動的probe函數,當驅動與
  107. 107  *                                        設備匹配以后此函數就會執行
  108. 108  * @param - dev         : platform設備
  109. 109  * @return                      : 0,成功;其他負值,失敗
  110. 110  */
  111. 111 static int led_probe(struct platform_device *dev)
  112. 112 {
  113. 113         printk("led driver and device was matched!\r\n");
  114. 114         /* 1、設置設備號 */
  115. 115         if (leddev.major) {
  116. 116                 leddev.devid = MKDEV(leddev.major, 0);
  117. 117               register_chrdev_region(leddev.devid, LEDDEV_CNT, LEDDEV_NAME);
  118. 118         } else {
  119. 119              alloc_chrdev_region(&leddev.devid, 0, LEDDEV_CNT, LEDDEV_NAME);
  120. 120                 leddev.major = MAJOR(leddev.devid);
  121. 121         }
  122. 122
  123. 123         /* 2、注冊設備      */
  124. 124         cdev_init(&leddev.cdev, &led_fops);
  125. 125         cdev_add(&leddev.cdev, leddev.devid, LEDDEV_CNT);
  126. 126
  127. 127         /* 3、創建類      */
  128. 128         leddev.class = class_create(THIS_MODULE, LEDDEV_NAME);
  129. 129         if (IS_ERR(leddev.class)) {
  130. 130                 return PTR_ERR(leddev.class);
  131. 131         }
  132. 132
  133. 133         /* 4、創建設備 */
  134. 134         leddev.device = device_create(leddev.class, NULL, leddev.devid,
  135. NULL, LEDDEV_NAME);
  136. 135         if (IS_ERR(leddev.device)) {
  137. 136                 return PTR_ERR(leddev.device);
  138. 137         }
  139. 138
  140. 139         /* 5、初始化IO */
  141. 140         leddev.node = of_find_node_by_path("/gpioled");
  142. 141         if (leddev.node == NULL){
  143. 142                 printk("gpioled node nost find!\r\n");
  144. 143                 return -EINVAL;
  145. 144         }
  146. 145
  147. 146         leddev.led0 = of_get_named_gpio(leddev.node, "led-gpio", 0);
  148. 147         if (leddev.led0 < 0) {
  149. 148                 printk("can't get led-gpio\r\n");
  150. 149                 return -EINVAL;
  151. 150         }
  152. 151
  153. 152         gpio_request(leddev.led0, "led0");
  154. 153     gpio_direction_output(leddev.led0, 1); /* led0 IO設置為輸出,默認高電平 */
  155. 154         return 0;
  156. 155 }
  157. 156
  158. 157 /*
  159. 158  * @description : platform驅動的remove函數,移除platform
  160. 驅動的時候此函數會執行
  161. 159  * @param - dev         : platform設備
  162. 160  * @return         : 0,成功;其他負值,失敗
  163. 161  */
  164. 162 static int led_remove(struct platform_device *dev)
  165. 163 {
  166. 164         gpio_set_value(leddev.led0, 1);         /* 卸載驅動的時候關閉LED */
  167. 165
  168. 166         cdev_del(&leddev.cdev);                         /*  刪除cdev */
  169. 167         unregister_chrdev_region(leddev.devid, LEDDEV_CNT); /* 注銷設備號 */
  170. 168         device_destroy(leddev.class, leddev.devid);
  171. 169         class_destroy(leddev.class);
  172. 170         return 0;
  173. 171 }
  174. 172
  175. 173 /* 匹配列表 */
  176. 174 static const struct of_device_id led_of_match[] = {
  177. 175         { .compatible = "gpioled" },
  178. 176         { /* Sentinel */ }
  179. 177 };
  180. 178
  181. 179 /* platform驅動結構體 */
  182. 180 static struct platform_driver led_driver = {
  183. 181         .driver         = {
  184. 182                 .name   = "imx6ul-led",     /* 驅動名字,用于和設備匹配 */
  185. 183                 .of_match_table = led_of_match, /* 設備樹匹配表 */
  186. 184         },
  187. 185         .probe          = led_probe,
  188. 186         .remove         = led_remove,
  189. 187 };
  190. 188
  191. 189 /*
  192. 190  * @description : 驅動模塊加載函數
  193. 191  * @param               : 無
  194. 192  * @return              : 無
  195. 193  */
  196. 194 static int __init leddriver_init(void)
  197. 195 {
  198. 196         return platform_driver_register(&led_driver);
  199. 197 }
  200. 198
  201. 199 /*
  202. 200  * @description : 驅動模塊卸載函數
  203. 201  * @param               : 無
  204. 202  * @return              : 無
  205. 203  */
  206. 204 static void __exit leddriver_exit(void)
  207. 205 {
  208. 206         platform_driver_unregister(&led_driver);
  209. 207 }
  210. 208
  211. 209 module_init(leddriver_init);
  212. 210 module_exit(leddriver_exit);
  213. 211 MODULE_LICENSE("GPL");
  214. 212 MODULE_AUTHOR("topeet");
復制代碼

第 174~177 行,匹配表,描述了此驅動都和什么樣的設備匹配,第 175 行添加了一條值為"gpioled"的 compatible 屬性值,當設備樹中某個設備節點的 compatible 屬性值也為 “gpioled”的時候就會與此驅動匹配。
第 180~187 行,platform_driver 驅動結構體,182 行設置這個 platform 驅動的名字為“imx6ul-led”,因此,當驅動加載成功以后就會在/sys/bus/platform/drivers/目錄下存在一個名為“imx6u-led”的文件。 第 183 行設置 of_match_table 為上面的 led_of_match。

3 應用測試程序

應用測試程序直接使用上一章44.3.2的led_test.c即可。


本文地址:http://m.qingdxww.cn/thread-752673-1-1.html     【打印本頁】

本站部分文章為轉載或網友發布,目的在于傳遞和分享信息,并不代表本網贊同其觀點和對其真實性負責;文章版權歸原作者及原出處所有,如涉及作品內容、版權和其它問題,我們將根據著作權人的要求,第一時間更正或刪除。
您需要登錄后才可以發表評論 登錄 | 立即注冊

廠商推薦

  • Microchip視頻專區
  • 利用SAM E54 Xplained Pro評估工具包演示CAN轉USB橋接器以及基于CAN的主機和自舉程序應用程序
  • 使用SAM-IoT Wx v2開發板演示AWS IoT Core應用程序
  • 使用Harmony3加速TCP/IP應用的開發培訓教程
  • 集成高級模擬外設的PIC18F-Q71家族介紹培訓教程
  • 貿澤電子(Mouser)專區
關于我們  -  服務條款  -  使用指南  -  站點地圖  -  友情鏈接  -  聯系我們
電子工程網 © 版權所有   京ICP備16069177號 | 京公網安備11010502021702
快速回復 返回頂部 返回列表
主站蜘蛛池模板: 四虎国产成人亚洲精品 | 黄色免费观看网站 | 国产永久在线 | 红纸鹤免费高清在线观看 | 一级毛片无毒不卡直接观看 | 成人三级毛片 | 日韩精品一区二区三区毛片 | 九七在线 | 在线观看免费小视频 | 色偷偷成人| 国产欧美日韩灭亚洲精品 | 丁香婷婷在线 | 岛国大片免费在线观看 | 国产欧美自拍视频 | 无限资源第一页2018在线播放 | 蜜桃精品视频 | 精品自在线| 亚洲三级黄 | 四虎影在永久地址在线观看 | 四虎最新永久免费视频 | 久久九九精品一区二区 | 在线亚洲精品福利网址导航 | 国产日韩亚洲欧洲一区二区三区 | 精品亚洲视频在线 | 绿巨人香蕉草莓丝瓜茄子番茄在线 | 亚洲精品一卡2卡3卡三卡四卡 | 老潮湿影院免费体验区 | 99re6这里只有精品视频 | 日韩毛片免费观看 | 麻豆精品视频在线 | 99精品视频99 | 国产高清在线不卡 | 亚洲欧美一区二区三区蜜芽 | 国产三片高清在线观看 | 中文字幕在线播 | 欧美日韩视频综合一区无弹窗 | 欧美成人免费观看久久 | 女人被男人插视频 | 国产又色又爽又黄的网站在线一级 | 久久精品一区二区三区不卡 | 亚洲一级毛片免观看 |