gpt4 book ai didi

linux - mmap 比 ioremap 慢

转载 作者:IT王子 更新时间:2023-10-28 23:54:48 27 4
gpt4 key购买 nike

我正在为运行 Linux 2.6.37 的 ARM 设备开发。我正在尝试尽快切换 IO 引脚。我制作了一个小内核模块和一个用户空间应用程序。我尝试了两件事:

  1. 使用 ioremap 直接从内核空间操作 GPIO 控制寄存器。
  2. 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/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com