• 驱动开发第二天


    头文件

    1. #ifndef __HEAD_H__
    2. #define __HEAD_H__
    3. #define PHY_LED1_MODER 0x50006000
    4. #define PHY_LED2_MODER 0x50007000
    5. #define PHY_LED3_MODER 0x50006000
    6. #define PHY_LED1_ODR 0x50006014
    7. #define PHY_LED2_ODR 0x50007014
    8. #define PHY_LED3_ODR 0x50006014
    9. #define PHY_RCC 0x50000A28
    10. #endif

    demo.c文件

    1. #include
    2. #include
    3. #include
    4. #include
    5. #include
    6. #include "head.h"
    7. unsigned int major;
    8. char kbuf[128]={};
    9. //定义三个指针指向映射后的虚拟内存
    10. unsigned int *vir_led1_moder;
    11. unsigned int *vir_led2_moder;
    12. unsigned int *vir_led3_moder;
    13. unsigned int *vir_led1_odr;
    14. unsigned int *vir_led2_odr;
    15. unsigned int *vir_led3_odr;
    16. unsigned int *vir_rcc;
    17. // 封装操作方法
    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. int ret;
    27. ret=copy_to_user(ubuf,kbuf,size);
    28. if(ret)
    29. {
    30. printk("copy_to_user fild\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. int ret;
    39. ret=copy_from_user(kbuf,ubuf,size);
    40. if(ret)
    41. {
    42. printk("copy_from_user filed\n");
    43. return -EIO;
    44. }
    45. if(kbuf[0]=='0')
    46. {
    47. (*vir_led1_odr)&=(~(0x1<<10));
    48. (*vir_led2_odr)&=(~(0x1<<10));
    49. (*vir_led3_odr)&=(~(0x1<<8));
    50. }
    51. else if(kbuf[0]=='1')
    52. {
    53. (*vir_led1_odr)|=(0x1<<10);
    54. (*vir_led2_odr)|=(0x1<<10);
    55. (*vir_led3_odr)|=(0x1<<8);
    56. }
    57. return 0;
    58. }
    59. int mycdev_close(struct inode *inode, struct file *file)
    60. {
    61. printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
    62. return 0;
    63. }
    64. // 定义操作方法结构体对象
    65. struct file_operations fops = {
    66. .open=mycdev_open,
    67. .read=mycdev_read,
    68. .write=mycdev_write,
    69. .release=mycdev_close,
    70. };
    71. static int __init mycdev_init(void)
    72. {
    73. // 注册字符设备驱动
    74. major = register_chrdev(0, "mychrdev", &fops);
    75. if (major < 0)
    76. {
    77. printk("字符设备驱动注册失败\n");
    78. return major;
    79. }
    80. printk("注册字符设备驱动成功major=%d\n", major);
    81. //进行寄存器的地址映射
    82. vir_led1_moder = ioremap(PHY_LED1_MODER,4);
    83. if(vir_led1_moder==NULL)
    84. {
    85. printk("物理内存地址映射失败%d\n",__LINE__);
    86. return -EFAULT;
    87. }
    88. vir_led1_odr=ioremap(PHY_LED1_ODR,4);
    89. if(vir_led1_odr==NULL)
    90. {
    91. printk("物理内存地址映射失败%d\n",__LINE__);
    92. return -EFAULT;
    93. }
    94. vir_led2_moder = ioremap(PHY_LED2_MODER,4);
    95. if(vir_led2_moder==NULL)
    96. {
    97. printk("物理内存地址映射失败%d\n",__LINE__);
    98. return -EFAULT;
    99. }
    100. vir_led2_odr=ioremap(PHY_LED2_ODR,4);
    101. if(vir_led2_odr==NULL)
    102. {
    103. printk("物理内存地址映射失败%d\n",__LINE__);
    104. return -EFAULT;
    105. }
    106. vir_led3_moder = ioremap(PHY_LED3_MODER,4);
    107. if(vir_led3_moder==NULL)
    108. {
    109. printk("物理内存地址映射失败%d\n",__LINE__);
    110. return -EFAULT;
    111. }
    112. vir_led3_odr=ioremap(PHY_LED3_ODR,4);
    113. if(vir_led3_odr==NULL)
    114. {
    115. printk("物理内存地址映射失败%d\n",__LINE__);
    116. return -EFAULT;
    117. }
    118. vir_rcc=ioremap(PHY_RCC,4);
    119. if(vir_rcc==NULL)
    120. {
    121. printk("物理内存地址映射失败%d\n",__LINE__);
    122. return -EFAULT;
    123. }
    124. printk("寄存器内存映射成功\n");
    125. //LED1寄存器初始化
    126. (*vir_rcc)|=(0x1<<4);
    127. (*vir_led1_moder)&=(~(0x3<<20));
    128. (*vir_led1_moder)|=(0x1<<20);
    129. (*vir_led1_odr)&=(~(0x1<<10));
    130. (*vir_led2_moder)&=(~(0x3<<20));
    131. (*vir_led2_moder)|=(0x1<<20);
    132. (*vir_led2_odr)&=(~(0x1<<10));
    133. (*vir_led3_moder)&=(~(0x3<<16));
    134. (*vir_led3_moder)|=(0x1<<16);
    135. (*vir_led3_odr)&=(~(0x1<<8));
    136. return 0;
    137. }
    138. static void __exit mycdev_exit(void)
    139. {
    140. //取消内存映射
    141. iounmap(vir_led1_moder);
    142. iounmap(vir_led1_odr);
    143. iounmap(vir_led2_moder);
    144. iounmap(vir_led2_odr);
    145. iounmap(vir_led3_moder);
    146. iounmap(vir_led3_odr);
    147. iounmap(vir_rcc);
    148. //注销字符设备驱动
    149. unregister_chrdev(major,"mychrdev");
    150. }
    151. module_init(mycdev_init);
    152. module_exit(mycdev_exit);
    153. MODULE_LICENSE("GPL");

  • 相关阅读:
    [计算机提升] 命令、批处理介绍
    卷积神经网络 - 车辆识别
    【第四部分 | JavaScript 基础】3:函数、作用域与预解析、对象
    SAP S4客户与供应商如何管理 事务代码 BP
    【无标题】
    在PostgreSQL中如何有效地批量导入大量数据,并确保数据加载过程中的性能和稳定性?
    提交SCI论文修改稿时标注修改文字颜色
    Java语言开发的AI智慧导诊系统源码springboot+redis 3D互联网智导诊系统源码
    Python函数
    FPGA project : rom_vga_jump
  • 原文地址:https://blog.csdn.net/2202_75860121/article/details/133954014