Rk3568驱动开发_点亮led灯(手动挡)_5

[复制链接]
发表于 2025-10-22 11:09:15 | 显示全部楼层 |阅读模式
1.MMU简介

完成捏造空间到物理空间的映射
内存掩护设立存储器的访问权限,设置捏造存储空间的缓冲特性

stm32点灯可以直接利用寄存器,但是linux点灯不能直接访问寄存器,linux会使能mmu

linux中利用的都是捏造地点,要想访问物理地点0x0a就得先搞清晰0xa对应的捏造地点
得到物理地点对应的捏造地点使用ioremap函数,本质是个宏,参数分别是物理地点启始巨细,要转换的字节数目
卸载驱动的时间用iounmap()卸载映射
stm32没有这个MMU其控制gpio直接利用寄存器就行,在linux上由于这个内存映射在,必要知道真实物理地点,反推其捏造地点才华像stm32一样利用寄存器
linux做驱动有设置装备树更高级的利用方式,像这种利用寄存器的恰似手动档
2.代码

驱动:
  1. #include <linux/module.h>
  2. #include <linux/kernel.h>
  3. #include <linux/init.h>
  4. #include <linux/fs.h>
  5. #include <linux/slab.h>
  6. #include <linux/uaccess.h>
  7. #include <linux/io.h>
  8. #define LED_MAJOR 200
  9. #define LED_NAME "led"
  10. #define PMU_GRF_BASE                                                      (0xFDC20000)
  11. #define PMU_GRF_GPIO0C_IOMUX_L                                (PMU_GRF_BASE + 0x0010)
  12. #define PMU_GRF_GPIO0C_DS_0                                          (PMU_GRF_BASE + 0X0090)
  13. #define GPIO0_BASE                                                        (0xFDD60000)
  14. #define GPIO0_SWPORT_DR_H                                      (GPIO0_BASE + 0X0004)
  15. #define GPIO0_SWPORT_DDR_H                                    (GPIO0_BASE + 0X000C)
  16. /* 映射后的寄存器虚拟地址指针 */
  17. static void __iomem *PMU_GRF_GPIO0C_IOMUX_L_PI;
  18. static void __iomem *PMU_GRF_GPIO0C_DS_0_PI;
  19. static void __iomem *GPIO0_SWPORT_DR_H_PI;
  20. static void __iomem *GPIO0_SWPORT_DDR_H_PI;
  21. static int led_open(struct inode* inode, struct file* filp){
  22.   return 0;
  23. }
  24. static int led_release(struct inode* inode, struct file* filp){
  25.   return 0;
  26. }
  27. static ssize_t led_write(struct file* filp, const char __user* buf, size_t count, loff_t* ppos){
  28.   return 0;
  29. }
  30. /* 字符设备操作集*/
  31. static const struct file_operations led_fops = {
  32.   .owner = THIS_MODULE,
  33.   .write = led_write,
  34.   .open = led_open,
  35.   .release = led_release,
  36. };
  37. /*注册驱动加载卸载*/
  38. static int __init led_init(void){ // 入口
  39.   // 初始化led灯
  40.   int ret = 0;
  41.   u32 val = 0;
  42.   PMU_GRF_GPIO0C_IOMUX_L_PI = ioremap(PMU_GRF_GPIO0C_IOMUX_L, 4);
  43.         PMU_GRF_GPIO0C_DS_0_PI = ioremap(PMU_GRF_GPIO0C_DS_0, 4);
  44.         GPIO0_SWPORT_DR_H_PI = ioremap(GPIO0_SWPORT_DR_H, 4);
  45.         GPIO0_SWPORT_DDR_H_PI = ioremap(GPIO0_SWPORT_DDR_H, 4);
  46.   // 初始化
  47.   // 设置GPIO0_c0为GPIO功能
  48.   val = readl(PMU_GRF_GPIO0C_IOMUX_L_PI);
  49.   val &= ~(0x7 << 0); //最低三位置0
  50.   val |= ((0x7 << 16) | (0x0 << 0)); // 16 17 18位置1其他不变,bit2:0:0,用作GPIO0_C0
  51.   writel(val, PMU_GRF_GPIO0C_IOMUX_L_PI);
  52.   // 设置GPIO_C0驱动能力为level5
  53.   val = readl(PMU_GRF_GPIO0C_DS_0_PI);
  54.   val &= ~(0x3f << 0);  // 0 ~ 5置0
  55.   val |= ((0x3f << 16) | (0x3f << 0)); // 16 ~ 21置1,0~5置1同时用作GPIO0c0
  56.   writel(val, PMU_GRF_GPIO0C_DS_0_PI);
  57.   // 设置GPIOO0_c0为输出
  58.   val = readl(GPIO0_SWPORT_DDR_H_PI);
  59.   val &= ~(0x1 << 0); // 0置0
  60.   val |= ((0x1 << 16) | (0x1 << 0)); // 16置1,0置1
  61.   writel(val, GPIO0_SWPORT_DDR_H_PI);
  62.   // 设置GPIO_c0为低电平,关闭LED
  63.   val = readl(GPIO0_SWPORT_DR_H_PI);
  64.   val &= ~(0x1 << 0);
  65.   val |= ((0x1 << 16) | (0x0 << 0));
  66.   writel(val, GPIO0_SWPORT_DR_H_PI);
  67.   // 开灯
  68.   val = readl(GPIO0_SWPORT_DR_H_PI);
  69.   val &= ~(0X1 << 0); /* bit0 清零*/
  70.   val |= ((0X1 << 16) | (0X1 << 0));        /* bit16 置1,允许写bit0,
  71.                          bit0,高电平*/
  72.   writel(val, GPIO0_SWPORT_DR_H_PI);  
  73.   
  74.   // 注册字符设备
  75.   ret = register_chrdev(LED_MAJOR, LED_NAME, &led_fops);
  76.   if(ret < 0){
  77.     printk("register chrdev failed!\r\n");
  78.     return -EIO;
  79.   }
  80.   printk("led_init\r\n");
  81.   return 0;
  82. }
  83. static void __exit led_exit(void){ // 出口
  84.   u32 val = 0;
  85.   // 关灯
  86.   val = readl(GPIO0_SWPORT_DR_H_PI);
  87.   val &= ~(0X1 << 0); /* bit0 清零*/
  88.   val |= ((0X1 << 16) | (0X0 << 0));        /* bit16 置1,允许写bit0,
  89.                          bit0,低电平        */
  90.   writel(val, GPIO0_SWPORT_DR_H_PI);
  91.   // 取消地址映射
  92.   iounmap(PMU_GRF_GPIO0C_IOMUX_L_PI);
  93.   iounmap(PMU_GRF_GPIO0C_DS_0_PI);
  94.   iounmap(GPIO0_SWPORT_DR_H_PI);
  95.   iounmap(GPIO0_SWPORT_DDR_H_PI);
  96.   // 注销
  97.   unregister_chrdev(LED_MAJOR, LED_NAME);
  98.   printk("led_exit\r\n");
  99. }
  100. module_init(led_init);
  101. module_exit(led_exit);
  102. MODULE_LICENSE("GPL");
  103. MODULE_AUTHOR("Narnat");
复制代码
ioremap(PMU_GRF_GPIO0C_IOMUX_L, 4);将物理地点转捏造内存
在步调挂载时初始化一些寄存器,并点亮led灯,卸载时关闭led灯
3.征象:






免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表