我需要读取嵌入式设备中的 eeprom。
到目前为止,这个“几乎”有效:
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <fcntl.h>
#include <linux/i2c-dev.h>
#define READ_SIZE (256)
#define NB_PAGES (128)
void dump_to_file(const char *output_file_path,
const uint8_t *buffer, const int buffer_length)
{
int output_file = open(output_file_path, O_RDWR|O_APPEND|O_CREAT);
if (output_file < 0) {
printf("Failed opening output file %s\n", output_file_path);
return;
}
write(output_file, buffer, buffer_length);
}
int main(int argc, char *argv[])
{
/* got these values from i2cdetect */
const char *i2c_device = "/dev/i2c-4";
const int device_address = 0x50;
/* open the i2c device file */
int file = open(i2c_device, O_RDWR);
if (file < 0) {
printf("Failed opening %s\n", i2c_device);
return 1;
}
if (ioctl(file, I2C_SLAVE, device_address) < 0) {
printf("Failed addressing device at %02X\n", device_address);
close(file);
return 1;
}
int i = 0;
for (i = 0; i < NB_PAGES; i++) {
char buf[READ_SIZE] = {0};
if (read(file, buf, READ_SIZE) != READ_SIZE) {
printf("Failed reading\n");
close(file);
return 1;
}
dump_to_file(argv[1], buf, READ_SIZE);
}
close(file);
return 0;
}
“几乎”是指它转储完整的 eeprom,但 START 取决于最后读取的 block 。
它并不总是一样的。
如果我读了 10 个 block 。然后再次运行该程序,我读了接下来的内容,而不是前 10 个。
如何设置起始地址?
更新: 如果我这样做:
i2cset -y 4 0x50 0x00 0x00
并运行上面的代码,它可以工作。 那么如何在代码中放入 i2cset 命令的等效命令呢?
最佳答案
完成! 这并不容易,因为我在任何地方都找不到文档..但我认为由于 eeprom 是 32K,也许它“就像”24c256。但即使在这种情况下,我在用户空间中也找不到任何东西,直到我决定凭直觉去做。 我研究了 i2cset 源代码,了解了它的作用并将其放入代码中。
这是结果,它从用户空间转储完整的 i2c 32k eprom。
请注意,可以在此处找到完整的备份和恢复实用程序: https://gist.github.com/Zibri/cf8ac0b311301aeeaa8910c7da824bff
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/i2c-dev.h>
#define READ_SIZE (256)
#define NB_PAGES (128)
void dump_to_file(const char *output_file_path,
const uint8_t *buffer, const int buffer_length)
{
int output_file = open(output_file_path, O_RDWR|O_APPEND|O_CREAT);
if (output_file < 0) {
printf("Failed opening output file %s\n", output_file_path);
return;
}
write(output_file, buffer, buffer_length);
}
int main(int argc, char *argv[])
{
const char *i2c_device = "/dev/i2c-4";
const int device_address = 0x50;
int file = open(i2c_device, O_RDWR);
if (file < 0) {
printf("Failed opening %s\n", i2c_device);
return 1;
}
if (ioctl(file, I2C_SLAVE, device_address) < 0) {
printf("Failed addressing device at %02X\n", device_address);
close(file);
return 1;
}
int i = 0;
write(file,'\x00\x00',2); // ADDRESS
for (i = 0; i < NB_PAGES; i++) {
char buf[READ_SIZE] = {0};
if (read(file, buf, READ_SIZE) != READ_SIZE) {
printf("Failed reading\n");
close(file);
return 1;
}
dump_to_file(argv[1], buf, READ_SIZE);
}
close(file);
return 0;
}
关于c - 从用户区读取 32k i2c eeprom,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68878486/