By the end of this section, you will gain experience in the following topics:
  • Technical specifications and usage examples of the EEPROM available in Gemstone
EEPROMs are generally used to store hardware or software parameters that can be configured on the board, board-specific information (product type, serial number, etc.), or firmware (BIOS, etc.) because they do not contain a file system, provide fast access during boot, and can retain stored data for a very long time without corruption.
While SD Cards and USB Flash drives can store data for up to 10 years without corruption, the AT24C512C model EEPROM can retain data for 40 years without corruption.

EEPROM Usage

The board includes a 512-Kbit (64KiB) AT24C512C model EEPROM connected to the SoC via the I2C bus. The necessary drivers for Linux are pre-installed, and it is defined in the Device Tree as follows:
&wkup_i2c0 {
	eeprom@51 {
		compatible = "atmel,24c512";
		reg = <0x51>;
	};
}
After connecting to the board’s terminal, the following command should display a folder named 2-0051:
gemstone@t3-gem-o1:~$ ls /sys/bus/i2c/drivers/at24/
total 0
drwxr-xr-x  2 root root    0 Apr  7  2022 ./
drwxr-xr-x 66 root root    0 Apr  7  2022 ../
lrwxrwxrwx  1 root root    0 Jul  9 14:35 2-0051 -> '../../../../devices/platform/bus@f0000/bus@f0000:bus@b00000/2b200000.i2c/i2c-2/2-0051'/
lrwxrwxrwx  1 root root    0 Jul  9 14:35 module -> ../../../../module/at24/
--w-------  1 root root 4.0K Jul  9 14:35 bind
--w-------  1 root root 4.0K Apr  7  2022 uevent
--w-------  1 root root 4.0K Jul  9 14:35 unbind
In the folder name, 2 indicates that the EEPROM is on I2C bus 2 (i.e., wkup_i2c0), and 0051 indicates that its I2C address is 0x51.
In the example below, the file named eeprom is generated by the at24 driver and allows accessing the EEPROM as a file in Linux, enabling read and write operations.
gemstone@t3-gem-o1:~$ ls /sys/bus/i2c/drivers/at24/2-0051/
total 0
drwxr-xr-x 4 root root    0 Apr  7  2022 ./
drwxr-xr-x 7 root root    0 Apr  7  2022 ../
drwxr-xr-x 3 root root    0 Apr  7  2022 2-00511/
lrwxrwxrwx 1 root root    0 Jul  9 14:54 driver -> ../../../../../../../bus/i2c/drivers/at24/
lrwxrwxrwx 1 root root    0 Jul  9 14:54 of_node -> '../../../../../../../firmware/devicetree/base/bus@f0000/bus@b00000/i2c@2b200000/eeprom@51'/
drwxr-xr-x 2 root root    0 Jul  9 14:54 power/
lrwxrwxrwx 1 root root    0 Apr  7  2022 subsystem -> ../../../../../../../bus/i2c/
lrwxrwxrwx 1 root root    0 Jul  9 14:54 supplier:regulator:regulator.0 -> ../../../../../../virtual/devlink/regulator:regulator.0--i2c:2-0051/
-rw------- 1 root root 4.0K Jul  9 14:54 eeprom
-r--r--r-- 1 root root 4.0K Jul  9 14:54 modalias
-r--r--r-- 1 root root 4.0K Apr  7  2022 name
-rw-r--r-- 1 root root 4.0K Apr  7  2022 uevent

Using EEPROM via Terminal

The following command completely erases the EEPROM:
Since the EEPROM used on the T3-GEM-O1 board is 512 kilobits (64KiB), the count (number of bytes to write) is set to 65536 (64 x 1024).
gemstone@t3-gem-o1:~$ sudo dd if=/dev/zero of=/sys/bus/i2c/drivers/at24/2-0051/eeprom bs=1 count=65536 status=progress
[sudo] password for gemstone: 
65493 bytes (65 kB, 64 KiB) copied, 356 s, 0.2 kB/s
65536+0 records in
65536+0 records out
65536 bytes (66 kB, 64 KiB) copied, 356.235 s, 0.2 kB/s
As seen in the dd output, the EEPROM write speed is 0.2 kB/s, meaning we can write 200 bytes per second. One disadvantage of EEPROMs is their very low write speed.
The following command can be used to write data to the EEPROM:
gemstone@t3-gem-o1:~$ echo "Gemstone EEPROM" | sudo tee /sys/bus/i2c/drivers/at24/2-0051/eeprom
[sudo] password for gemstone: 
Gemstone EEPROM
To perform a read operation, the following command can be executed:
gemstone@t3-gem-o1:~$ sudo cat /sys/bus/i2c/drivers/at24/2-0051/eeprom
Gemstone EEPROM
For EEPROM read and write operations, examine the following usage examples in Python and C:
#!/usr/bin/python3

eeprom_dest = "/sys/bus/i2c/drivers/at24/2-0051/eeprom"
eeprom_size = 65536

# Write
with open(eeprom_dest, "w") as eeprom:
    eeprom.write("Read-Write Example of EEPROM")

# Read
with open(eeprom_dest, "r") as eeprom:
    eeprom_data = eeprom.read(eeprom_size)
    print("EEPROM Data:", eeprom_data)