首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用writel将4位写入到ioremap ed内存地址

使用writel将4位写入到ioremap ed内存地址
EN

Stack Overflow用户
提问于 2017-04-02 05:36:36
回答 1查看 5.3K关注 0票数 2

我对内核编程很陌生,现在我试图在设备驱动程序中将一些值写入32位GPIO寄存器。I/O是到内存地址的ioremap()-ed。问题是,我不知道writel()/writeb()/writew()是如何将位写入地址的。

供应商的文件上说注册在0xE5200000上。我必须写入的位是[0:3]位,剩下的28位( [4:31]位)为零。

这是我到目前为止编写的设备驱动程序中代码的一部分:

代码语言:javascript
复制
#define TCON_ADDR 0xE250000 // The address as provided by the vendor
static void *TIMER_CON_ADDR;
// I have to map and write to the address when the device is opened
static int on_dev_open(struct inode *inode, struct file *file) {
    unsigned int data;
    TIMER_CON_ADDR = ioremap(TCON_ADDR, 4); // Map the [0:4] bits to TIMER_CON_ADDR
    data = 4; // 0100 in binary
    writel(data, TIMER_CON_ADDR); // Write 0100 to TIMER_CON_ADDR
    return 0;
}

上面的代码可能对大家来说都是胡说八道,但我对write(l|w|b)ioremap()并不熟悉。

所以我的问题是:

  1. 我是否正确地将[0:4]位映射到TIMER_CON_ADDR?
  2. 如果没有,我如何正确地映射它们?
  3. 在正确映射4位之后,如何使用任何write(1|w|b)函数以正确的顺序将位(0100)写入TIMER_CON_ADDR?
  4. write(l|w|b)在引擎盖下做什么来写位呢?
  5. 有什么信息我漏掉了吗?

谢谢你提前提供帮助。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-04-02 08:22:32

  1. 我是否正确地将[0:4]位映射到TIMER_CON_ADDR?

不,你写32位,writel写4字节,4*8=32位

  1. 如果没有,我如何正确地映射它们?

无法映射4位,最小8位=1字节,但是如果您使用32位寄存器,则需要map 32位=4字节。也不要忘记检查和处理错误。

  1. 在正确映射4位之后,如何使用任何write(1|w|b)函数以正确的顺序将位(0100)写入TIMER_CON_ADDR?

您需要使用readl,内核中充满了示例,只需在linux内核源代码树的grep子目录中运行drivers。一般想法读/写:

代码语言:javascript
复制
u32 reg = readl(TIMER_CON_ADDR);
reg &= ~0xfu;
reg |= 4;
writel(reg, TIMER_CON_ADDR);

  1. write(l|w|b)在引擎盖下做什么来写位呢?

看看源代码,它只是简单的C函数,比如:

代码语言:javascript
复制
static inline void __raw_writel(u32 value, volatile void __iomem *addr)
{
    *(volatile u32 __force *)addr = value;
}

主要的想法是告诉编译器,它不应该删除您的内存读写。

  1. 有什么信息我漏掉了吗?

阅读类似驱动程序的源代码,它已经包含了此类简单驱动程序的几乎所有解决方案。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43164988

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档