This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Linux/AM5708: Problems with a direct access to I2C registers via /dev/mem

Part Number: AM5708

Tool/software: Linux

Hello,

I've loaded linux compiled with arago-project to my device with am5708.

root@am5708-p38:~# uname -r
4.14.79-gbde58ab01e

And I need an access to registers in userspace for debug purposes. I used next implementation for that - 

void *mem::alloc_phy_to_virt(int *fd, void *map_base, off_t target)
{

    if((*fd = open("/dev/mem", O_RDWR | O_SYNC)) == -1)
    {
       std::cout << "alloc_phy_to_virt: error open /dev/mem." << std::endl;
       return NULL;
    }
    else
       std::cout << "/dev/mem opened." << std::endl;

    /* Map one page */
    map_base = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, *fd, target & ~MAP_MASK);
    if(map_base == (void *) -1){
       std::cout << "alloc_phy_to_virt: error Memory mapped." << std::endl;
       close(*fd);
       return NULL;
    }
   else
      std::cout << "alloc_phy_to_virt: memory mapped at address " << map_base << std::endl;

    return (void*)((uint32_t) map_base + (target & MAP_MASK));
}

void mem::free_phy_to_virt(int fd, void *map_base)
{
    munmap(map_base, MAP_SIZE);
    close(fd);
}

int main(int argc, char *argv[]) {
	void *map_base = NULL;
	int fd;
	void *virt_addr_base = mem::alloc_phy_to_virt(&fd, map_base, 0x48070024);//0x4B300000);//0x48070000);
	uint32_t* virt_addr = (uint32_t*)((uint32_t)virt_addr_base);
	printf("reg - 0x%08X\n", virt_addr[0]);
        mem::free_phy_to_virt(fd, map_base);
        return 0;
}

It has worked well for GMPC, QSPI and GPIOs but when I tried to get an access to I2C register(0x48070000) I have got next - 

root@am5708-p38:~# ./scr reg
/dev/mem opened.
alloc_phy_to_virt: memory mapped at address 0xb6fa9000[   49.320255] ------------[ cut here ]------------
[   49.329580] WARNING: CPU: 0 PID: 495 at /media/test/f9423bc8-ed41-49e0-b1d0-35027338ce86/sitara_sdk/tisdk/build/arago-tmp-external-linaro-toolchain/work-shared/am5708-p38/kernel-source/drivers/bus/omap_l3_noc.c:147 l3_interrupt_handler+0x254/0x370
[   49.351890] ---[ end trace eacf642e1763cabe ]---

[   49.356659] Unhandled fault: asynchronous external abort (0x1211) at 0x00000000
[   49.364059] pgd = ee698200
[   49.366773] [00000000] *pgd=ae695003, *pmd=be146003
reg - 0x00000000

Or, when I try again - 

root@am5708-p38:~# ./scr reg
/dev/mem opened.[ 1330.570524] ------------[ cut here ]------------
[ 1330.576489] WARNING: CPU: 0 PID: 512 at /media/test/f9423bc8-ed41-49e0-b1d0-35027338ce86/sitara_sdk/tisdk/build/arago-tmp-external-linaro-toolchain/work-shared/am5708-p38/kernel-source/drivers/bus/omap_l3_noc.c:147 l3_interrupt_handler+0x254/0x370
[ 1330.598797] ---[ end trace eacf642e1763cabf ]---

alloc_phy_to_virt: memory mapped at address 0xb6fed000
[ 1330.603516] Unhandled fault: asynchronous external abort (0x1211) at 0x00000000
[ 1330.615863] pgd = ee56f6c0
[ 1330.618577] [00000000] *pgd=ae560003, *pmd=00000000
reg - 0x00000000
root@am5708-p38:~# [ 1331.339420] systemd[1]: systemd-journald.service: Failed with result 'core-dump'.
[ 1331.366133] systemd[1]: systemd-journald.service: Service has no hold-off time, scheduling restart.
[ 1331.393472] systemd[1]: Stopped Flush Journal to Persistent Storage.
[ 1331.399902] systemd[1]: Stopping Flush Journal to Persistent Storage...
[ 1331.421555] systemd[1]: Stopped Journal Service.
[ 1331.442148] systemd[1]: Starting Journal Service...
[ 1331.474550] systemd-journald[514]: File /run/log/journal/64c35a795d984b958ae610cc1ae46839/system.journal corrupted or uncleanly shut down, renaming and replacing.
[ 1331.538470] systemd[1]: Started Journal Service.
[ 1332.502227] systemd-coredump[513]: MESSAGE=Process 61 (systemd-journal) of user 0 dumped core.
[ 1332.510891] systemd-coredump[513]: Coredump diverted to /var/lib/systemd/coredump/core.systemd-journal.0.57adaf7be91f4ad58f7d2b96fd8b1a7f.61.1550493254000000.xz

I was trying change a word size and access mode, but without any success.

  • Hi Vladimir,

    First you need to ensure that I2C1 module is enabled in device PRCM module, check register value of CM_L4PER_I2C1_CLKCTRL.

    I2C1 module should be enabled in your kernel DTS file, status "okay".

    You can also use devmem2 and/or omapconf tools to access registers in userspace.

    Regards,
    Pavel
  • Oh, big thanks, the module was switched off in clkctrl. When it had been switched on I could get access to registers.
    The strange thing, i2c1 has status "okay" in my dts file. Anyway, thank you for help.