• 驱动9.07


     实现三盏灯的控制,编写应用程序测试

    head.h

    1. #ifndef __HEAD_H__
    2. #define __HEAD_H__
    3. //PE10
    4. #define LED1_RCC 0X50000A28
    5. #define LED1_MODER 0X50006000
    6. #define LED1_ODR 0X50006014
    7. //PF10
    8. #define LED2_RCC 0X50000A28
    9. #define LED2_MODER 0X50007000
    10. #define LED2_ODR 0X50007014
    11. #endif

    mychrdev.c 

    1. #include
    2. #include
    3. #include
    4. #include
    5. #include "head.h"
    6. #include
    7. char kbuf[128] = {0};
    8. unsigned int *vir_rcc;
    9. unsigned int *vir_moder;
    10. unsigned int *vir_odr;
    11. unsigned int *vir_rcc_f;
    12. unsigned int *vir_moder_f;
    13. unsigned int *vir_odr_f;
    14. //定义操作方法
    15. int mychrdev_open(struct inode *inode, struct file *file)
    16. {
    17. printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
    18. return 0;
    19. }
    20. ssize_t mychrdev_read(struct file *file, char *ubuf, size_t size, loff_t *lof)
    21. {
    22. int ret;
    23. ret = copy_to_user(ubuf,kbuf,sizeof(kbuf));
    24. if(ret)
    25. {
    26. printk("copy_to_user err\n");
    27. return -EIO;
    28. }
    29. return 0;
    30. }
    31. ssize_t mychrdev_write(struct file *file, const char *ubuf, size_t size, loff_t *lof)
    32. {
    33. int ret;
    34. ret = copy_from_user(kbuf,ubuf,sizeof(ubuf));
    35. if(ret)
    36. {
    37. printk("copy_from_user err\n");
    38. return -EIO;
    39. }
    40. //PE10
    41. if(kbuf[0] == '1') //开灯
    42. {
    43. //开灯逻辑
    44. (*vir_odr) |= (0x1 << 10);
    45. }
    46. else if(kbuf[0] == '0') //关灯
    47. {
    48. //关灯逻辑
    49. (*vir_odr) &= (~(0x1 << 10));
    50. }
    51. //PF10
    52. if(kbuf[1] == '1') //开灯
    53. {
    54. //开灯逻辑
    55. (*vir_odr_f) |= (0x1 << 10);
    56. printk("%d\n",__LINE__);
    57. }
    58. else if(kbuf[1] == '0') //关灯
    59. {
    60. //关灯逻辑
    61. (*vir_odr_f) &= (~(0x1 << 10));
    62. }
    63. //PE8
    64. if(kbuf[2] == '1') //开灯
    65. {
    66. //开灯逻辑
    67. (*vir_odr) |= (0x1 << 8);
    68. }
    69. else if(kbuf[2] == '0') //关灯
    70. {
    71. //关灯逻辑
    72. (*vir_odr) &= (~(0x1 << 8));
    73. }
    74. return 0;
    75. }
    76. int mychrdev_close(struct inode *inode, struct file *file)
    77. {
    78. printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
    79. return 0;
    80. }
    81. //定义存放主设备号变量
    82. unsigned int major;
    83. //定义操作方法的结构体变量
    84. struct file_operations fops={
    85. .open = mychrdev_open,
    86. .read = mychrdev_read,
    87. .write = mychrdev_write,
    88. .release = mychrdev_close
    89. };
    90. static int __init mycdev_init(void)
    91. {
    92. //字符设备驱动注册
    93. major = register_chrdev(0,"mychrdev",&fops);
    94. if(major < 0)
    95. {
    96. printk("字符设备注册失败\n");
    97. }
    98. printk("字符设备注册成功:%d\n",major);
    99. //相关寄存器的内存映射
    100. //GPIOE
    101. vir_rcc = ioremap(LED1_RCC,4);
    102. if(vir_rcc == NULL)
    103. {
    104. printk("物理地址映射失败%d\n",__LINE__);
    105. }
    106. vir_moder = ioremap(LED1_MODER,4);
    107. if(vir_moder == NULL)
    108. {
    109. printk("物理地址映射失败%d\n",__LINE__);
    110. }
    111. vir_odr = ioremap(LED1_ODR,4);
    112. if(vir_odr == NULL)
    113. {
    114. printk("物理地址映射失败%d\n",__LINE__);
    115. }
    116. //GOIOF
    117. vir_rcc = ioremap(LED2_RCC,4);
    118. if(vir_rcc == NULL)
    119. {
    120. printk("物理地址映射失败%d\n",__LINE__);
    121. }
    122. vir_moder_f = ioremap(LED2_MODER,4);
    123. if(vir_moder_f == NULL)
    124. {
    125. printk("物理地址映射失败%d\n",__LINE__);
    126. }
    127. vir_odr_f = ioremap(LED2_ODR,4);
    128. if(vir_odr_f == NULL)
    129. {
    130. printk("物理地址映射失败%d\n",__LINE__);
    131. }
    132. printk("物理地址映射成功\n");
    133. //相关寄存器的初始化
    134. //RCC寄存器
    135. (*vir_rcc) |= (0x1 << 4);
    136. //GPIOE_MODER寄存器(PE10)
    137. (*vir_moder) &= (~(0x3 << 20));
    138. (*vir_moder) |= (0x1 << 20);
    139. //GPIOE_ODR寄存器
    140. (*vir_odr) &= (~(0x1 << 10));
    141. //RCC寄存器(PF10)
    142. (*vir_rcc) |= (0x1 << 5);
    143. //GPIOF_MODER寄存器
    144. (*vir_moder_f) &= (~(0x3 << 20));
    145. (*vir_moder_f) |= (0x1 << 20);
    146. //GPIOF_ODR寄存器
    147. (*vir_odr_f) &= (~(0x1 << 10));
    148. //GPIOE_MODER寄存器(PE8)
    149. (*vir_moder) &= (~(0x3 << 16));
    150. (*vir_moder) |= (0x1 << 16);
    151. //GPIOE_ODR寄存器
    152. (*vir_odr) &= (~(0x1 << 8));
    153. return 0;
    154. }
    155. static void __exit mycdev_exit(void)
    156. {
    157. //取消物理地址映射
    158. iounmap(vir_rcc);
    159. iounmap(vir_moder);
    160. iounmap(vir_odr);
    161. iounmap(vir_rcc_f);
    162. iounmap(vir_moder_f);
    163. iounmap(vir_odr_f);
    164. //字符设备驱动注销
    165. unregister_chrdev(major,"mychrdev");
    166. }
    167. module_init(mycdev_init);
    168. module_exit(mycdev_exit);
    169. MODULE_LICENSE("GPL");

    test.c

    1. #include
    2. #include
    3. #include
    4. #include
    5. #include
    6. #include
    7. #include
    8. int main(int args,char const *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("输入指令控制开/关灯(LED1|LED2|LED3)----0(OFF)、1(ON)>");
    20. fgets(buf,sizeof(buf),stdin);
    21. buf[strlen(buf)-1] = '\0';
    22. write(fd,buf,sizeof(buf));
    23. }
    24. close(fd);
    25. return 0;
    26. }

    测试现象

    111->LED1,LED2,LED3全部点亮

    010->LED1,LED3熄灭 LED2点亮

  • 相关阅读:
    低代码平台如何满足复杂业务需求,二次开发能力不容忽视
    WiFi模块在智能家居中的应用与优化
    利用轻量一键申请多域名通配符免费证书(Trustasia)
    视频监控系统EasyCVR如何通过API接口获取国标GB28181协议接入的实时录像?
    关于 SY8120I 的DC-DC的降压芯片的学习(12V降至3.3V)
    时空智友企业流程化管控系统任意文件上传漏洞复现【附POC】
    深度学习标注工具(包括自动标注)总结——持续更新
    可视化学习:如何使用噪声生成纹理
    matlab习题 —— 符号运算相关练习
    MySQL何时适合创建索引,需要注意什么以及创建原则
  • 原文地址:https://blog.csdn.net/weixin_47976606/article/details/132759821