• 控制三盏灯


    驱动代码

    1. #include <linux/init.h>
    2. #include <linux/module.h>
    3. #include <linux/fs.h>
    4. #include <linux/uaccess.h>
    5. #include <linux/io.h>
    6. #include "head.h"
    7. unsigned int major;//保存主设备号
    8. char kbuf[128] = {0};
    9. unsigned int *vir1_moder;
    10. unsigned int *vir1_odr;
    11. unsigned int *vir1_rcc;
    12. unsigned int *vir2_moder;
    13. unsigned int *vir2_odr;
    14. unsigned int *vir2_rcc;
    15. unsigned int *vir3_moder;
    16. unsigned int *vir3_odr;
    17. unsigned int *vir3_rcc;
    18. //封装操作方法
    19. int mycdev_open(struct inode *inode,struct file *file)
    20. {
    21. printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
    22. return 0;
    23. };
    24. ssize_t mycdev_read(struct file *file,char *ubuf,size_t size,loff_t *lof)
    25. {
    26. int ret;
    27. ret = copy_to_user(ubuf,kbuf,size);
    28. if (ret)
    29. {
    30. printk("copy_to_user err\n");
    31. return -EIO;
    32. }
    33. return 0;
    34. }
    35. ssize_t mycdev_write(struct file *file,const char *ubuf,size_t size,loff_t *lof)
    36. {
    37. int ret = 0;
    38. ret = copy_from_user(kbuf,ubuf,size);
    39. if (ret)
    40. {
    41. printk("copy_from_user err\n");
    42. return -EIO;
    43. }
    44. switch(kbuf[0])
    45. {
    46. case '1':
    47. (*vir1_odr) |= (0x1 << 10);
    48. break;
    49. case '2':
    50. (*vir1_odr) &= (~(0x1 << 10));
    51. break;
    52. case '3':
    53. (*vir2_odr) |= (0x1 << 10);
    54. break;
    55. case '4':
    56. (*vir2_odr) &= (~(0x1 << 10));
    57. break;
    58. case '5':
    59. (*vir3_odr) |= (0x1 << 8);
    60. break;
    61. case '6':
    62. (*vir3_odr) &= (~(0x1 << 8));
    63. break;
    64. default:
    65. printk("输入错误\n");
    66. break;
    67. }
    68. return 0;
    69. }
    70. int mycdev_close(struct inode *inode,struct file *file)
    71. {
    72. printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
    73. return 0;
    74. };
    75. //定义一个操作方法结构体对象并初始化
    76. struct file_operations fops = {
    77. .open = mycdev_open,
    78. .read = mycdev_read,
    79. .write = mycdev_write,
    80. .release = mycdev_close,
    81. };
    82. static int __init mycdev_init(void)
    83. {
    84. //字符设备驱动注册
    85. major = register_chrdev(0,"mychrdev",&fops);
    86. if(major < 0)
    87. {
    88. printk("字符串设备驱动注册失败\n");
    89. }
    90. printk("字符设备驱动注册成功 major = %d\n",major);
    91. //相关寄存器内存映射
    92. vir1_odr = ioremap(LED1_ODR,4);
    93. if (vir1_odr == NULL)
    94. {
    95. printk("物理内存映射失败%d\n",__LINE__);
    96. return -EFAULT;
    97. }
    98. vir1_rcc = ioremap(LED1_RCC,4);
    99. if (vir1_rcc == NULL)
    100. {
    101. printk("物理内存映射失败%d\n",__LINE__);
    102. return -EFAULT;
    103. }
    104. vir1_moder = ioremap(LED1_MODER,4);
    105. if (vir1_moder == NULL)
    106. {
    107. printk("物理内存映射失败%d\n",__LINE__);
    108. return -EFAULT;
    109. }
    110. vir2_odr = ioremap(LED2_ODR,4);
    111. if (vir2_odr == NULL)
    112. {
    113. printk("物理内存映射失败%d\n",__LINE__);
    114. return -EFAULT;
    115. }
    116. vir2_rcc = ioremap(LED2_RCC,4);
    117. if (vir2_rcc == NULL)
    118. {
    119. printk("物理内存映射失败%d\n",__LINE__);
    120. return -EFAULT;
    121. }
    122. vir2_moder = ioremap(LED2_MODER,4);
    123. if (vir2_moder == NULL)
    124. {
    125. printk("物理内存映射失败%d\n",__LINE__);
    126. return -EFAULT;
    127. }
    128. vir3_odr = ioremap(LED3_ODR,4);
    129. if (vir3_odr == NULL)
    130. {
    131. printk("物理内存映射失败%d\n",__LINE__);
    132. return -EFAULT;
    133. }
    134. vir3_rcc = ioremap(LED3_RCC,4);
    135. if (vir3_rcc == NULL)
    136. {
    137. printk("物理内存映射失败%d\n",__LINE__);
    138. return -EFAULT;
    139. }
    140. vir3_moder = ioremap(LED3_MODER,4);
    141. if (vir3_moder == NULL)
    142. {
    143. printk("物理内存映射失败%d\n",__LINE__);
    144. return -EFAULT;
    145. }
    146. printk("寄存器内存映射成功\n");
    147. //硬件寄存器的初始化
    148. //RCC使能
    149. (*vir1_rcc) |= (0x1 << 4);
    150. //设置PE10为输出
    151. (*vir1_moder) &= (~(0x3 << 20));
    152. (*vir1_moder) |= (0x1 << 20);
    153. //默认关灯
    154. (*vir1_odr) &= (~(0x1 << 10));
    155. //RCC使能
    156. (*vir2_rcc) |= (0x1 << 5);
    157. //设置PE10为输出
    158. (*vir2_moder) &= (~(0x3 << 20));
    159. (*vir2_moder) |= (0x1 << 20);
    160. //默认关灯
    161. (*vir1_odr) &= (~(0x1 << 10));
    162. //RCC使能
    163. (*vir1_rcc) |= (0x1 << 4);
    164. //设置PE10为输出
    165. (*vir1_moder) &= (~(0x3 << 16));
    166. (*vir1_moder) |= (0x1 << 16);
    167. //默认关灯
    168. (*vir1_odr) &= (~(0x1 << 8));
    169. return 0;
    170. }
    171. static void __exit mycdev_exit(void)
    172. {
    173. //取消物理内存映射
    174. iounmap(vir1_moder);
    175. iounmap(vir1_rcc);
    176. iounmap(vir1_odr);
    177. iounmap(vir2_moder);
    178. iounmap(vir2_rcc);
    179. iounmap(vir2_odr);
    180. iounmap(vir3_moder);
    181. iounmap(vir3_rcc);
    182. iounmap(vir3_odr);
    183. //字符设备驱动注销
    184. unregister_chrdev(major,"mychrdev");
    185. }
    186. module_init(mycdev_init);
    187. module_exit(mycdev_exit);
    188. MODULE_LICENSE("GPL");

    应用层代码

    1. #include <stdio.h>
    2. #include <sys/types.h>
    3. #include <sys/stat.h>
    4. #include <fcntl.h>
    5. #include <unistd.h>
    6. #include <stdlib.h>
    7. #include <string.h>
    8. int main(int argc,const char * argv[])
    9. {
    10. char buf[128] = {0};
    11. int fd = open("/dev/mychrdev",O_RDWR);
    12. if(fd < 0)
    13. {
    14. printf("设备文件打开失败\n");
    15. exit(-1);
    16. }
    17. while(1)
    18. {
    19. printf("请输入对LED的控制命令1(LED1开灯)2(LED1关灯)3(LED2开灯)4(LED2关灯)5(LED3开灯)6(LED3关灯)>");
    20. fgets(buf,sizeof(buf),stdin);//在终端输入数据到buf
    21. buf[strlen(buf)-1] = '\0';
    22. write(fd,buf,sizeof(buf));
    23. memset(buf,0,sizeof(buf));
    24. }
    25. close(fd);
    26. return 0;
    27. }

  • 相关阅读:
    spring-boot-maven-plugin
    前端token知识梳理:token如何存储?token过期如何处理?如何无感刷新token?
    Linux详解(基础、环境配置、项目部署入门)
    交叉编译工具的安装和配置过程介绍
    浅析微前端框架 single-spa
    UEFI之DXE阶段
    C++ push_back()和back() 、pop()、push()、emplace() 和 emplace_back()
    前端面试题
    为什么 C# 可能是最好的第一编程语言
    Linux之 Python-Python开发平台 Ubuntu
  • 原文地址:https://blog.csdn.net/2301_77612529/article/details/132742722