• 驱动开发--day2


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

    1. #ifndef __HEAD_H__
    2. #define __HEAD_H__
    3. #define LED1_MODER 0X50006000
    4. #define LED1_ODR 0X50006014
    5. #define LED1_RCC 0X50000A28
    6. #define LED2_MODER 0X50007000
    7. #define LED2_ODR 0X50007014
    8. #endif

    mychrdev.c

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

    test.c

    1. #include
    2. #include
    3. #include
    4. #include
    5. #include
    6. #include
    7. #include
    8. int main(int argc,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. memset(buf,0,sizeof(buf));
    20. printf("请输入对LED1的控制命令11(开灯) 01(关灯)>>>");
    21. fgets(buf,sizeof(buf),stdin);
    22. buf[strlen(buf)-1]='\0';
    23. write(fd,buf,sizeof(buf));
    24. memset(buf,0,sizeof(buf));
    25. printf("请输入对LED2的控制命令12(开灯) 02(关灯)>>>");
    26. fgets(buf,sizeof(buf),stdin);
    27. buf[strlen(buf)-1]='\0';
    28. write(fd,buf,sizeof(buf));
    29. memset(buf,0,sizeof(buf));
    30. printf("请输入对LED3的控制命令13(开灯) 03(关灯)>>>");
    31. fgets(buf,sizeof(buf),stdin);
    32. buf[strlen(buf)-1]='\0';
    33. write(fd,buf,sizeof(buf));
    34. }
    35. close(fd);
    36. }

    测试过程及现象:

    1.编译>>>

    2.测试>>>

    3.现象>>>

  • 相关阅读:
    【 c++ 二元运算符重载,以<<(抽取符)为例,说清为什么它支持hex,endl等操作函数】
    [Linux]如何理解kernel、shell、bash
    宏观经济学复习
    尚硅谷ES学习笔记一
    浅谈ClickHouse安全性和权限管理
    交换高级特性 —— DTP协商(trunk链路动态协商)+(交换机接口速率+双工模式 协商问题)+ 光接口无法UP常见的原因
    Redis笔记
    用友U8 crm客户关系管理存在任意文件上传漏洞2 附POC
    Spring(01)
    【面试经典150 | 数学】回文数
  • 原文地址:https://blog.csdn.net/m0_72852022/article/details/132744974