- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我是内核编程新手,现在尝试将一些值写入设备驱动程序中的 32 位 GPIO 寄存器。 I/O 为ioremap()
-ed 到内存地址。问题是,我不知道怎么办writel()
/writeb()
/writew()
将位写入地址。
供应商文件显示寄存器位于 0xE5200000
。我必须写入的位是 [0:3]
位并将剩余 28 位([4:31]
位)保留为零。
这是我迄今为止编写的设备驱动程序中的代码的一部分:
#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()
.
所以我的问题是:
[0:4]
位到 TIMER_CON_ADDR 是否正确?write(1|w|b)
中的任何一个函数以正确的顺序将位 ( 0100
) 写入 TIMER_CON_ADDR?write(l|w|b)
是什么意思?在幕后写位吗?感谢您提前提供的所有帮助。
最佳答案
- Did I map the
[0:4]
bits to TIMER_CON_ADDR correctly?
不,你写32位,writel
写4个字节,4 * 8 = 32位
- If not, how do I map them correctly?
无法映射 4 位,最小 8 位 = 1 个字节,但如果您使用 32 位注册您需要映射 32 位 = 4 字节。也不要忘记检查和处理错误。
- After I have correctly mapped the 4 bits, how do I use any of the
write(1|w|b)
functions to write bits (0100
) to TIMER_CON_ADDR in the correct order?
您需要使用 readl,内核中充满了示例,只需在 Linux 内核源代码树的 drivers
子目录中运行 grep
即可。读/写总体思路:
u32 reg = readl(TIMER_CON_ADDR);
reg &= ~0xfu;
reg |= 4;
writel(reg, TIMER_CON_ADDR);
- What does
write(l|w|b)
do under the hood to write bits?
看源代码,它只是简单的C函数,例如:
static inline void __raw_writel(u32 value, volatile void __iomem *addr)
{
*(volatile u32 __force *)addr = value;
}
主要思想是告诉编译器它不应该删除你的内存读/写
- Is there any information I've missed / got wrong?
看过类似驱动的源码,已经包含了差不多了这些简单驱动程序的所有解决方案。
关于c - 使用 writel 将 4 位写入 ioremap 内存地址,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43164988/
我正在开发一个 Linux 内核驱动程序,它为用户空间提供一块物理内存。我有驱动程序的工作版本,但目前速度很慢。所以,我退回了几步,尝试制作一个小巧、简单的驱动程序来重现问题。 我在启动时使用内核参数
我有一个 ARM 目标。 我需要读出一个物理地址。该地址是并行 NOR 闪存中的一个位置。ROM直接在地址总线上。 如果我创建一个模块: if ((rmap = ioremap(ROM_BASE
我正在尝试为 Raspberry PI 创建自定义 UART 驱动程序。我尝试重新映射 MMIO。但是ioremap总是返回NULL。 #define UART_REG_BASE_ADDR 0x7E
在 Linux 内核中,为什么不建议取消引用通过使用 ioremap 映射 I/O 物理地址获得的内核线性地址?为什么要使用 readl/writel 等函数取消引用那些映射的线性地址? 最佳答案 某
我正在尝试访问 Linux 中 am335x 处理器上的给定内存区域。这个想法是首先指定物理地址,然后使用 ioremap 访问所述地址。我已经在谷歌上搜索这个问题一段时间了,但似乎找不到任何好的解决
有什么方法可以对 ioremap 返回的虚拟地址进行 DMA 最佳答案 仅当系统有一个 IOMMU ,一个仅用于 I/O 的内存管理单元(这并不常见)。 由于驱动程序提供了物理内存地址来执行 iore
Ioremap 是在内核模式下完成的。ioremap 是否在页表中创建条目 ioremap的调用还是访问地址的时候? 最佳答案 对于ioremap,页表是立即更新的。由于该函数旨在将物理“I/O”地址
我正在为 Linux 开发一个简单的驱动程序,它将通过 SPI 与设备通信。在我使用 request_mem_region 和 ioremap 之后,我可以从返回的地址读取的所有内容都是 0即使我给它
所以,对于内核驱动程序,我是一个新手,并且对 ioremap 函数有疑问。 我正在编写一个驱动程序,用于访问在具有 ARM Cortex-M3 和 FPGA 结构的 SoC 上的自定义 VHDL 模块
我需要从内核中保留一个大的物理连续 RAM 缓冲区,并能够保证该缓冲区将始终使用特定的硬编码物理地址。该缓冲区应在内核的整个生命周期内保留。我已经编写了一个 chardev 驱动程序作为在用户空间中访
我正在为运行 Linux 2.6.37 的 ARM 设备开发。我正在尝试尽快切换 IO 引脚。我制作了一个小内核模块和一个用户空间应用程序。我尝试了两件事: 使用 ioremap 直接从内核空间操作
我使用 memmap=8G$4G Linux 内核启动参数保留内存块。 是否需要ioremap此内存? ioremap 手册页说: ioremap performs a platform specif
假设我有一些物理地址(这是我的 DMA 源外设的总线位置): phys_addr = 0xffff0000; 我这样做: virt_addr = ioremap(phys_addr, PAGE_SIZ
我是内核编程新手,现在尝试将一些值写入设备驱动程序中的 32 位 GPIO 寄存器。 I/O 为ioremap() -ed 到内存地址。问题是,我不知道怎么办writel()/writeb()/wri
我正在更改 linux 内核调度程序以在已知物理内存位置打印下一个进程的 pid。 mmap 用于用户空间程序,而我读到 ioremap 将页面标记为不可缓存,这会减慢程序的执行速度。我想要一种快速写
我正在尝试编写一个在 RPI3 上读取 GPIO 的内核驱动程序(模块) 我使用 ioremap 访问 GPIO 的内存,但显然它崩溃了。 我在/var/log/messages 日志文件中得到一个异
我正在编写一个示例应用程序,用于读取寄存器并在给定的 SPI 设备地址上写入特定值。 我使用 altera spi 1.0 驱动程序,在注册 spi 设备时获得基地址为 0xE5002460。 我想使
我是一名优秀的程序员,十分优秀!