无法在Linux设备驱动程序(橙色PI)中读取/写入I2C寄存器

发布于 2025-01-29 08:42:19 字数 2752 浏览 6 评论 0原文

我正在使用i2c寄存器作为设备驱动程序的配置,但是:

  • 我无法在request_mem_region() - &gt之后读取/编写I2C寄存器; ioremap()。我看到I2C,UART,SPI ...但是我仍然可以与GPIO和计时器一起使用。
  • 在构建发行版之前,我试图在menuconfig中更改配置,但是它是有效的(启用嵌入式系统,启用地图ram ...)。当然,我也尝试了readl()writel()iowrite32()ioread32()。 ..
  • 但是,当我编辑I2C寄存器时,代码在配置发行版时可用并可以在 /dev /iOmem上看到。

我认为RAM访问存在问题。但是如何解决呢?谢谢!

测试后的代码之后:

u8 twi_mem_flag = 0;

int PIOA_Init(void)
{
    if (!request_mem_region(TWI_BASE, 0x400, "TWI_MEM")) {
        printk(KERN_INFO "TWI_MEM is existed\n");
        twi_mem_flag = 1;
    }
    PA_CFG0_REG  = (uint32_t *) ioremap(PA_CFG0, 4);
    PA_PUL0_REG  = (uint32_t *) ioremap(PA_PUL0, 4);
    PA_DATA_REG  = (uint32_t *) ioremap(PA_DAT, 4);
    PA_DRV0_REG  = (uint32_t *) ioremap(PA_DRV0, 4);
    PA_EINT_CFG0_REG   = (uint32_t *) ioremap(PA_EINT_CFG0, 4);
    PA_EINT_CTL_REG    = (uint32_t *) ioremap(PA_EINT_CTL, 4);
    PA_EINT_STATUS_REG = (uint32_t *) ioremap(PA_EINT_STATUS, 4);
    PA_EINT_DEB_REG    = (uint32_t *) ioremap(PA_EINT_DEB, 4);
    
    TWI_ADDR_REG   = (uint32_t *) ioremap(TWI_ADDR, 4);
    TWI_XADDR_REG    = (uint32_t *) ioremap(TWI_XADDR, 4);
    TWI_DATA_REG = (uint32_t *) ioremap(TWI_DATA, 4);
    TWI_CNTR_REG    = (uint32_t *) ioremap(TWI_CNTR, 4);
    
    *PA_CFG0_REG &= ~(0X77 << 24);
    *PA_CFG0_REG |=  (0X01 << 24);

    *PA_PUL0_REG &= ~(0X0f << 12);
    *PA_PUL0_REG |=  (0X05 << 12);

    *PA_EINT_CFG0_REG   = (0x03 << 28);
    *PA_EINT_CTL_REG    = (0x01 << 7);
    *PA_EINT_STATUS_REG     = (0x01 << 7);
    *PA_EINT_DEB_REG    = (0x11);
    
    *TWI_ADDR_REG |= 0x07;
    *TWI_DATA_REG |= 0x77;
    *TWI_CNTR_REG |= 0x05;
    printk( KERN_INFO "GPIO: %x - %x - %x - %x\n", *PA_CFG0_REG, *PA_PUL0_REG, *PA_DATA_REG, *PA_DRV0_REG);
    printk( KERN_INFO "TWI: %x - %x - %x - %x\n", *TWI_ADDR_REG, *TWI_XADDR_REG, *TWI_DATA_REG, *TWI_CNTR_REG);

    return 0;
}

void PIOA_destroy(void)
{
    iounmap(PA_DRV0_REG);
    iounmap(PA_DATA_REG);
    iounmap(PA_CFG0_REG);
    iounmap(PA_PUL0_REG);
    
    iounmap(PA_EINT_CFG0_REG);
    iounmap(PA_EINT_CTL_REG);
    iounmap(PA_EINT_STATUS_REG);
    iounmap(PA_EINT_DEB_REG);
        
    iounmap(TWI_ADDR_REG);
    iounmap(TWI_XADDR_REG);
    iounmap(TWI_DATA_REG);
    iounmap(TWI_CNTR_REG);
    
    if (!twi_mem_flag)
        release_mem_region(TWI_BASE, 0x400);
}
[  228.246399] GPIO: 1227777 - 5400 - 0 - 55555555 
[  228.246420] TWI: 0 - 0 - 0 - 0 
[  228.246428] The blink led device is installed !!

I'm using I2C register to config for device driver but:

  • I cannot read/write I2C register after request_mem_region() -> ioremap(). I see that just happens with I2C, UART, SPI... but I still can use with GPIO and TIMER.
  • I tried to change config in menuconfig before building distro but it's efficient (enable Embedded system, enable map Ram...). Of course, I too tried readl(), writel(), iowrite32(), ioread32()...
  • But code works fine when I edit I2C register that is available when configuring the distro and can see it on /dev/iomem.

I think there is a problem with ram access. But how to fix it? Thanks!

After code for test:

u8 twi_mem_flag = 0;

int PIOA_Init(void)
{
    if (!request_mem_region(TWI_BASE, 0x400, "TWI_MEM")) {
        printk(KERN_INFO "TWI_MEM is existed\n");
        twi_mem_flag = 1;
    }
    PA_CFG0_REG  = (uint32_t *) ioremap(PA_CFG0, 4);
    PA_PUL0_REG  = (uint32_t *) ioremap(PA_PUL0, 4);
    PA_DATA_REG  = (uint32_t *) ioremap(PA_DAT, 4);
    PA_DRV0_REG  = (uint32_t *) ioremap(PA_DRV0, 4);
    PA_EINT_CFG0_REG   = (uint32_t *) ioremap(PA_EINT_CFG0, 4);
    PA_EINT_CTL_REG    = (uint32_t *) ioremap(PA_EINT_CTL, 4);
    PA_EINT_STATUS_REG = (uint32_t *) ioremap(PA_EINT_STATUS, 4);
    PA_EINT_DEB_REG    = (uint32_t *) ioremap(PA_EINT_DEB, 4);
    
    TWI_ADDR_REG   = (uint32_t *) ioremap(TWI_ADDR, 4);
    TWI_XADDR_REG    = (uint32_t *) ioremap(TWI_XADDR, 4);
    TWI_DATA_REG = (uint32_t *) ioremap(TWI_DATA, 4);
    TWI_CNTR_REG    = (uint32_t *) ioremap(TWI_CNTR, 4);
    
    *PA_CFG0_REG &= ~(0X77 << 24);
    *PA_CFG0_REG |=  (0X01 << 24);

    *PA_PUL0_REG &= ~(0X0f << 12);
    *PA_PUL0_REG |=  (0X05 << 12);

    *PA_EINT_CFG0_REG   = (0x03 << 28);
    *PA_EINT_CTL_REG    = (0x01 << 7);
    *PA_EINT_STATUS_REG     = (0x01 << 7);
    *PA_EINT_DEB_REG    = (0x11);
    
    *TWI_ADDR_REG |= 0x07;
    *TWI_DATA_REG |= 0x77;
    *TWI_CNTR_REG |= 0x05;
    printk( KERN_INFO "GPIO: %x - %x - %x - %x\n", *PA_CFG0_REG, *PA_PUL0_REG, *PA_DATA_REG, *PA_DRV0_REG);
    printk( KERN_INFO "TWI: %x - %x - %x - %x\n", *TWI_ADDR_REG, *TWI_XADDR_REG, *TWI_DATA_REG, *TWI_CNTR_REG);

    return 0;
}

void PIOA_destroy(void)
{
    iounmap(PA_DRV0_REG);
    iounmap(PA_DATA_REG);
    iounmap(PA_CFG0_REG);
    iounmap(PA_PUL0_REG);
    
    iounmap(PA_EINT_CFG0_REG);
    iounmap(PA_EINT_CTL_REG);
    iounmap(PA_EINT_STATUS_REG);
    iounmap(PA_EINT_DEB_REG);
        
    iounmap(TWI_ADDR_REG);
    iounmap(TWI_XADDR_REG);
    iounmap(TWI_DATA_REG);
    iounmap(TWI_CNTR_REG);
    
    if (!twi_mem_flag)
        release_mem_region(TWI_BASE, 0x400);
}
[  228.246399] GPIO: 1227777 - 5400 - 0 - 55555555 
[  228.246420] TWI: 0 - 0 - 0 - 0 
[  228.246428] The blink led device is installed !!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文