All of lore.kernel.org
 help / color / mirror / Atom feed
* correct length of bcm message
@ 2021-02-04 15:38 Patrick Menschel
  2021-02-04 17:47 ` Patrick Menschel
  0 siblings, 1 reply; 7+ messages in thread
From: Patrick Menschel @ 2021-02-04 15:38 UTC (permalink / raw)
  To: linux-can

Hi,

is anyone writing to BCMSocket on the Raspberry Pi from Python3 ?

I'm digging through an endianess / alignment issue on armhf platform.

My testcode [1] that I wrote years ago on works on X86_64 platform but
fails on armhf platform with OSERROR 22 "invalid argument".

Then I started concatenating bytes by hand instead of using ctypes.

What I came around is that frames[0] is somehow expected to be 8 bytes
length although it should be 16 bytes.

struct bcm_msg_head {
...
        struct can_frame frames[0];
};

I ended up inserting padding 8 bytes instead of frames[0] value and that
actually works.

That makes my overall BCMHead 40 bytes and the complete bcm message
including the can frame 56bytes.

[1] https://github.com/menschel/pysocketcan

Thanks,
Patrick

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: correct length of bcm message
  2021-02-04 15:38 correct length of bcm message Patrick Menschel
@ 2021-02-04 17:47 ` Patrick Menschel
  2021-02-04 20:14   ` Oliver Hartkopp
  0 siblings, 1 reply; 7+ messages in thread
From: Patrick Menschel @ 2021-02-04 17:47 UTC (permalink / raw)
  To: linux-can

Am 04.02.21 um 16:38 schrieb Patrick Menschel:
> Hi,
> 
> is anyone writing to BCMSocket on the Raspberry Pi from Python3 ?
> 
> I'm digging through an endianess / alignment issue on armhf platform.
> 
> My testcode [1] that I wrote years ago on works on X86_64 platform but
> fails on armhf platform with OSERROR 22 "invalid argument".

Some more details.

The length on X86_64 results in 72 bytes which are consumed by bcm.

On armhf it results in 52 bytes which cause OSError: [Errno 22] Invalid
argument.

> 
> Then I started concatenating bytes by hand instead of using ctypes.
> 
> What I came around is that frames[0] is somehow expected to be 8 bytes
> length although it should be 16 bytes.
> 
> struct bcm_msg_head {
> ...
>         struct can_frame frames[0];
> };
> 
> I ended up inserting padding 8 bytes instead of frames[0] value and that
> actually works.

I have to amend that, it's 4 padding bytes.

struct.pack("=IIIllllII4xIB3x8s",opcode,flags,count,ival1_sec,ival1_usec,ival2_sec,ival2_usec,can_id,nframes,can_id,can_dlc,data)
                       ^^ padding bytes

Sending the resulting 56bytes to bcmsocket gets me a cyclic message on
armhf.

> 
> That makes my overall BCMHead 40 bytes and the complete bcm message
> including the can frame 56bytes.
> 
> [1] https://github.com/menschel/pysocketcan
> 

Thanks,
Patrick

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: correct length of bcm message
  2021-02-04 17:47 ` Patrick Menschel
@ 2021-02-04 20:14   ` Oliver Hartkopp
  2021-02-05  8:27     ` Patrick Menschel
  0 siblings, 1 reply; 7+ messages in thread
From: Oliver Hartkopp @ 2021-02-04 20:14 UTC (permalink / raw)
  To: Patrick Menschel, linux-can

Hello Patrick,

On 04.02.21 18:47, Patrick Menschel wrote:
> Am 04.02.21 um 16:38 schrieb Patrick Menschel:
>> Hi,
>>
>> is anyone writing to BCMSocket on the Raspberry Pi from Python3 ?
>>
>> I'm digging through an endianess / alignment issue on armhf platform.
>>
>> My testcode [1] that I wrote years ago on works on X86_64 platform but
>> fails on armhf platform with OSERROR 22 "invalid argument".
> 
> Some more details.
> 
> The length on X86_64 results in 72 bytes which are consumed by bcm.
> 
> On armhf it results in 52 bytes which cause OSError: [Errno 22] Invalid
> argument.
> 
>>
>> Then I started concatenating bytes by hand instead of using ctypes.
>>
>> What I came around is that frames[0] is somehow expected to be 8 bytes
>> length although it should be 16 bytes.

struct can_frames[0] is used in this struct definition to point out, 
that this struct is followed by a number (0..257) struct can_frame's.

This creates a padding at the end of struct bcm_head, so that the struct 
can_frame (which is always 64 bit aligned) can be directly concatenated.

Regards,
Oliver

>>
>> struct bcm_msg_head {
>> ...
>>          struct can_frame frames[0];
>> };
>>
>> I ended up inserting padding 8 bytes instead of frames[0] value and that
>> actually works.
> 
> I have to amend that, it's 4 padding bytes.
> 
> struct.pack("=IIIllllII4xIB3x8s",opcode,flags,count,ival1_sec,ival1_usec,ival2_sec,ival2_usec,can_id,nframes,can_id,can_dlc,data)
>                         ^^ padding bytes
> 
> Sending the resulting 56bytes to bcmsocket gets me a cyclic message on
> armhf.
> 
>>
>> That makes my overall BCMHead 40 bytes and the complete bcm message
>> including the can frame 56bytes.
>>
>> [1] https://github.com/menschel/pysocketcan
>>
> 
> Thanks,
> Patrick
> 

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: correct length of bcm message
  2021-02-04 20:14   ` Oliver Hartkopp
@ 2021-02-05  8:27     ` Patrick Menschel
  2021-02-05  9:01       ` Oliver Hartkopp
  0 siblings, 1 reply; 7+ messages in thread
From: Patrick Menschel @ 2021-02-05  8:27 UTC (permalink / raw)
  To: Oliver Hartkopp, linux-can

Thanks Oliver,

Am 04.02.21 um 21:14 schrieb Oliver Hartkopp:
> struct can_frames[0] is used in this struct definition to point out,
> that this struct is followed by a number (0..257) struct can_frame's.
> 
> This creates a padding at the end of struct bcm_head, so that the struct
> can_frame (which is always 64 bit aligned) can be directly concatenated.

so this behavior is caused by this alignment

struct can_frame {
    ...
    __u8    data[8] __attribute__((aligned(8)));
}

and walks back upwards to

nframes (end at 36 bytes)
...
< 4 bytes gap >
...
frames (start at 40 bytes)

Should the alignment not be defined on structure instead?

struct can_frame __attribute__((aligned(8))) {
...
}


Interesting to know, apparently native alignment is 8 on X86_64 linux
and 4 on armhf linux. That's why it worked on X86_64.

Regarding python ctypes module, setting _pack_=8 has no remedy effect on
armhf platform, so I'll move to struct module.

Thanks again.

Regards,
Patrick

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: correct length of bcm message
  2021-02-05  8:27     ` Patrick Menschel
@ 2021-02-05  9:01       ` Oliver Hartkopp
  2021-02-07  6:33         ` Patrick Menschel
  0 siblings, 1 reply; 7+ messages in thread
From: Oliver Hartkopp @ 2021-02-05  9:01 UTC (permalink / raw)
  To: Patrick Menschel, linux-can



On 05.02.21 09:27, Patrick Menschel wrote:

> Am 04.02.21 um 21:14 schrieb Oliver Hartkopp:
>> struct can_frames[0] is used in this struct definition to point out,
>> that this struct is followed by a number (0..257) struct can_frame's.
>>
>> This creates a padding at the end of struct bcm_head, so that the struct
>> can_frame (which is always 64 bit aligned) can be directly concatenated.
> 
> so this behavior is caused by this alignment
> 
> struct can_frame {
>      ...
>      __u8    data[8] __attribute__((aligned(8)));
> }
> 
> and walks back upwards to
> 
> nframes (end at 36 bytes)
> ...
> < 4 bytes gap >
> ...
> frames (start at 40 bytes)
> 
> Should the alignment not be defined on structure instead?
> 
> struct can_frame __attribute__((aligned(8))) {
> ...
> }

Hm, the original idea was to be able to access the data[] with a 64 bit 
aligned access, e.g. to initialize the content by a single assignment.

The can_id and the other stuff (len, flags, padding, whatever) before 
the data[] section is intentionally also 64 bit long.

So it should be no difference in functionality.

> Interesting to know, apparently native alignment is 8 on X86_64 linux
> and 4 on armhf linux. That's why it worked on X86_64.
> 
> Regarding python ctypes module, setting _pack_=8 has no remedy effect on
> armhf platform, so I'll move to struct module.

Regards,
Oliver

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: correct length of bcm message
  2021-02-05  9:01       ` Oliver Hartkopp
@ 2021-02-07  6:33         ` Patrick Menschel
  2021-02-07 18:23           ` Oliver Hartkopp
  0 siblings, 1 reply; 7+ messages in thread
From: Patrick Menschel @ 2021-02-07  6:33 UTC (permalink / raw)
  To: linux-can

>> Interesting to know, apparently native alignment is 8 on X86_64 linux
>> and 4 on armhf linux. That's why it worked on X86_64.
>>
>> Regarding python ctypes module, setting _pack_=8 has no remedy effect on
>> armhf platform, so I'll move to struct module.

Hi,

tying some loose ends here.
My final solution to force alignment after bcm_msg_head to the next 8
byte boundary in python3 is to use an alignment hack of struct module.
https://docs.python.org/3/library/struct.html#struct-examples

struct.pack("IIIllllII0q",opcode,flags,count,ival1_sec,ival1_usec,ival2_sec,ival2_usec,can_id,nframes)

The "0q" is a zero length long long which causes padding up to the next
8 byte boundary.

This works for ARMHF (40 bytes) and X86_64 (72 bytes).

Regards,
Patrick

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: correct length of bcm message
  2021-02-07  6:33         ` Patrick Menschel
@ 2021-02-07 18:23           ` Oliver Hartkopp
  0 siblings, 0 replies; 7+ messages in thread
From: Oliver Hartkopp @ 2021-02-07 18:23 UTC (permalink / raw)
  To: Patrick Menschel, linux-can



On 07.02.21 07:33, Patrick Menschel wrote:
>>> Interesting to know, apparently native alignment is 8 on X86_64 linux
>>> and 4 on armhf linux. That's why it worked on X86_64.
>>>
>>> Regarding python ctypes module, setting _pack_=8 has no remedy effect on
>>> armhf platform, so I'll move to struct module.
> 
> Hi,
> 
> tying some loose ends here.
> My final solution to force alignment after bcm_msg_head to the next 8
> byte boundary in python3 is to use an alignment hack of struct module.
> https://docs.python.org/3/library/struct.html#struct-examples
> 
> struct.pack("IIIllllII0q",opcode,flags,count,ival1_sec,ival1_usec,ival2_sec,ival2_usec,can_id,nframes)
> 
> The "0q" is a zero length long long which causes padding up to the next
> 8 byte boundary.

Excellent! Exactly what is needed here.

Thanks,
Oliver

> This works for ARMHF (40 bytes) and X86_64 (72 bytes).
> 
> Regards,
> Patrick
> 

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2021-02-07 18:27 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-02-04 15:38 correct length of bcm message Patrick Menschel
2021-02-04 17:47 ` Patrick Menschel
2021-02-04 20:14   ` Oliver Hartkopp
2021-02-05  8:27     ` Patrick Menschel
2021-02-05  9:01       ` Oliver Hartkopp
2021-02-07  6:33         ` Patrick Menschel
2021-02-07 18:23           ` Oliver Hartkopp

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.