我一直在阅读PCIe规范的恐怖,但仍无法对以下问题对得到任何解决方案.
PCIe是否允许映射超过4GB边界的巨大(例如16GB)64位非预取内存空间?或者它们仍然与32位时的1GB相同,并且没有办法要求巨大的非预取空间?
假设规范允许它(以及我的读取它),广泛可用的BIOS支持它吗?或者它在理论上是允许的,但在实践中却没有完成?
我需要一个与ctypes Structures兼容的位域定义,这样我就可以将它用作指向内存映射的硬件寄存器集的指针,即
class RegFile(Structure):
_fields_ = [
('ticks', c_uint32),
('id', id_bitfield),
]
Run Code Online (Sandbox Code Playgroud)
理想情况下,它们是非常Pythonic的东西,并且表现得很像dicts.我已经设法将大部分血腥细节工作到我现在拥有工厂函数的位置,这使得bitfield类与制作namedtuples类似.这是一个剥离标准浮点字段的例子.
def make_register(name, fields, basetype=c_uint32):
# Define the underlying bitfield type
bitfield = type(name + '_bitfield', (LittleEndianStructure, ), {})
bitfield._pack_ = 1
bitfield._fields_ = fields
# Set up the union
d = {
'_fields_' : [('base', basetype), ('_b', bitfield)],
'_anonymous_' : ('_b',),
'__iter__' : _register_iter,
'keys' : _register_keys,
'items' : _register_items,
'update' : _register_update
}
return type(name, (Union, ), d)
ieee754_fields = [
('mantissa', c_uint, 23),
('exponent', c_uint, …Run Code Online (Sandbox Code Playgroud) 有没有人想出一个在Python下使用内存映射设备寄存器的好解决方案?理想情况下,某些东西可以让我使用命名寄存器,甚至在这些寄存器中命名位域,这种方式不完全是临时的?理想的跨平台,但我只能使用Linux.
似乎mmap和ctypes Structs的某些组合可能能够处理它,但是a)Structs似乎不允许你指定位域位置(它们也不是在C中,所以......),和b)我可以弄清楚如何在mmap上删除Struct映射.
或者我从根本上问我如何使用圆锯作为螺丝刀?(即它没有这样做,为什么你想要?)
C中的一个例子(未经测试,不使用)将是这样的:
volatile struct {
uint32_t mfr_id;
uint32_t prod_id;
uint32_t ctl;
uint32_t dummy[5];
...
} * pDev;
hFile = open('/dev/bridge', O_RDWR)
pDev = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, hFile, 0);
assert(pDev->mfr_id == 0x12345678);
assert(pDev->prod_id == 0xDEADBEEF);
uint32_t temp = pDev->ctl;
temp &= CTL_ACCESS_MASK | CTL_SHIFT_MASK;
temp |= CTL_ACCESS_RO | CTL_SHIFT_5;
pDev->ctl = temp;
Run Code Online (Sandbox Code Playgroud)