cTypes寄存器位字段
ctypes-bitfield的Python项目详细描述
cTypes位字段库包含两个模块,bitfield
和remotestruct
。
bitfield
提供了创建与cTypes兼容的机制
由位字段组成的寄存器的实现。
remotestruct
允许cTypes派生类,如Structure和BitField
通过远程接口访问,如TCP/IP或VME间接寻址
计划。
位字段
bitfield
提供了创建与cTypes兼容的机制
由位字段组成的寄存器的实现。基地
cTypes库已经提供了很多这种功能,但是
bitfield builder实现将其包装起来,以便更简单地使用,并避免了一些
奇怪的行为。
通常,基础寄存器类型是一个固定大小的整数, c_uint16或c_uint64等。然而,有点奇怪的例子用法 会像这样:
>>> from bitfield import * >>> IEEE754 = make_bf('IEEE754', [ ... ('mantissa', c_uint, 23), ... ('exponent', c_uint, 8), ... ('sign', c_uint, 1) ... ], basetype=c_float, doc='Bitfields of an IEEE754 single precision float.') >>> x = IEEE754() >>> x.keys() ['mantissa', 'exponent', 'sign'] >>> x.base = 5.0 >>> list(x.items()) #doctest: +ELLIPSIS [('mantissa', 2097152...), ('exponent', 129...), ('sign', 0...)] >>> x.sign = 1 >>> x.base -5.0 >>> x.exponent -= 2 >>> x.base -1.25 >>> x.update(sign = 0, mantissa = 0) >>> x.base 1.0
位字段对象是从cTypes.union派生的。因为这个推导, 这些类可以堆叠成cTypes.Structures,这意味着它们可以 直接处理内存映射数据。如果内存映射数据不稳定, 例如硬件寄存器,那么update()方法运行的事实 在一次写入而不是每个字段一次写入的整个寄存器上,可以 有用。
远程结构
remotestruct
允许cTypes派生类,例如
位字段,通过远程接口(如TCP/IP或VME)访问
间接计划。实际上,这意味着对元素的请求
将结构转换为对任意字节序列的请求,获取它们,
管理翻译。
例如,如果您有一种机制,通过以太网套接字, 无法将8字节作为W 0x100 55 45 10 18 26 28 33 47写入地址0x100, 然后通过发送R 0x100 4并返回来读取其中的四个字节 55 45 10 18(所有的换行符都是分隔的),然后您将编写一个 协议处理程序:
>>> class SerialHandler(object): ... def __init__(self, sock): ... self.sock = sock ... ... def writeBytes(self, addr, data): ... msg = "W " + hex(addr) + ' '.join(str(d) for d in data) ... self.sock.sendall(msg.encode('ascii')) ... ... def readBytes(self, addr, size): ... msg = "R 0x{0:X} {1}".format(addr, size) ... self.sock.sendall(msg.encode('ascii')) ... ... received = [] ... while True: ... x = self.sock.recv(4096) ... received.append(x) ... if b'\n' in x: ... break ... ... msg = b''.join(received) ... data = bytes(int(b) for b in msg.split(b' ')) ... return data >>> class DataStructure(Structure): ... _fields_ = [ ... ('flags', c_uint32), ... ('_dummy1', c_uint32), ... ('offset', c_int32), ... ('slope', c_float) ... ] >>> sock = socket.create_connection(('1.2.3.4', 80)) >>> handler = SerialHandler(sock) >>> rs = remotestruct.Remote(DataStructure, handler) >>> rs.flags 5 >>> rs.flags = 183 >>> rs.flags 183
缓存句柄
远程结构可能因传输速度慢而出现性能问题;获取 你知道的数据并没有因为简单而一次又一次的改变 这样写代码。解决方法是将处理程序包装在 Cache Debug,它提供了一个灵活的缓存机制来防止拖拽。 已知数据。cachedhandler不会只提取请求的数据, 基于以下假设预取整个对齐的数据“缓存线” 您需要的下一个数据可能在物理上接近 目前正在申请。因此,对于默认的32字节缓存线,请求 地址40-41处的2字节将请求所有字节32-63,并将它们存储在 缓存集(默认8)。此数据将保持高速缓存,直到它 否则缓存集将被新的缓存线覆盖。
使用cachedhandler重复前面的示例将添加:
>>> sock = socket.create_connection(('1.2.3.4', 80)) >>> basehandler = SerialHandler(sock) >>> cachedhandler = CachedHandler( ... handler=basehandler, ... timeout=2.5 ... ) >>> rs = remotestruct.Remote(DataStructure, cachedhandler) >>> rs.flags 5 >>> rs.flags = 183 >>> rs.flags 183
cachedhandler对于超时最有用,它指示数据的旧程度 在缓存中可以是在它过期之前;在上面的示例中设置了超时 到2.5秒。none的超时意味着数据永远不会过期;timeout 0表示数据始终过期,这实际上禁用了缓存。
cachedhandler有许多选项来控制缓存集的数量和 缓存线的长度,您可以轻松地用一生的时间进行调整,以尝试获取 “完美”缓存设置。别这样。cachedhandler可以是 使用stats=true初始化,这将使缓存保留命中的统计信息, 错过和超时。如果缓存超时太多,则 获取的数据超过了您可以使用的范围,因此应该减少缓存线的长度。 如果未命中太多,则会有更多的缓存集或更长的缓存线 将是您的解决方案,具体取决于您的数据访问模式。
cachedhandler还有nocache和noprefetch选项来微调控件 性能;这可以是对防止破坏性寄存器访问至关重要。
更改日志
- 0.3.1
- 修复了一些包装问题。
- 0.3.0
将.items迭代器转换为列表。不会这么久的 开销是一个问题,它从 命令行要容易得多。
添加了cachedhandler,并将位字段和remotestruct从 将单个模块转换为完整的包。
适用于Python2.7+和3.2+
author: | Rob Gaddi, Highland Technology, Inc. |
---|---|
date: | 24-Aug-2015 |
version: | 0.3.0 |