{ "info": { "author": "Rob Gaddi", "author_email": "rgaddi@highlandtechnology.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.2", "Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.4", "Topic :: System :: Hardware" ], "description": "===============\nctypes-bitfield\n===============\n\nThe ctypes-bitfield library consists of two modules, `bitfield` and `remotestruct`.\n\n`bitfield` provides a mechanism for creating ctypes compatible\nimplementations of registers made up of bitfields.\n\n`remotestruct` allows for ctypes derived classes, such as Structure and Bitfield, to be\naccessed over a remote interface, such as TCP/IP or a VME indirection\nscheme.\n\nbitfield\n--------\n\n`bitfield` provides a mechanism for creating ctypes compatible\nimplementations of registers made up of bitfields. The base\nctypes library already provides much of this functionality, but the\nbitfield builder implementation wraps it up for simpler usage and avoids some\nof the quirky behaviors.\n\nNormally the underlying register type would be a fixed size integer, a \nc_uint16 or c_uint64 or the like. However, a somewhat strange example usage\nwould look something like this::\n\n >>> from bitfield import *\n >>> IEEE754 = make_bf('IEEE754', [\n ... ('mantissa', c_uint, 23),\n ... ('exponent', c_uint, 8),\n ... ('sign', c_uint, 1)\n ... ], basetype=c_float, doc='Bitfields of an IEEE754 single precision float.')\n >>> x = IEEE754()\n >>> x.keys()\n ['mantissa', 'exponent', 'sign']\n >>> x.base = 5.0\n >>> list(x.items()) #doctest: +ELLIPSIS\n [('mantissa', 2097152...), ('exponent', 129...), ('sign', 0...)]\n >>> x.sign = 1\n >>> x.base\n -5.0\n >>> x.exponent -= 2\n >>> x.base\n -1.25\n >>> x.update(sign = 0, mantissa = 0)\n >>> x.base\n 1.0\n \nBitfield objects are derived from ctypes.Union. Because of this derivation,\nthese classes can be stacked into ctypes.Structures, which means they can\nwork directly on memory mapped data. If the memory-mapped data is volatile, \nsuch as hardware registers, then the fact that the update() method operates\non the entire register in one write, rather than one write per field, may\nbe of use.\n\nremotestruct\n------------\n`remotestruct` allows for ctypes derived classes, such as Structure and \nBitfield, to be accessed over a remote interface, such as TCP/IP or a VME \nindirection scheme. Effectively, this means turning requests for elements \nof the structure into requests for arbitrary byte sequences, fetching them, \nand managing the translation.\n\nIf, for instance, you had a mechanism whereby, over an Ethernet socket, you \ncould write 8 bytes to address 0x100 as ``W 0x100 55 45 10 18 26 28 33 47``, \nthen read back four of those bytes by sending ``R 0x100 4`` and getting back \n``55 45 10 18`` (all of that newline delimited), then you would write a \nprotocol handler::\n\n >>> class SerialHandler(object):\n ... def __init__(self, sock):\n ... self.sock = sock\n ... \n ... def writeBytes(self, addr, data):\n ... msg = \"W \" + hex(addr) + ' '.join(str(d) for d in data)\n ... self.sock.sendall(msg.encode('ascii'))\n ... \n ... def readBytes(self, addr, size):\n ... msg = \"R 0x{0:X} {1}\".format(addr, size)\n ... self.sock.sendall(msg.encode('ascii'))\n ... \n ... received = []\n ... while True:\n ... x = self.sock.recv(4096)\n ... received.append(x)\n ... if b'\\n' in x:\n ... break\n ... \n ... msg = b''.join(received)\n ... data = bytes(int(b) for b in msg.split(b' '))\n ... return data\n\n >>> class DataStructure(Structure):\n ... _fields_ = [\n ... ('flags', c_uint32),\n ... ('_dummy1', c_uint32),\n ... ('offset', c_int32),\n ... ('slope', c_float)\n ... ]\n \n >>> sock = socket.create_connection(('1.2.3.4', 80))\n >>> handler = SerialHandler(sock)\n >>> rs = remotestruct.Remote(DataStructure, handler)\n >>> rs.flags\n 5\n >>> rs.flags = 183\n >>> rs.flags\n 183\n\nCachedHandler\n=============\nRemoteStructs can suffer from performance issues over slow transports; fetching\ndata that you know hasn't changed over and over again just because it was easier\nto write the code that way. The solution to this is to wrap the handler in a\nCachedHandler, which provides a flexible caching mechanism to prevent pulling\nknown data. The CachedHandler will, rather than pulling only the data requested,\nprefetch an entire aligned \"cache line\" of data based on the presumption that\nthe next data you'll need is likely to be physically near to the data you're \ncurrently asking for. So with the default 32 byte cacheline, a request for the\n2 bytes at address 40-41 will request all bytes 32-63, and store them in one of\nthe cache sets (default 8). This data will remain cached until it either times\nout or the cache set is overwritten by a new cacheline.\n\nRepeating the previous example with a CachedHandler would add::\n\n >>> sock = socket.create_connection(('1.2.3.4', 80))\n >>> basehandler = SerialHandler(sock)\n >>> cachedhandler = CachedHandler(\n\t... \thandler=basehandler,\n\t... \ttimeout=2.5\n\t... )\n >>> rs = remotestruct.Remote(DataStructure, cachedhandler)\n >>> rs.flags\n 5\n >>> rs.flags = 183\n >>> rs.flags\n 183\n\nThe CachedHandler is most useful with a timeout, which dictates how old data\nin the cache can be before it expires; in the example above the timeout is set\nto 2.5 seconds. A timeout of None means that data will never expire; a timeout\nof 0 means that data is always expired, effectively disabling the cache.\n\nThe CachedHandler has many options to control the number of cache sets and the\nlength of cache lines which you can easily spend your life tuning to try to get\nthe \"perfect\" cache settings. Don't do this. The CachedHandler can be\ninitialized with stats=True, which will make the cache keep statistics on hits,\nmisses and timeouts. If the cache is getting too many timeouts then you're \ngrabbing more data than you can use and should turn the cache line length down.\nIf you're getting too many misses then more cache sets or longer cache lines\nwill be your solution, depending on your data access patterns.\n\nThe CachedHandler also has nocache and noprefetch options to fine-tune control\nperformance; this can be essential to prevent destructive register accesses.\n\nChangelog\n---------\n\n0.3.1\n\tFixed some packaging problems.\n\n0.3.0\n\tTurned the .items iterator into a list. It's never going to be so long\n\tthat the overhead is a problem, and it makes interactive use from the\n\tcommand line so much easier.\n\t\n\tAdded the CachedHandler, and moved bitfield and remotestruct from being\n\tsingle modules to being full packages.\n\nWorks under Python 2.7+ and 3.2+\n\n:author: Rob Gaddi, Highland Technology, Inc.\n:date: 24-Aug-2015\n:version: 0.3.0\n", "description_content_type": null, "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/NJDFan/ctypes-bitfield/", "keywords": "sample bitfield register memory", "license": "MIT", "maintainer": "", "maintainer_email": "", "name": "ctypes-bitfield", "package_url": "https://pypi.org/project/ctypes-bitfield/", "platform": "", "project_url": "https://pypi.org/project/ctypes-bitfield/", "project_urls": { "Homepage": "https://github.com/NJDFan/ctypes-bitfield/" }, "release_url": "https://pypi.org/project/ctypes-bitfield/0.3.2/", "requires_dist": null, "requires_python": "", "summary": "Ctypes Register Bitfields", "version": "0.3.2" }, "last_serial": 3666711, "releases": { "0.1": [ { "comment_text": "", "digests": { "md5": "e9bcaec7bed51a9b6a07ac180c34e918", "sha256": "23898745ffa221fec63fd9fc15b6116eb1b54f9de75750668290382000667c08" }, "downloads": -1, "filename": "ctypes-bitfield-0.1.tar.gz", "has_sig": false, "md5_digest": "e9bcaec7bed51a9b6a07ac180c34e918", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 4410, "upload_time": "2014-05-08T22:03:28", "url": "https://files.pythonhosted.org/packages/cb/a0/4c2883af507cbd5ad9807bffaa4ef630e91149c868508c2a21534cfaf45c/ctypes-bitfield-0.1.tar.gz" } ], "0.2.6": [ { "comment_text": "", "digests": { "md5": "d1fa25fbc0ec9763c20eadf4ed98997b", "sha256": "3f7b4c30de93f0372786fc3cb682e2b3739a41d97ff3ae861d1417a62dbb4156" }, "downloads": -1, "filename": "ctypes-bitfield-0.2.6.tar.gz", "has_sig": false, "md5_digest": "d1fa25fbc0ec9763c20eadf4ed98997b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13189, "upload_time": "2014-09-02T23:42:14", "url": "https://files.pythonhosted.org/packages/d6/46/0837a7604dc1993666198c243ef109f4ea8c867590225839d5d9e6e19694/ctypes-bitfield-0.2.6.tar.gz" } ], "0.3.0": [ { "comment_text": "", "digests": { "md5": "9268635e1ced2b1c6266bff84be8554f", "sha256": "de391214ff4d9e6a4c4c9249cf3a55574016a50bae64157cdc3fe41abdfc82e2" }, "downloads": -1, "filename": "ctypes-bitfield-0.3.0.tar.gz", "has_sig": false, "md5_digest": "9268635e1ced2b1c6266bff84be8554f", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 36515, "upload_time": "2015-08-24T18:20:32", "url": "https://files.pythonhosted.org/packages/6e/d5/c5d0c1a8d08bc0cd6dc298378fe4d484d37db656dabb1a3710b8c6950c94/ctypes-bitfield-0.3.0.tar.gz" } ], "0.3.1": [ { "comment_text": "", "digests": { "md5": "b8b7e1286604f3fff76c4f9b06d1d404", "sha256": "5d1422bd829029930cd289aade0c0e4a22a3c69266037368a93e5332eaf2b12d" }, "downloads": -1, "filename": "ctypes-bitfield-0.3.1.tar.gz", "has_sig": false, "md5_digest": "b8b7e1286604f3fff76c4f9b06d1d404", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 30423, "upload_time": "2015-08-24T23:34:50", "url": "https://files.pythonhosted.org/packages/fe/77/255e20fdab448c19a13ecd70fe5cb78f34b56a169d30fbeb30a2b0fc604a/ctypes-bitfield-0.3.1.tar.gz" } ], "0.3.2": [ { "comment_text": "", "digests": { "md5": "0445290a41416420e57686c758f4497b", "sha256": "446dd03b37d91260fa18842d3e832a2ce91d7dd35e02b0e261c6733d87ac3710" }, "downloads": -1, "filename": "ctypes-bitfield-0.3.2.tar.gz", "has_sig": false, "md5_digest": "0445290a41416420e57686c758f4497b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 30434, "upload_time": "2018-03-13T21:03:18", "url": "https://files.pythonhosted.org/packages/f1/6e/bcd02789a537fec7ff9b02ba59ea7e75b07f610a5d7352fafa5d8bacf269/ctypes-bitfield-0.3.2.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "0445290a41416420e57686c758f4497b", "sha256": "446dd03b37d91260fa18842d3e832a2ce91d7dd35e02b0e261c6733d87ac3710" }, "downloads": -1, "filename": "ctypes-bitfield-0.3.2.tar.gz", "has_sig": false, "md5_digest": "0445290a41416420e57686c758f4497b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 30434, "upload_time": "2018-03-13T21:03:18", "url": "https://files.pythonhosted.org/packages/f1/6e/bcd02789a537fec7ff9b02ba59ea7e75b07f610a5d7352fafa5d8bacf269/ctypes-bitfield-0.3.2.tar.gz" } ] }