【问题标题】:Linux device driver - memory mapped I/O example discussionLinux 设备驱动程序 - 内存映射 I/O 示例讨论
【发布时间】:2016-03-27 06:37:20
【问题描述】:

我已经浏览了以下主题,但仍有一些问题。

ioread32 followed by iowrite32 not giving same value

  1. 在链接中,我在哪里可以得到我的base,它被定义为0xfed00000 在帖子中?
  2. 第二个参数应该放什么

    void request_mem_region(unsigned long start, unsigned long len,char *name);

  3. 第二个参数应该放什么

    void *ioremap_nocache(unsigned long phys_addr, unsigned long size);

  4. 通过生成 Makefile 并生成内核模块,我应该使用insmod 然后dmesg 来检查代码是否按预期工作,这样是否正确?

  5. 在这种情况下,我应该在源代码中的return 0; 之前添加iounmap(virtual_base); 吗?

谢谢

【问题讨论】:

  • (1) 它是外设的基(物理)地址。如果它是板上的分立芯片,请查阅电路板文档。如果它是 SoC 中的嵌入式外设,请查阅 SoC 数据表中的内存映射。 (2) & (3) 长度/大小是外设的寄存器集占用的字节数。有时会指定下一个外围设备的整个内存区域。 (5) 哪个返回语句?如果 ioremap() 在驱动程序的探测例程中执行,则 iounmap() 应该在探测器的错误出口 在驱动程序的删除例行公事。
  • @sawdust 谢谢,你能把它作为答案发给我吗?
  • @第(4)项,我认为唯一的方法是通过dmesg,还有其他更简单的方法来检查结果吗?

标签: linux memory io linux-device-driver


【解决方案1】:
  1. 在链接中,我在哪里可以得到我在帖子中定义为 0xfed00000 的基数?

它是外设寄存器的基(物理)地址。
如果外围设备是板上的分立芯片,请查阅电路板文档。
如果外设嵌入在 SoC 中,请查阅 SoC 数据表中的内存映射。

  1. 第二个参数应该放什么
void request_mem_region(unsigned long start, unsigned long len,char *name);
  1. 第二个参数应该放什么
void *ioremap_nocache(unsigned long phys_addr, unsigned long size);

这两个例程应该使用相同的第一个和第二个参数来调用。
长度/大小是外设的寄存器集占用的字节数。
有时会指定下一个外围设备的整个内存区域。

  1. 通过 Makefile 并生成内核模块,我应该使用 insmod 然后 dmesg 来检查代码是否按预期工作,这样是否正确?

明智地散布 printk() 语句是测试 Linux 内核驱动程序/模块的可靠方法。
Unix 有 kdb

  1. 在这种情况下,我应该添加 iounmap(virtual_base);返回 0 之前;在源代码中?

不要复制那个写得很糟糕的初始化代码示例。
如果 ioremap() 在驱动程序的 probe()(或其他初始化)例程中执行,则 iounmap() 应该在探针的驱动程序的 remove()(或对 init 的补充)例程中的错误退出序列
Linux 内核源代码中有许多示例可供研究。使用在线 Linux 交叉引用,例如 http://lxr.free-electrons.com/source/
请注意,几乎所有 Linux 驱动程序都会使用 iounmap() 两次或更多次。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-05-27
    • 2015-07-17
    • 2014-03-10
    • 1970-01-01
    • 2017-05-17
    • 2017-06-08
    • 2011-01-19
    • 1970-01-01
    相关资源
    最近更新 更多