- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
我正在为运行 Linux 2.6.37 的 ARM 设备开发。我正在尝试尽快切换 IO 引脚。我制作了一个小内核模块和一个用户空间应用程序。我尝试了两件事:
ioremap
直接从内核空间操作 GPIO 控制寄存器。mmap()
GPIO 控制寄存器,无需缓存并从用户空间使用它们。这两种方法都有效,但第二种方法比第一种方法慢 3 倍左右(在示波器上观察到)。我想我禁用了所有缓存机制。
当然,我想获得两个世界中最好的:用户空间的灵 active 和易于开发以及内核空间的速度。
有人知道为什么 mmap()
可能比 ioremap()
慢吗?
这是我的代码:
static int ti81xx_usmap_mmap(struct file* pFile, struct vm_area_struct* pVma)
{
pVma->vm_flags |= VM_RESERVED;
pVma->vm_page_prot = pgprot_noncached(pVma->vm_page_prot);
if (io_remap_pfn_range(pVma, pVma->vm_start, pVma->vm_pgoff,
pVma->vm_end - pVma->vm_start, pVma->vm_page_prot))
return -EAGAIN;
pVma->vm_ops = &ti81xx_usmap_vm_ops;
return 0;
}
static void ti81xx_usmap_test_gpio(void)
{
u32* pGpIoRegisters = ioremap_nocache(TI81XX_GPIO0_BASE, 0x400);
const u32 pin = 1 << 24;
int i;
/* I should use IO read/write functions instead of pointer deferencing,
* but portability isn't the issue here */
pGpIoRegisters[OMAP4_GPIO_OE >> 2] &= ~pin; /* Set pin as output*/
for (i = 0; i < 200000000; ++i)
{
pGpIoRegisters[OMAP4_GPIO_SETDATAOUT >> 2] = pin;
pGpIoRegisters[OMAP4_GPIO_CLEARDATAOUT >> 2] = pin;
}
pGpIoRegisters[OMAP4_GPIO_OE >> 2] |= pin; /* Set pin as input*/
iounmap(pGpIoRegisters);
}
int main(int argc, char** argv)
{
int file, i;
ulong* pGpIoRegisters = NULL;
ulong pin = 1 << 24;
file = open("/dev/ti81xx-usmap", O_RDWR | O_SYNC);
if (file < 0)
{
printf("open failed (%d)\n", errno);
return 1;
}
printf("Toggle from kernel space...");
fflush(stdout);
ioctl(file, TI81XX_USMAP_IOCTL_TEST_GPIO);
printf(" done\n");
pGpIoRegisters = mmap(NULL, 0x400, PROT_READ | PROT_WRITE, MAP_SHARED, file, TI81XX_GPIO0_BASE);
printf("Toggle from user space...");
fflush(stdout);
pGpIoRegisters[OMAP4_GPIO_OE >> 2] &= ~pin;
for (i = 0; i < 30000000; ++i)
{
pGpIoRegisters[OMAP4_GPIO_SETDATAOUT >> 2] = pin;
pGpIoRegisters[OMAP4_GPIO_CLEARDATAOUT >> 2] = pin;
}
pGpIoRegisters[OMAP4_GPIO_OE >> 2] |= pin;
printf(" done\n");
fflush(stdout);
munmap(pGpIoRegisters, 0x400);
close(file);
return 0;
}
最佳答案
这是因为 ioremap_nocache() 仍然在您的 VM 映射中启用 CPU 写入缓冲区,而 pgprot_noncached() 禁用缓冲性和缓存性。
同类比较将改为使用 ioremap_strongly_ordered()。
关于linux - mmap 比 ioremap 慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10928978/
我正在开发一个 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。 我想使
我是一名优秀的程序员,十分优秀!