Вопрос

I'm trying to make an 11-bit ID field for a CAN communication channel. I think I should be able to use:

import ctypes
class ID(ctypes.Union):
    _fields_ = [('device', ctypes.c_int, 3),  # 3 bits for device id
                ('message', ctypes.c_int, 8)]  # 8 bits for message ID

The issue is what happens when I try to validate that an instance of this class is what I wanted. Specifically:

>>> x = ID()
>>> type(x.device)
<type 'int'>

Why is that an int and not a c_int? Likewise:

>>> x = ID()
>>> x.device.bit_length()
0

which is precisely what I didn't want.

EDIT:

Thanks for the help! I should definitely be using a struct.

I'm trying to make an object that represents the identifier and data sections of a CAN data frame. The convention I'm working with further divides the identifier frame into 3- and 8-bit segments, representing the device and message ID, respectively. what I'd like is a class representing the identifier frame, in which I can assign values to members corresponding to my convention's device and message IDs, and which serializes into an 11-bit ID value.

Maybe I need to take another look at the C library I'm using for the CAN channel--it may be that I can use a 16-bit struct of which I only use 11 bits.

Это было полезно?

Решение

Inside the Union, the device member is stored using 8 bits.

However, ctypes will automatically convert back and forth to native int types for you, using (a good approximation of) the usual C rules for converting between types. For example, try this:

>>> x.device = 257
>>> x.device
1

So, you don't have anything to fix here.


However, you do have a problem:

I'm trying to make an 11-bit ID field for a CAN communication channel.

A Union of an 8-bit int and a 3-bit int is 8 bits, just as in C. You want a Struct. See Structures and unions and the type references linked from there for details.

On top of that, while a Struct of a 3-bit int and an 8-bit int only has 11 bits of useful information, it will almost certainly take up at least 16 bits of memory, with 5 bits of padding.* You can only address memory a byte (8 bits) at a time. So… I'm not sure exactly what you were trying to do with this ID, but I suspect it's not going to work. If you explain your actual problem, ideally with some complete sample code, we can probably help.


* In fact, at least in current CPython versions, it will actually take up 32 bits of memory. See eryksun's comments for more details.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top