Python3 ctypes c\u unit32末端

2024-05-16 04:31:23 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图将PCI配置空间数据加载到python中进行评估,但是在使用BAR0的c_unit32时遇到了一个问题。我已经设法简化了问题/脚本,以显示cuint16的行为与我预期的一样,但是cuint32失败了。Bar0必须是一个c_unit32,在实际脚本中,Bar0被解码为一个单独的结构,它使用位0-13表示各个字段,然后使用位14:31作为较低的条。在

因为加载到pci/config/example中的一个小的字符串/sys/example是从一个小的/config/example/example/example/example/example/example/example/example/example/example/example/example/example/example/example/example/example/exampl

期望:

输入字符串:“86802010f6710000”

供应商ID:0x8086
设备ID:0x1020
Bar0:0x71f60000

实际:

输入字符串:“86802010f6710000”

供应商ID:0x8086
设备ID:0x1020
Bar0:0x71f6

VendorID和DeviceID字段已正确交换。我假设“0000”被字节交换并放在f671的前面,然后f671被字节交换为71f6。然后消除前导的00,创建“0x71f6”。如果我使用“f6710100”,它将变为0x171f6,则可以确认这一点。在


当我使用uint32时,如何确保它被正确地解释为0x71f6000?


代码:

from ctypes import *


class PCICfg(Structure):

    _pack_ = 1
    _fields_ = [
                ("VendorID", c_uint16),
                ("DeviceID", c_uint16),
                ("Bar0",     c_uint32),
               ]


class PCIUnion(Union):

    _pack_ = 1
    _fields_ = [
                ("ConfigSpace", PCICfg),
                ("Bytes",       c_ubyte * sizeof(PCICfg))
               ]


    def from_str(self, input):

        print("Input String: ", input)

        hex_data = bytearray.fromhex(input)

        for x in range(0, len(hex_data)):
            self.Bytes[x] = hex_data[x]


if __name__ == '__main__':

    cfg = PCIUnion()
    cfg.from_str("86802010f6710100")

    print("VID: %s" % hex(cfg.ConfigSpace.VendorID))
    print("DID: %s" % hex(cfg.ConfigSpace.DeviceID))
    print("BA0: %s" % hex(cfg.ConfigSpace.Bar0))

Tags: 字符串fromidinputdataexamplecfgprint
1条回答
网友
1楼 · 发布于 2024-05-16 04:31:23

您看到的是正确的32位little-endian结果,但是如果您的输入实际上是little-endian 16位单词的十六进制表示,那么就这样处理它:

from ctypes import *
from binascii import unhexlify

class PCICfg(Structure):
    _pack_ = 1
    _fields_ = [("VendorID", c_uint16),
                ("DeviceID", c_uint16),
                ("Bar0Hi", c_uint16),
                ("Bar0Lo", c_uint16)]

class PCIUnion(Union):
    _pack_ = 1
    _fields_ = [("ConfigSpace", PCICfg),
                ("Bytes", c_ubyte * sizeof(PCICfg))]

    def from_str(self, inp):
        print("Input String: ", inp)
        self.Bytes[:] = unhexlify(inp)

if __name__ == '__main__':
    cfg = PCIUnion()
    cfg.from_str("86802010f6710100")
    print("VID: {:#04x}".format(cfg.ConfigSpace.VendorID))
    print("DID: {:#04x}".format(cfg.ConfigSpace.DeviceID))
    print("BA0: {:#04x}{:04x}".format(cfg.ConfigSpace.Bar0Hi,cfg.ConfigSpace.Bar0Lo))
Input String:  86802010f6710100
VID: 0x8086
DID: 0x1020
BA0: 0x71f60001

相关问题 更多 >