Packing byte fields and an array object into struct
Ned Batchelder
ned at nedbatchelder.com
Wed Nov 13 13:44:38 EST 2013
On Wednesday, November 13, 2013 1:31:49 PM UTC-5, krishna... at gmail.com wrote:
> Hello,
>
> I am trying to build a structure to be passed down to an I2C device driver. The driver expects a struct that has a data array of size 512 bytes among other things. This is my code -
>
> rd_wr = 0x0 # Read operation
> i2c_addr = addr
> mux = mux_sel
> multi_len = count
> cmd = 0x0
> i2c_inst_type = CHEL_I2C_AUTO_RD_TYPE_5
> flag = CHEL_I2C_AUTO_VALID
> status = 0x0
> data = array.array('B', (0 for x in range(0,512)))
>
> os_inst_bytes = (struct.pack('B', rd_wr) +
> struct.pack('B', i2c_addr) +
> struct.pack('B', mux) +
> struct.pack('B', multi_len) +
> struct.pack('B', cmd) +
> struct.pack('B', i2c_inst_type) +
> struct.pack('B', flag) +
> struct.pack('I', status) +
> struct.pack('512B', data))
>
> #Convert to byte array
> os_inst = bytearray(os_inst_bytes)
>
> ret = fcntl.ioctl(self._dev_fd,
> self.__IOWR(FXCB_FPGAIO_I2C_AUTO_OS_INST),
> os_inst, 1)
>
> I get an error like this -
>
> 591 struct.pack('B', flag) +
> 592 struct.pack('I', status) +
>
> --> 593 struct.pack('512B', data))
>
> error: pack requires exactly 512 arguments
>
> In [1]:
>
> Even though data is a 512 element array, it is not treat as such in this struct.pack. The data field is used to return data from the driver. I should be able to unpack the struct os_inst and read the data buffer after the IOCTL call. How can I achieve this ?
>
> Thanks in advance!
To make a 512-byte field in struct, use '512s' with a data value of ''. It will zero-pad the result and give you 512 zero bytes. Also, you can use multiple format specifiers in one struct.pack call:
os_inst_bytes = struct.pack('7BI512s', rd_wr, i2c_addr, muc, multi_len, cmd, i2c_inst_type, flag, status, '')
Lastly, I suspect the value returned from struct.pack is byte-string enough for the ioctl call, no need to use bytearray.
--Ned.
More information about the Python-list
mailing list