2014-10-18 31 views
1

我通过TCP套接字从设备接收一些数据。我有结构的规范,但不知道如何使用它来解压缩它。我假设这意味着要为struct.unpack函数编写一个格式化字符串,但鉴于制造商的规格,我无法弄清楚这一点。这些32位碎片中的每一个都是“DWORD”,但我不确定如何解释,并提取相关位:使用Python解包数据结构

状态头是一个22x32位(88字节)的混合结构之前的数据类型并提供有关正在传输的数据的信息。下表显示了该结构的相关成员。阴影的成员字段留作未来扩展,用于内部用于仪器监视和控制,或者根本未实现。

Imgur Imgur

这里有两个样本结构:

b'\x08\x04i!\x13\x02\x00\x1f\x00\x00\x80\x0c\x01\x00p\x00\x00\x00\x00\x00\x00\x00\x00\x00\x84\x9e\x00\x00\x85\x9e\x01\x00:B\x04\x00\x08\xf4DT\x01\x00k\x01\xdc\x8c\x00\x00c\x03X\x00\x9eR\xa4QTV\xf0U\xd0\x83\xd0\x83\xd0\x83\xd0\x83\x01\x00\x00\[email protected]\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

b'\x08Ti!\x1a\x02\x00\x1f\x00\x00x\x0c\x01\x00p\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd4\x91\x00\x00\xd5\x91\x01\x00`y\x00\x00\x05\xf4DT\x01\x00\xbb\x00\xdb\x8c\x00\x00c\x03X\x00\x9eR\xa4QTV\xf0U\xd0\x83\xd0\x83\xd0\x83\xd0\x83\x01\x00\x00\[email protected]\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

+1

你知道每个字段(int,str,bytes等)的数据类型吗?你知道这是小还是大吗?你能提供一个数据样本吗? – davidism 2014-10-18 16:19:19

+0

我真的不知道。我已经编辑了这个问题,以包含手册中的另一个表格,以防有所帮助。 – petebachant 2014-10-18 16:28:39

回答

2

这应该让你开始。使用struct.unpack解包接收的字节,然后对由少于1个字节的数据表示的字段进行解析。

from struct import unpack 

# data recieved, 88 random bytes for example purpose 
data = b'\xdb[\x91wdI\t\xef\xc6c\xde\x14\xac\x1e\x08\x10.f\xc0\xbd\xfd\xa15\x8cP\x101\xed\xc5\xd9\x98X\xb5\xc2\x00Z\xd2\xb9\xb0Xa\x04\xfa\xb8\xceA\x94_7\xc7\xde\t\xf2kX\x9d2\xc3\x84\xb3\x19\x8e\xf5\x99\xc3\xba\x08\xaa0$\x17\xfbd\xbb\x7f\xfd&\xf5\x1aU\t`\[email protected]\xce\xff' 

# unpack the struct into variables 
(
    abcde, fw_ver, cur_layer, fs_radix, # 0 needs parse 
    fghij, knpl, fbg_thermistor, # 1 needs parse 
    tx_ambient_temp, reserved2, # 2 
    num_ffpi_peaks, num_fbg_peaks, # 3 
    num_dut2_peaks, num_dut1_peaks, # 4 
    num_dut4_peaks, num_dut3_peaks, # 5 
    reserved7, qr, acq_counter3, # 6 needs parse 
    serial_number, # 7 
    kernel_timestamp_microseconds, # 8 
    kernel_timestamp_seconds, # 9 
    kernel_src_buffer, kernel_buffers, # 10 
    error_and_kernel_rt_loc0, # 11 needs parse 
    header_length, header_ver, buffers, # 12 
    dut2_gain, dut1_gain, # 13 
    dut4_gain, dut3_gain, # 14 
    dut2_noise_thresh, dut1_noise_thresh, # 15 
    dut4_noise_thresh, dut3_noise_thresh, # 16 
    hw_clk_div, peak_data_rate_div, # 17 
    granularity, # 18 
    reserved4, # 19 
    starting_lambda, # 20 
    ending_lambda # 21 
) = unpack(
    '>' # big endian 
    'BBBB' # 0 needs parse 
    'BBH' # 1 needs parse 
    'HH' # 2 
    'HH' # 3 
    'HH' # 4 
    'HH' # 5 
    'BBH' # 6 needs parse 
    'I' # 7 
    'I' # 8 
    'I' # 9 
    'HH' # 10 
    'I' # 11 needs parse 
    'HBB' # 12 
    'HH' # 13 
    'HH' # 14 
    'HH' # 15 
    'HH' # 16 
    'HH' # 17 
    'I' # 18 
    'I' # 19 
    'I' # 20 
    'I', # 21 
    data 
) 

# 0 parse abcde 
acq_triggered = bool(abcde & 0x80) 
calibration_fault = bool(abcde & 0x40) 
start_of_frame = bool(abcde & 0x20) 
primary_fan_state = bool(abcde & 0x10) 
secondary_fan_state = bool(abcde & 0x08) 
s0_mux_state = bool(abcde & 0x04) 
s1_mux_state = bool(abcde & 0x02) 
s2_mux_state = bool(abcde & 0x01) 

# 1 parse fghij 
xfer_type = fghij >> 4 
soa_therm_limit = bool(fghij & 0x08) 
soa_current_limit = bool(fghij & 0x04) 
tec_over_temp = bool(fghij & 0x02) 
tec_under_temp = bool(fghij & 0x01) 

# 1 parse knpl 
operating_mode = knpl >> 6 
triggering_mode = (knpl & 0x30) >> 4 
sm041_mux_level = (knpl & 0x0c) >> 2 
sw_position = knpl & 0x03 

# 6 parse qr 
nrz_command = qr >> 5 
reserved6 = qr & 0x1f 

# 11 parse 
error = error_and_kernel_rt_loc0 >> 24 
kernel_rt_loc0 = error_and_kernel_rt_loc0 & 0xffffff 

因为这是通过TCP传递的,所以我假定为big endian,但这可能是错误的。如果所有数据都关闭,请尝试使用<作为小端。或者,如果你不幸运,一些值可能是一个值,另一些值是另一个值,在这种情况下,你将不得不将它拆分成多个解包。您还必须进一步处理这些值,因为我相信其中一些值不应被解释为整数。


的解压缩格式可缩短至

(all, those, variables) = unpack('>6B9H2BH3I2HIH2B10H4I', data) 

,但我不认为这是最明确。

+0

@petebachant我很乐意帮助你[聊天](http://chat.stackoverflow.com/rooms/6/python)。既然你似乎在实际的数据上运行它,你能发布两个示例数据包(每个88字节)吗?听起来这些字段的顺序可能会颠倒过来,并且具有相同序列号和fw版本的2个数据包将清除它。 – davidism 2014-10-19 23:11:18

+0

我在原始问题中添加了两个样本数据包。它们都应该包含几乎所有相同的数据。 – petebachant 2014-10-20 16:31:35