• 驱动开发day2


    任务:使用模块化编译安装驱动实现三盏LED灯的亮灭

    驱动程序

    1. #include
    2. #include
    3. #include
    4. #include
    5. #include
    6. #define PHY_RCC 0X50000A28
    7. #define PHY_LED1_MODER 0x50006000
    8. #define PHY_LED2_MODER 0x50007000
    9. #define PHY_LED1_ODR 0x50006014
    10. #define PHY_LED2_ODR 0x50007014
    11. unsigned int major;
    12. char kbuf[128] = "";
    13. unsigned int *vir_rcc;
    14. unsigned int *vir_moder1;
    15. unsigned int *vir_odr1;
    16. unsigned int *vir_moder2;
    17. unsigned int *vir_odr2;
    18. int mycdev_open(struct inode *inode,struct file *file)
    19. {
    20. printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
    21. return 0;
    22. }
    23. ssize_t mycdev_read(struct file *file,char *ubuf,size_t size,loff_t *lof)
    24. {
    25. printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
    26. unsigned long ret;
    27. ret = copy_to_user(ubuf,kbuf,size);
    28. if(ret)
    29. {
    30. printk("copy_to_user_failed\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. printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
    38. unsigned long ret;
    39. ret = copy_from_user(kbuf,ubuf,size);
    40. if(ret)
    41. {
    42. printk("copy_from_user_failed\n");
    43. return -EIO;
    44. }
    45. if(kbuf[0] == '0')
    46. {
    47. //关闭LED1灯
    48. printk("LED1 OFF\n");
    49. (*vir_odr1) &= (~(0x1 << 10));
    50. }
    51. else if(kbuf[0] == '1')
    52. {
    53. //打开LED1灯
    54. printk("LED1 ON\n");
    55. (*vir_odr1) |= (0x1 << 10);
    56. }
    57. if(kbuf[1] == '0')
    58. {
    59. //关闭LED2灯
    60. printk("LED2 OFF\n");
    61. (*vir_odr2) &= (~(0x1 << 10));
    62. }
    63. else if(kbuf[1] == '1')
    64. {
    65. //打开LED2灯
    66. printk("LED2 ON\n");
    67. (*vir_odr2) |= (0x1 << 10);
    68. }
    69. if(kbuf[2] == '0')
    70. {
    71. //关闭LED3灯
    72. printk("LED3 OFF\n");
    73. (*vir_odr1) &= (~(0x1 << 8));
    74. }
    75. else if(kbuf[2] == '1')
    76. {
    77. //打开LED3灯
    78. printk("LED3 ON\n");
    79. (*vir_odr1) |= (0x1 << 8);
    80. }
    81. return 0;
    82. }
    83. int mycdev_close(struct inode *inode,struct file *file)
    84. {
    85. printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
    86. return 0;
    87. }
    88. struct file_operations fops={
    89. .open=mycdev_open,
    90. .read=mycdev_read,
    91. .write=mycdev_write,
    92. .release=mycdev_close,
    93. };
    94. static int __init mycdev_init(void)
    95. {
    96. major = register_chrdev(0,"mydev",&fops);
    97. if(major < 0)
    98. {
    99. printk("字符设备注册失败\n");
    100. return major;
    101. }
    102. else
    103. {
    104. printk("字符设备注册成功,major=%d\n",major);
    105. }
    106. //物理地址映射到虚拟地址上
    107. vir_rcc = ioremap(PHY_RCC,4);
    108. if(vir_rcc == NULL)
    109. {
    110. printk("映射失败 : %d\n",__LINE__);
    111. return -EFAULT;
    112. }
    113. //LED1/3
    114. vir_moder1 = ioremap(PHY_LED1_MODER,4);
    115. if(vir_moder1 == NULL)
    116. {
    117. printk("映射失败 : %d\n",__LINE__);
    118. return -EFAULT;
    119. }
    120. vir_odr1 = ioremap(PHY_LED1_ODR,4);
    121. if(vir_odr1 == NULL)
    122. {
    123. printk("映射失败 : %d\n",__LINE__);
    124. return -EFAULT;
    125. }
    126. //LED2
    127. vir_moder2 = ioremap(PHY_LED2_MODER,4);
    128. if(vir_moder2 == NULL)
    129. {
    130. printk("映射失败 : %d\n",__LINE__);
    131. return -EFAULT;
    132. }
    133. vir_odr2 = ioremap(PHY_LED2_ODR,4);
    134. if(vir_odr2 == NULL)
    135. {
    136. printk("映射失败 : %d\n",__LINE__);
    137. return -EFAULT;
    138. }
    139. printk("映射成功\n");
    140. //串口初始化
    141. (*vir_rcc) |= (0x3 << 4);
    142. //LED1初始化
    143. (*vir_moder1) &= (~(0x3 << 20));
    144. (*vir_moder1) |= (0x1 << 20);
    145. (*vir_odr1) &= (~(0x1 << 10));
    146. //LED2初始化
    147. (*vir_moder2) &= (~(0x3 << 20));
    148. (*vir_moder2) |= (0x1 << 20);
    149. (*vir_odr2) &= (~(0x1 << 10));
    150. //LED3初始化
    151. (*vir_moder1) &= (~(0x3 << 16));
    152. (*vir_moder1) |= (0x1 << 16);
    153. (*vir_odr1) &= (~(0x1 << 8));
    154. printk("LED初始化成功\n");
    155. return 0;
    156. }
    157. static void __exit mycdev_exit(void)
    158. {
    159. //取消映射
    160. iounmap(vir_rcc);
    161. iounmap(vir_moder1);
    162. iounmap(vir_odr1);
    163. iounmap(vir_moder2);
    164. iounmap(vir_odr2);
    165. unregister_chrdev(major,"mydev");
    166. }
    167. module_init(mycdev_init);
    168. module_exit(mycdev_exit);
    169. MODULE_LICENSE("GPL");

    应用程序

    1. #include
    2. #include
    3. #include
    4. #include
    5. #include
    6. #include
    7. int main()
    8. {
    9. int fd=open("/dev/mychrdev",O_RDWR);
    10. if(fd < 0)
    11. {
    12. printf("文件打开失败\n");
    13. return -1;
    14. }
    15. else
    16. {
    17. printf("文件打开成功\n");
    18. }
    19. char buf[128]="";
    20. while(1)
    21. {
    22. memset(buf,0,sizeof(buf));
    23. printf("请输入LED1/2/3的状态(1:ON/0:OFF)>>");
    24. fgets(buf,sizeof(buf),stdin);
    25. buf[strlen(buf)-1]='\0';
    26. if(buf[0]=='q')
    27. {
    28. break;
    29. }
    30. write(fd,buf,sizeof(buf));
    31. memset(buf,0,sizeof(buf));
    32. read(fd,buf,sizeof(buf));
    33. printf("buf : %s\n",buf);
    34. }
    35. close(fd);
    36. return 0;
    37. }

    串口现象:

    开发板现象:

  • 相关阅读:
    python怎么表示复数
    山西深度研学游之长城之行
    java在cmd中乱码的问题解决
    【sgGoogleTranslate】自定义组件:基于Vue.js用谷歌Google Translate翻译插件实现网站多国语言开发
    day02-Gateway(网关)
    学习rsync
    vue3+Element-plus el-select 下拉选择 多选增加全选封装组件
    新品速看丨创新微MinewSemi正式推出GNSS高精度卫星定位导航模块
    Unity 2021.x 与 Visual Studio 2013 的调试问题
    批发商/分销商会有一波向B2B转型的浪潮
  • 原文地址:https://blog.csdn.net/m0_64146298/article/details/133953334