• 驱动——LED灯循环闪烁


     使用结构体形式对寄存器地址进行映射,实现3盏LED灯的循环点亮

    1、创建LED灯点亮所需要的GPIO寄存器的结构体,并对寄存器地址进行宏定义

     2、①通过ioremap函数将物理地址映射为虚拟地址

    void* ioremap(phys_addr_t offset, size_t size)

    函数功能:将物理地址映射为虚拟地址

    参数:

    @offset:物理地址

    @size:映射大小,单位字节

    返回值: 成功返回虚拟地址,失败返回NULL

    ②通过映射的虚拟地址对寄存器进行初始化

    3、通过copy_from_user函数从用户空间读取信息,对要进行操作的灯进行判断,并对相应寄存器进行操作

    int copy_from_user(void *to, const void __user volatile *from, unsigned long n)

    函数功能:将数据从用户空间拷贝到内核空间

    参数:

    @to:内核空间首地址

    @from:用户空间首地址

    @ n:拷贝数据大小(以字节为单位)

    返回值: 成功返回0 失败返回未拷贝的字节数

     4、通过iounmap取消对寄存器的映射

    void iounmap(void __iomem *addr)

    函数功能:取消映射

    参数:

     

    @offset:映射之后的虚拟地址

    返回值: 无

    附实现代码

    测试代码:

    1. #include
    2. #include
    3. #include
    4. #include
    5. #include
    6. #include
    7. #include
    8. char buf[128] = {0};
    9. int main(int argc, const char *argv[])
    10. {
    11. int fd = -1;
    12. int i=0;
    13. fd = open("/dev/led",O_RDWR);
    14. if(-1 == fd)
    15. {
    16. perror("open is error");
    17. exit(1);
    18. }
    19. while(1)
    20. {
    21. buf[0]='1';
    22. buf[1]='1';
    23. write(fd,buf,sizeof(buf));
    24. sleep(1);
    25. buf[1]='0';
    26. write(fd,buf,sizeof(buf));
    27. sleep(1);
    28. buf[0]='2';
    29. buf[1]='1';
    30. write(fd,buf,sizeof(buf));
    31. sleep(1);
    32. buf[1]='0';
    33. write(fd,buf,sizeof(buf));
    34. sleep(1);
    35. buf[0]='3';
    36. buf[1]='1';
    37. write(fd,buf,sizeof(buf));
    38. sleep(1);
    39. buf[1]='0';
    40. write(fd,buf,sizeof(buf));
    41. }
    42. close(fd);
    43. return 0;
    44. }
    1. #ifndef __LED_H__
    2. #define __LED_H__
    3. typedef struct{
    4. volatile unsigned int MODER;
    5. volatile unsigned int OTYPER;
    6. volatile unsigned int OSPEEDR;
    7. volatile unsigned int PUPDR;
    8. volatile unsigned int IDR;
    9. volatile unsigned int ODR;
    10. }gpio_t;
    11. #define GPIOE_ADDR 0x50006000
    12. #define GPIOF_ADDR 0x50007000
    13. #define RCC_ADDR 0x50000A28
    14. #endif

     功能代码

    1. #include
    2. #include
    3. #include
    4. #include
    5. #include
    6. #include"./led.h"
    7. #define GNAME "mydev"
    8. volatile gpio_t* VIRT_GPIOE;
    9. volatile gpio_t* VIRT_GPIOF;
    10. volatile unsigned int* VIRT_RCC;
    11. int major;
    12. char kbuf[128]={0};
    13. int mydev_open(struct inode *inode, struct file *file)
    14. {
    15. printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
    16. return 0;
    17. }
    18. ssize_t mydev_read(struct file *file, char __user *ubuf, size_t size, loff_t *loff)
    19. {
    20. int set;
    21. printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
    22. if(size > sizeof(kbuf)) size = sizeof(kbuf);
    23. set = copy_to_user(ubuf,kbuf,size);
    24. if(set)
    25. {
    26. printk("copy to user is error\n");
    27. return -EIO;
    28. }
    29. return size;
    30. }
    31. ssize_t mydev_write(struct file *file, const char __user *ubuf, size_t size, loff_t *loff)
    32. {
    33. int ret;
    34. printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
    35. if(size > sizeof(kbuf)) size = sizeof(kbuf);
    36. ret = copy_from_user(kbuf,ubuf,size);
    37. if(ret)
    38. {
    39. printk("copy from user is error\n");
    40. return -EIO;
    41. }
    42. printk("copy from user kbuf = %s\n",kbuf);
    43. switch(kbuf[0])
    44. {
    45. case '1':
    46. if(kbuf[1]=='1')
    47. {
    48. VIRT_GPIOE->ODR |= (0x1<<10);
    49. }
    50. else if(kbuf[1]=='0')
    51. {
    52. VIRT_GPIOE->ODR &= (~(0x1<<10));
    53. }
    54. break;
    55. case '3':
    56. if(kbuf[1]=='1')
    57. {
    58. VIRT_GPIOE->ODR |= (0x1<<8);
    59. }
    60. else if(kbuf[1]=='0')
    61. {
    62. VIRT_GPIOE->ODR &= (~(0x1<<8));
    63. }
    64. break;
    65. case '2':
    66. if(kbuf[1]=='1')
    67. {
    68. VIRT_GPIOF->ODR |= (0x1<<10);
    69. }
    70. else if(kbuf[1]=='0')
    71. {
    72. VIRT_GPIOF->ODR &= (~(0x1<<10));
    73. }
    74. break;
    75. }
    76. return size;
    77. }
    78. int mydev_close(struct inode *inode, struct file *file)
    79. {
    80. printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
    81. return 0;
    82. }
    83. struct file_operations fops={
    84. .open=mydev_open,
    85. .read=mydev_read,
    86. .write=mydev_write,
    87. .release=mydev_close,
    88. };
    89. static int __init mydev_init(void)
    90. {
    91. major=register_chrdev(0,GNAME,&fops);
    92. if(major<0)
    93. {
    94. printk("register file\n");
    95. return major;
    96. }
    97. printk("major=%d\n",major);
    98. VIRT_RCC = ioremap(RCC_ADDR,4);
    99. if(NULL == VIRT_RCC)
    100. {
    101. printk("VIRT_RCC error\n");
    102. return -ENXIO;
    103. }
    104. VIRT_GPIOE = ioremap(GPIOE_ADDR,4);
    105. if(NULL == VIRT_GPIOE)
    106. {
    107. printk("VIRT_GPIOE error\n");
    108. return -ENXIO;
    109. }
    110. VIRT_GPIOF = ioremap(GPIOF_ADDR,4);
    111. if(NULL == VIRT_GPIOF)
    112. {
    113. printk("VIRT_GPIOF error\n");
    114. return -ENXIO;
    115. }
    116. *VIRT_RCC |= (0x3<<4);
    117. VIRT_GPIOE->MODER &= (~(0x3<<20));
    118. VIRT_GPIOE->MODER |= (0x1<<20);
    119. VIRT_GPIOE->ODR &= (~(0x1<<10));
    120. VIRT_GPIOE->MODER &= (~(0x3<<16));
    121. VIRT_GPIOE->MODER |= (0x1<<16);
    122. VIRT_GPIOE->ODR &= (~(0x1<<8));
    123. VIRT_GPIOF->MODER &= (~(0x3<<20));
    124. VIRT_GPIOF->MODER |= (0x1<<20);
    125. VIRT_GPIOF->ODR &= (~(0x1<<10));
    126. return 0;
    127. }
    128. static void __exit mydev_exit(void)
    129. {
    130. unregister_chrdev(major,GNAME);
    131. iounmap(VIRT_GPIOE);
    132. iounmap(VIRT_GPIOF);
    133. iounmap(VIRT_RCC);
    134. }
    135. module_init(mydev_init);
    136. module_exit(mydev_exit);
    137. MODULE_LICENSE("GPL");

    led

  • 相关阅读:
    Mysql 锁学习笔记
    启明云端ESP32 C3 模组WT32C3通过 MQTT 连接 AWS
    MySQL迁移数据目录(2022.11.01)
    Go基础(待更新)
    【Designing ML Systems】第 7 章 :模型部署和预测服务
    网络协议五
    2022 RedisDays 内容揭秘
    XML——基本语法及使用规则
    基于Python实现情感分析实验
    企业集中监控体系思路及架构
  • 原文地址:https://blog.csdn.net/ww1106/article/details/127892007