integration test_eeprom error `periphery.i2c.I2CError: [Errno 5] I2C transfer: Input/output error`
farzadpanahi opened this issue · comments
this is happening in integration tests.
looks like when we run test_eeprom by itself, it will pass, but when we run all the integration tests, there is a chance of failure.
I do not know the exact steps to reproduce this issue.
________________________________________________________________________________________________ test_write_edgepi_data ________________________________________________________________________________________________
self = <periphery.i2c.I2C object at 0x7fa4442a00>, address = 80, messages = [<periphery.i2c.I2C.Message object at 0x7fa4442dc0>]
def transfer(self, address, messages):
"""Transfer `messages` to the specified I2C `address`. Modifies the
`messages` array with the results of any read transactions.
Args:
address (int): I2C address.
messages (list): list of I2C.Message messages.
Raises:
I2CError: if an I/O or OS error occurs.
TypeError: if `messages` type is not list.
ValueError: if `messages` length is zero, or if message data is not valid bytes.
"""
if not isinstance(messages, list):
raise TypeError("Invalid messages type, should be list of I2C.Message.")
elif len(messages) == 0:
raise ValueError("Invalid messages data, should be non-zero length.")
# Convert I2C.Message messages to _CI2CMessage messages
cmessages = (_CI2CMessage * len(messages))()
for i in range(len(messages)):
# Convert I2C.Message data to bytes
if isinstance(messages[i].data, bytes):
data = messages[i].data
elif isinstance(messages[i].data, bytearray):
data = bytes(messages[i].data)
elif isinstance(messages[i].data, list):
data = bytes(bytearray(messages[i].data))
cmessages[i].addr = address
cmessages[i].flags = messages[i].flags | (I2C._I2C_M_RD if messages[i].read else 0)
cmessages[i].len = len(data)
cmessages[i].buf = ctypes.cast(ctypes.create_string_buffer(data, len(data)), ctypes.POINTER(ctypes.c_ubyte))
# Prepare transfer structure
i2c_xfer = _CI2CIocTransfer()
i2c_xfer.nmsgs = len(cmessages)
i2c_xfer.msgs = cmessages
# Transfer
try:
> fcntl.ioctl(self._fd, I2C._I2C_IOC_RDWR, i2c_xfer, False)
E OSError: [Errno 5] Input/output error
venv_test/lib/python3.9/site-packages/periphery/i2c.py:135: OSError
During handling of the above exception, another exception occurred:
eeprom = <edgepi.eeprom.edgepi_eeprom.EdgePiEEPROM object at 0x7fa4227c10>
def test_write_edgepi_data(eeprom):
original_data = eeprom.read_edgepi_data()
for _ in range(10):
# initializing size of string
str_len = 100
# using random.choices()
# generating random strings
res = ''.join(random.choices(string.ascii_uppercase +
string.digits, k=str_len))
# Modified data to write to memory
modified_data = eeprom.read_edgepi_data()
modified_data.config_key.certificate = DUMMY_KEY + res
modified_data.config_key.private_key = DUMMY_KEY + res
modified_data.data_key.certificate = DUMMY_KEY + res
modified_data.data_key.private_key = DUMMY_KEY + res
# Write modified data
> eeprom.write_edgepi_data(modified_data)
src/test_edgepi/integration_tests/test_eeprom/test_eeprom.py:90:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
src/edgepi/eeprom/edgepi_eeprom.py:186: in write_edgepi_data
self.__write_edgepi_reserved_memory(self.eeprom_pb.SerializeToString())
src/edgepi/eeprom/edgepi_eeprom.py:130: in __write_edgepi_reserved_memory
self.__page_write_register(mem_offset, page)
src/edgepi/eeprom/edgepi_eeprom.py:221: in __page_write_register
self.transfer(EEPROMInfo.DEV_ADDR.value, msg)
src/edgepi/peripherals/i2c.py:86: in transfer
self.i2cdev.transfer(dev_addr, msg)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <periphery.i2c.I2C object at 0x7fa4442a00>, address = 80, messages = [<periphery.i2c.I2C.Message object at 0x7fa4442dc0>]
def transfer(self, address, messages):
"""Transfer `messages` to the specified I2C `address`. Modifies the
`messages` array with the results of any read transactions.
Args:
address (int): I2C address.
messages (list): list of I2C.Message messages.
Raises:
I2CError: if an I/O or OS error occurs.
TypeError: if `messages` type is not list.
ValueError: if `messages` length is zero, or if message data is not valid bytes.
"""
if not isinstance(messages, list):
raise TypeError("Invalid messages type, should be list of I2C.Message.")
elif len(messages) == 0:
raise ValueError("Invalid messages data, should be non-zero length.")
# Convert I2C.Message messages to _CI2CMessage messages
cmessages = (_CI2CMessage * len(messages))()
for i in range(len(messages)):
# Convert I2C.Message data to bytes
if isinstance(messages[i].data, bytes):
data = messages[i].data
elif isinstance(messages[i].data, bytearray):
data = bytes(messages[i].data)
elif isinstance(messages[i].data, list):
data = bytes(bytearray(messages[i].data))
cmessages[i].addr = address
cmessages[i].flags = messages[i].flags | (I2C._I2C_M_RD if messages[i].read else 0)
cmessages[i].len = len(data)
cmessages[i].buf = ctypes.cast(ctypes.create_string_buffer(data, len(data)), ctypes.POINTER(ctypes.c_ubyte))
# Prepare transfer structure
i2c_xfer = _CI2CIocTransfer()
i2c_xfer.nmsgs = len(cmessages)
i2c_xfer.msgs = cmessages
# Transfer
try:
fcntl.ioctl(self._fd, I2C._I2C_IOC_RDWR, i2c_xfer, False)
except (OSError, IOError) as e:
> raise I2CError(e.errno, "I2C transfer: " + e.strerror)
E periphery.i2c.I2CError: [Errno 5] I2C transfer: Input/output error
venv_test/lib/python3.9/site-packages/periphery/i2c.py:137: I2CError