V10lator
Posts: 39
Joined: Wed Jul 07, 2021 11:18 am

AT24: mmap failed: No such device

Sun Sep 26, 2021 2:26 am

I wrote this small device tree overlay:

Code: Select all

// Definitions for at24c32
/dts-v1/;
/plugin/;

/{
        compatible = "brcm,bcm2835";

        fragment@0 {
                target = <&i2c_arm>;
                __overlay__ {
                        #address-cells = <1>;
                        #size-cells = <0>;
                        status = "okay";

                        at24: at24@57 {
                                compatible = "microchip,24c32", "atmel,24c32";
                                reg = <0x57>;
                                size = <4096>;
                                pagesize = <32>;
                                status = "okay";
                        };
                };
        };
};
This works: A file named /sys/class/i2c-dev/i2c-1/device/1-0057/eeprom is available and I'm able to read and write to it. So I wanted to start utilizing it in code:

Code: Select all

        int fd = open("/sys/class/i2c-dev/i2c-1/device/1-0057/eeprom", O_RDWR | O_SYNC);
        if(fd < 0)
        {
                fprintf(stderr, "[AT24 DRIVER] Error opening sys file!\n");
                return false;
        }

        struct stat fs;
        if(fstat(fd, &fs) < 0)
        {
                fprintf(stderr, "[AT24 DRIVER] Error getting stats.\n");
                close(fd);
                return false;
        }

        size_t at24_size = fs.st_size;

        if(sizeof(AT24_CONFIG) > at24_size)
        {
                fprintf(stderr, "[AT24 DRIVER] Sanity check: %lu > %lu\n", sizeof(AT24_CONFIG), at24_size);
                close(fd);
                return false;
        }


        void *at24_config = mmap(NULL, at24_size,
                PROT_READ | PROT_WRITE,
                MAP_SHARED_VALIDATE | MAP_LOCKED,
                fd, 0
        );

        close(fd);

        if(at24_config == MAP_FAILED)
        {
                fprintf(stderr, "[AT24 DRIVER] Bad, mmap failed: %s\n", strerror(errno));
                return false;
        }
Sadly I always get

Code: Select all

[AT24 DRIVER] Bad, mmap failed: No such device
Now why is this? According to the manpage:
The underlying filesystem of the specified file does not support memory mapping.
But everywhere on the net they sa one can easily mmap an eeprom, so...?

trejan
Posts: 3714
Joined: Tue Jul 02, 2019 2:28 pm

Re: AT24: mmap failed: No such device

Sun Sep 26, 2021 2:33 am

Are you sure they're using I2C EEPROMs? mmaping one sounds weird and not something that would work.

V10lator
Posts: 39
Joined: Wed Jul 07, 2021 11:18 am

Re: AT24: mmap failed: No such device

Sun Sep 26, 2021 3:51 am

trejan wrote:
Sun Sep 26, 2021 2:33 am
Are you sure they're using I2C EEPROMs?
No, I'm not sure. So all I can do is open the file and copy its content to RAM? That doesn't sound like a good thing to do, esp for writing (overwrite the whole file when just a few bytes have to be changed in the EEPROM), so are there any other ways?

trejan
Posts: 3714
Joined: Tue Jul 02, 2019 2:28 pm

Re: AT24: mmap failed: No such device

Sun Sep 26, 2021 4:04 am

V10lator wrote:
Sun Sep 26, 2021 3:51 am
trejan wrote:
Sun Sep 26, 2021 2:33 am
Are you sure they're using I2C EEPROMs?
No, I'm not sure.
I doubt what you were looking at was using a I2C EEPROM.
V10lator wrote:
Sun Sep 26, 2021 3:51 am
So all I can do is open the file and copy its content to RAM? That doesn't sound like a good thing to do, esp for writing (overwrite the whole file when just a few bytes have to be changed in the EEPROM), so are there any other ways?
Seek to where you want to change and then write the new bytes there.

V10lator
Posts: 39
Joined: Wed Jul 07, 2021 11:18 am

Re: AT24: mmap failed: No such device

Sun Sep 26, 2021 5:49 am

trejan wrote:
Sun Sep 26, 2021 4:04 am
Seek to where you want to change and then write the new bytes there.
That requires a lot of code and is ugly: https://github.com/V10lator/Master-Cont ... c/config.c

Before it wasn't as ugly but didn't allow to overwrite some bytes only: https://github.com/V10lator/Master-Cont ... c/config.c

The holy grail would be just just have a struct, mmap that damn EEPROM and cast the pointer to the struct. Then every value changed in the struct would be automagically saved on the EEPROM and it would write only the bytes needed. Is there really no way to do that?

trejan
Posts: 3714
Joined: Tue Jul 02, 2019 2:28 pm

Re: AT24: mmap failed: No such device

Sun Sep 26, 2021 6:12 am

V10lator wrote:
Sun Sep 26, 2021 5:49 am
The holy grail would be just just have a struct, mmap that damn EEPROM and cast the pointer to the struct. Then every value changed in the struct would be automagically saved on the EEPROM and it would write only the bytes needed. Is there really no way to do that?
You can't mmap an I2C EEPROM as there is no direct memory access to it. If you're feeling ambitious then you could make a kernel module that allocates a chunk of RAM to allow MMIO then alters the EEPROM behind the scenes. It'd be more work than just doing it in your code though.

If you want simple then allocate a buffer in RAM and store your config data in that. Whenever something is change then you copy the entire buffer to EEPROM. The 24C32 is good for at least 1 million write cycles so you can trade complexity for some additional write cycles.

V10lator
Posts: 39
Joined: Wed Jul 07, 2021 11:18 am

Re: AT24: mmap failed: No such device

Sun Sep 26, 2021 8:16 am

It's less about write cycles and more about speed. This is right from the at24 driver itself:
With a 100 kHz I2C clock, one 256 byte read takes about 1/43 second which is excessive
The chip is 4096 bytes which means reading (and writing, assuming both actions are equally slow) the whole chip takes almost half of a second! Now I have other things on the I2C bus which need to be readed out 16 times a second, so this can't work.

Anway, my newest codes keep two copies of the ROM so it's able to see what changed and (hopefully, codes are largely untested) writes changed bytes only: https://github.com/V10lator/Master-Cont ... c/config.c

Return to “C/C++”