The I2C adaptation layer work is complete now and it is indeed working as a
layer in between the RTEMS i2c stack and the iicbus stack in FreeBSD. But it’s
not enough to see that the /dev/iic0
is being created as any call to the
iic0
is basically going to the RTEMS i2c-0
device. That’s what we intended
through the i2c-adaptation
layer.
To test the driver I decided to create a sample application outside of the
rtems-libbsd
and use the RTEMS api to register the i2c-0
bus and then use
the FreeBSD calls to read from the EEPROM, which will get directed to the
i2c-0
device. As there has been no app like this in the RTEMS directories (in
my knowledge), I forked the repo rtems-bbb created by Christian Mauderer.
Then I started building my app in there. As I have discussed above, the app is
going to be a very basic one and what we intend to do is something like this:
- Register the
i2c-0
device. - call the
rtems_bsd_initialize()
. - Read the EEPROM using ioctl call.
So basically the Init()
(The entry point of the app), was sorted. What we
need is the function to read EEPROM. The approach is to first open() the iic0
device then set a test iic_msg *
message. Store it in a variable of type
iic_rdwr_data
and call ioctl()
on it.
Here’s the Sample eeprom_read()
from the app. And that’s basically it:
int
read_eeprom(int address)
{
int fd;
int ret;
uint8_t wbuf[2];
uint8_t rbuf[2];
struct iic_msg msg[2];
struct iic_rdwr_data rdwr;
if ((fd = open(I2C_BUS, O_RDWR)) < 0) {
perror("open");
return (-1);
}
msg[0].slave = EEPROM_ADDRESS << 1;
msg[0].flags = 0;
msg[0].len = 1;
wbuf[0] = 0xff & address;
msg[0].buf = wbuf;
rbuf[0] = 0;
rbuf[1] = 0;
msg[1].slave = (EEPROM_ADDRESS << 1) | IIC_M_RD;
msg[1].flags = IIC_M_RD;
msg[1].len = 2;
msg[1].buf = rbuf;
rdwr.msgs = msg;
rdwr.nmsgs = 2;
ret = ioctl(fd, I2CRDWR, &rdwr);
if (ret < 0) {
perror("ioctl(I2CRDWR)");
ret = (-1);
} else
ret = (rbuf[0] << 8) + rbuf[1];
close(fd);
return (ret);
}
It is to be noted that this is returning int and not dumping a hex, which would have been more desirable but since this is just to test the working of the driver, this would be just fine ;-)
Along with the EEPROM read function, I have added the i2c tool from FreeBSD and that acts as a full fledged test for the whole i2c stack, The tool works great with the current state of drivers but it lacks the transfer mode (as of now) but it will certainly work after the libbsd update as I have tested the latest patch in FreeBSD upstream that adds the transfer mode to the app.
Here’s the link to the exact app directory, since it is GitHub, you can keep an eye for any further changes in the application.
If anyone is trying to build and run the app on a Beaglebone Black, then you’ll
have to remember to use the create-dtb.sh
to create the dtb with the applied
overlay to make the driver work. For now you’ll have to manually replace the
original dtb with the generated dtb
file. But I’ll soon try to to make it all
automatic.
Thanks for the patient reading and as always, any feedback or discussion is really appreciated!