• 系统移植 串口输入ECHO点灯


    华清远见上海中心22071班

    串口输入

    echo 1 > /dev/myled0 ---->led1灯点亮

    echo 0 > /dev/myled0 ---->led1灯熄灭

    echo 1 > /dev/myled1 ---->led1灯点亮

    echo 0 > /dev/myled1 ---->led1灯熄灭

    echo 1 > /dev/myled2 ---->led1灯点亮

    echo 0 > /dev/myled2 ---->led1灯熄灭

     

     

     

    1. #include <linux/init.h>
    2. #include <linux/module.h>
    3. #include <linux/cdev.h>
    4. #include <linux/fs.h>
    5. #include <linux/slab.h>
    6. #include <linux/io.h>
    7. #include "led.h"
    8. #if 0
    9. #define LED_MAJOR 500
    10. #else
    11. #define LED_MAJOR 0
    12. #endif
    13. #define COUNT 3
    14. #define SEQNUM 0
    15. #define DRIVERNAME "myled"
    16. struct cdev *ledcdev;
    17. struct class *cls;
    18. struct device *dce;
    19. volatile unsigned int *virt_RCC;
    20. volatile gpio_t *virt_gpioe;
    21. volatile gpio_t *virt_gpiof;
    22. int major = LED_MAJOR;
    23. int minor = 0;
    24. int mycdevopen(struct inode *inode, struct file *file)
    25. {
    26. int ledmajor, ledminor;
    27. ledmajor = MAJOR(inode->i_rdev);
    28. ledminor = MINOR(inode->i_rdev);
    29. printk("ledmajor=%d ledminor = %d\n", ledmajor, ledminor);
    30. printk("open success\n");
    31. file->private_data = (void *)(ledminor);
    32. return 0;
    33. }
    34. int mycdevrelease(struct inode *inode, struct file *file)
    35. {
    36. printk("release success\n");
    37. return 0;
    38. }
    39. ssize_t mycdevread(struct file *file, char __user *ubuf, size_t size, loff_t *loffs)
    40. {
    41. return 0;
    42. }
    43. ssize_t mycdevwrite(struct file *file, const char __user *ubuf, size_t size, loff_t *loffs)
    44. {
    45. int ledminor;
    46. unsigned long res;
    47. char kbuf[128] = "";
    48. ledminor = (int)file->private_data;
    49. switch (ledminor)
    50. {
    51. case 0:
    52. if (size > sizeof(kbuf))
    53. {
    54. size = sizeof(kbuf);
    55. }
    56. res = copy_from_user(kbuf, ubuf, size);
    57. if (res)
    58. {
    59. printk("copy_from_user failed (err %ld)", res);
    60. return res;
    61. }
    62. if ('0' == kbuf[0])
    63. {
    64. virt_gpioe->ODR &= (~(0x1 << 10));
    65. }
    66. else
    67. {
    68. virt_gpioe->ODR |= (0x1 << 10);
    69. }
    70. break;
    71. case 1:
    72. if (size > sizeof(kbuf))
    73. {
    74. size = sizeof(kbuf);
    75. }
    76. res = copy_from_user(kbuf, ubuf, size);
    77. if (res)
    78. {
    79. printk("copy_from_user failed (err %ld)", res);
    80. return res;
    81. }
    82. if ('0' == kbuf[0])
    83. {
    84. virt_gpiof->ODR &= (~(0x1 << 10));
    85. }
    86. else
    87. {
    88. virt_gpiof->ODR |= (0x1 << 10);
    89. }
    90. break;
    91. case 2:
    92. if (size > sizeof(kbuf))
    93. {
    94. size = sizeof(kbuf);
    95. }
    96. res = copy_from_user(kbuf, ubuf, size);
    97. if (res)
    98. {
    99. printk("copy_from_user failed (err %ld)", res);
    100. return res;
    101. }
    102. if ('0' == kbuf[0])
    103. {
    104. virt_gpioe->ODR &= (~(0x1 << 8));
    105. }
    106. else
    107. {
    108. virt_gpioe->ODR |= (0x1 << 8);
    109. }
    110. break;
    111. }
    112. return size;
    113. }
    114. struct file_operations fops = {
    115. .open = mycdevopen,
    116. .read = mycdevread,
    117. .write = mycdevwrite,
    118. .release = mycdevrelease};
    119. static int __init
    120. led_init(void)
    121. {
    122. int res, i;
    123. dev_t devt;
    124. // cdev的创建
    125. ledcdev = cdev_alloc();
    126. if (NULL == ledcdev)
    127. {
    128. printk("cdev alloc failed\n");
    129. res = -ENOMEM;
    130. goto ERR1;
    131. }
    132. // cdev的初始化
    133. cdev_init(ledcdev, &fops);
    134. // 条件判断是否动/静态注册设备号
    135. if (LED_MAJOR > 0)
    136. {
    137. res = register_chrdev_region(MKDEV(LED_MAJOR, SEQNUM), COUNT, DRIVERNAME);
    138. if (res)
    139. {
    140. printk("Unable to register char major %d\n", LED_MAJOR);
    141. goto ERR2;
    142. }
    143. major = LED_MAJOR;
    144. minor = SEQNUM;
    145. }
    146. else
    147. {
    148. res = alloc_chrdev_region(&devt, 0, COUNT, DRIVERNAME);
    149. if (res)
    150. {
    151. printk("Could not allocate chrdev region (err %d)\n", -res);
    152. goto ERR2;
    153. }
    154. major = MAJOR(devt);
    155. minor = MINOR(devt);
    156. }
    157. // 字符设备驱动添加至系统
    158. res = cdev_add(ledcdev, MKDEV(major, minor), COUNT);
    159. if (res)
    160. {
    161. printk("Unable register character device add (err %d)\n", -res);
    162. goto ERR3;
    163. }
    164. // 上传目录
    165. cls = class_create(THIS_MODULE, DRIVERNAME);
    166. if (IS_ERR(cls))
    167. {
    168. res = PTR_ERR(cls);
    169. printk("Class create failed (err %d)\n", -res);
    170. goto ERR4;
    171. }
    172. // 上传节点
    173. for (i = 0; i < COUNT; i++)
    174. {
    175. dce = device_create(cls, NULL, MKDEV(major, i), NULL, "myled%d", i);
    176. if (IS_ERR(dce))
    177. {
    178. res = PTR_ERR(dce);
    179. printk("Device create failed (err %d)\n", res);
    180. goto ERR5;
    181. }
    182. }
    183. //映射RCC_MP_AHB4ENSETR
    184. virt_RCC = (unsigned int *)ioremap(RCC, 4);
    185. if (NULL == virt_RCC)
    186. {
    187. printk("rcc ioremap failed\n");
    188. return -ENOMEM;
    189. }
    190. //映射gpioe的地址
    191. virt_gpioe = (gpio_t *)ioremap(GPIOE, sizeof(gpio_t));
    192. if (NULL == virt_gpioe)
    193. {
    194. printk("gpioe ioremap failed\n");
    195. return -ENOMEM;
    196. }
    197. //映射gpiof的地址
    198. virt_gpiof = (gpio_t *)ioremap(GPIOF, sizeof(gpio_t));
    199. if (NULL == virt_gpiof)
    200. {
    201. printk("gpiof ioremap failed\n");
    202. return -ENOMEM;
    203. }
    204. // RCC使能GPIOE,GPIOF
    205. *virt_RCC |= (0x1 << 4);
    206. *virt_RCC |= (0x1 << 5);
    207. // PE10,PE8设置为输出模式[21:20]=01 [17:16]=01
    208. virt_gpioe->MODER &= (~(0x3 << 20));
    209. virt_gpioe->MODER |= (0x1 << 20);
    210. virt_gpioe->MODER &= (~(0x3 << 16));
    211. virt_gpioe->MODER |= (0x1 << 16);
    212. // PF10设置为输出模式[21:20]=01
    213. virt_gpiof->MODER &= (~(0x3 << 20));
    214. virt_gpiof->MODER |= (0x1 << 20);
    215. //初始化PE10,PE8PF10为熄灭状态
    216. virt_gpiof->ODR &= (~(0x1 << 10));
    217. virt_gpioe->ODR &= (~(0x1 << 10));
    218. virt_gpioe->ODR &= (~(0x1 << 8));
    219. return 0;
    220. ERR5:
    221. for (--i; i >= 0; i--)
    222. {
    223. device_destroy(cls, MKDEV(major, i));
    224. }
    225. class_destroy(cls);
    226. ERR4:
    227. cdev_del(ledcdev);
    228. ERR3:
    229. unregister_chrdev_region(MKDEV(major, minor), COUNT);
    230. ERR2:
    231. kfree(ledcdev);
    232. ERR1:
    233. return res;
    234. }
    235. static void __exit led_exit(void)
    236. {
    237. int i;
    238. iounmap(virt_RCC);
    239. iounmap(virt_gpioe);
    240. iounmap(virt_gpiof);
    241. for (i = 0; i < COUNT; i++)
    242. {
    243. device_destroy(cls, MKDEV(major, i));
    244. }
    245. class_destroy(cls);
    246. cdev_del(ledcdev);
    247. unregister_chrdev_region(MKDEV(major, minor), COUNT);
    248. kfree(ledcdev);
    249. }
    250. module_init(led_init);
    251. module_exit(led_exit);
    252. MODULE_LICENSE("GPL");

  • 相关阅读:
    C#:轮询调度算法​(附完整源码)
    HashTable读为什么要加锁
    不一样的网络协议-------KCP协议
    开发chromium你要知道的几个地址
    QT进阶---------pro项目文件中的常用命令 (第三天)
    Flutter完整的Dio网络框架null空安全二次封装。
    30岁从事软件测试,目前已失业4个月,迷茫不知该怎么办。?
    【小月电子】XILINX FPGA开发板(XLOGIC_V1)系统学习教程-LESSON8 LCD1602液晶显示
    如何设计一个面向未来的云原生数据库?
    基于springboot+vue的靓车汽车销售网站(前后端分离)
  • 原文地址:https://blog.csdn.net/weixin_66861497/article/details/127936005