• 底层驱动day2作业


    控制三盏灯亮灭

    代码:

    1. //head.h
    2. #ifndef __HEAD_H__
    3. #define __HEAD_H__
    4. #define PHY_RCC 0x50000A28
    5. #define PHY_GPIOE_MODER 0x50006000
    6. #define PHY_GPIOF_MODER 0x50007000
    7. #define PHY_GPIOE_ODR 0x50006014
    8. #define PHY_GPIOF_ODR 0x50007014
    9. #endif
    1. //demo.c
    2. #include<linux/init.h>
    3. #include<linux/module.h>
    4. #include<linux/fs.h>
    5. #include<linux/uaccess.h>
    6. #include<linux/io.h>
    7. #include"include/head.h"
    8. char kbuf[128] = {0};
    9. int a = 10;
    10. unsigned int major;
    11. unsigned int *vir_led1_odr;
    12. unsigned int *vir_led1_moder;
    13. unsigned int *vir_rcc;
    14. unsigned int *vir_led2_odr;
    15. unsigned int *vir_led2_moder;
    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_write(struct file *file,const char *ubuf,size_t size,loff_t *lof)
    22. {
    23. printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
    24. int ret = copy_from_user(kbuf,ubuf,size);
    25. if(ret)
    26. {
    27. printk("failed\n");
    28. return -EIO;
    29. }
    30. switch(kbuf[0]) //kbuf的第0位为led灯,第2位为led灯的状态
    31. {
    32. case '1':
    33. if(kbuf[2] == '0')
    34. {
    35. //关灯
    36. (*vir_led1_odr) &= (~(0x1 << 10));
    37. }
    38. else if(kbuf[2] == '1')
    39. {
    40. //开灯
    41. (*vir_led1_odr) |= (0x1 << 10);
    42. }
    43. break;
    44. case '2':
    45. if(kbuf[2] == '0')
    46. {
    47. //关灯
    48. (*vir_led2_odr) &= (~(0x1 << 10));
    49. }
    50. else if(kbuf[2] == '1')
    51. {
    52. //开灯
    53. (*vir_led2_odr) |= (0x1 << 10);
    54. }
    55. break;
    56. case '3':
    57. if(kbuf[2] == '0')
    58. {
    59. //关灯
    60. (*vir_led1_odr) &= (~(0x1 << 8));
    61. }
    62. else if(kbuf[2] == '1')
    63. {
    64. //开灯
    65. (*vir_led1_odr) |= (0x1 << 8);
    66. }
    67. break;
    68. default:
    69. break;
    70. }
    71. return 0;
    72. }
    73. ssize_t mycdev_read(struct file *file,char *ubuf,size_t size,loff_t *lof)
    74. {
    75. printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
    76. int ret = copy_to_user(ubuf,kbuf,size);
    77. if(ret)
    78. {
    79. printk("failed\n");
    80. return -EIO;
    81. }
    82. return 0;
    83. }
    84. int mycdev_close(struct inode *inode,struct file *file)
    85. {
    86. printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
    87. return 0;
    88. }
    89. struct file_operations fops = {
    90. .open = mycdev_open,
    91. .read = mycdev_read,
    92. .write = mycdev_write,
    93. .release = mycdev_close,
    94. };
    95. module_param(a,int,0664);
    96. static int __init mycdev_init(void)
    97. {
    98. printk("a = %d\n",a);
    99. major = register_chrdev(0,"mychrdev",&fops);
    100. if(major < 0)
    101. {
    102. printk("字符设备驱动注册失败\n");
    103. return major;
    104. }
    105. printk("字符设备驱动注册成功 major = %d\n",major);
    106. vir_led1_moder = ioremap(PHY_GPIOE_MODER,4);
    107. if(NULL == vir_led1_moder)
    108. {
    109. printk("物理内存地址映射失败\n");
    110. return -EFAULT;
    111. }
    112. vir_led1_odr = ioremap(PHY_GPIOE_ODR,4);
    113. if(NULL == vir_led1_odr)
    114. {
    115. printk("物理内存地址映射失败\n");
    116. return -EFAULT;
    117. }
    118. vir_rcc = ioremap(PHY_RCC,4);
    119. if(NULL == vir_rcc)
    120. {
    121. printk("物理内存地址映射失败\n");
    122. return -EFAULT;
    123. }
    124. vir_led2_moder = ioremap(PHY_GPIOF_MODER,4);
    125. if(NULL == vir_led2_moder)
    126. {
    127. printk("物理内存地址映射失败\n");
    128. return -EFAULT;
    129. }
    130. vir_led2_odr = ioremap(PHY_GPIOF_ODR,4);
    131. if(NULL == vir_led2_odr)
    132. {
    133. printk("物理内存地址映射失败\n");
    134. return -EFAULT;
    135. }
    136. printk("寄存器内存映射成功\n");
    137. (*vir_rcc) |= (0x1 << 4);
    138. (*vir_rcc) |= (0x1 << 5);
    139. (*vir_led1_moder) &= (~(0x3 << 20)); //led1_moder
    140. (*vir_led1_moder) |= (0x1 << 20);
    141. (*vir_led1_moder) &= (~(0x3 << 16)); //led3_moder
    142. (*vir_led1_moder) |= (0x1 << 16);
    143. (*vir_led1_odr) &= (~(0x1 << 10)); //led1_odr
    144. (*vir_led1_odr) &= (~(0x1 << 8)); //led3_odr
    145. (*vir_led2_moder) &= (~(0x3 << 20)); //led2_moder
    146. (*vir_led2_moder) |= (0x1 << 20);
    147. (*vir_led2_odr) &= (~(0X1 << 10)); //led2_odr
    148. return 0;
    149. }
    150. static void __exit mycdev_exit(void)
    151. {
    152. unregister_chrdev(major,"mychrdev");
    153. }
    154. module_init(mycdev_init);
    155. module_exit(mycdev_exit);
    156. MODULE_LICENSE("GPL");
    1. //test.c
    2. #include<unistd.h>
    3. #include<fcntl.h>
    4. #include<sys/stat.h>
    5. #include<sys/types.h>
    6. #include<stdio.h>
    7. #include<string.h>
    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. return -1;
    16. }
    17. printf("打开设备文件成功\n");
    18. while(1)
    19. {
    20. fgets(buf,sizeof(buf),stdin);
    21. buf[strlen(buf) - 1] = 0;
    22. write(fd,buf,sizeof(buf));
    23. }
    24. //read(fd,buf,sizeof(buf));
    25. memset(buf,0,sizeof(buf));
    26. read(fd,buf,sizeof(buf));
    27. printf("buf:%s\n",buf);
    28. close(fd);
    29. return 0;
    30. }

     

    实验现象:

     

  • 相关阅读:
    typescript:命名空间
    docker 安装 onlyoffice
    LiveMedia视频中间件支持GB35114的设备接入
    Java集合——List接口
    LeetCode 剑指 Offer II 091.粉刷房子 - 原地修改
    (九)Java算法:快速排序(详细图解)
    模糊查询like用法实例(Bee)
    Mac M1下使用Colima替代docker desktop搭建云原生环境
    MATLAB逻辑运算
    JDK安装配置
  • 原文地址:https://blog.csdn.net/a136630108/article/details/133953179