Understood … but I‘d like to separate them in two different PRs … mixing up 
things is rarely a good idea … I‘ll create PR for the alignment issue later 
today. The PR for the general CDCECM on RP2040 will follow as it’s complete. 

/Piet


> Am 17.01.2022 um 13:43 schrieb Alan Carvalho de Assis <acas...@gmail.com>:
> 
> It is possible to send two type of modifications in a single PR when
> they are relative to the same logic goal (that is the case here).
> 
> But please separate CDCECM support to rp2040 in a commit and the
> alignment in another commit, so in the PR description you can use
> something like this:
> Add support to CDCECM for RaspberryPi Pico and fix an alignment issue.
> 
> BR,
> 
> Alan
> 
>> On 1/17/22, Peter Kalbus <p...@me.com.invalid> wrote:
>> Hi Alan,
>> 
>> sure … can I create a PR from a single chasnge?
>> 
>> Background is, that I have two changes on the branch:
>> 
>>    - older one: get CDCECM enabled in RP2040 in general —> not yet fully done
>>    - newer one: the fix from alignment issue
>> 
>> /Piet
>> 
>> 
>>> Am 17.01.2022 um 13:08 schrieb Alan Carvalho de Assis
>>> <acas...@gmail.com>:
>>> 
>>> Hi Peter,
>>> 
>>> Could you please send a Pull Request to mainline? Click on Pull
>>> Request tab and New Pull Request.
>>> 
>>> BR,
>>> 
>>> Alan
>>> 
>>> On 1/17/22, Peter Kalbus <p...@mailbox.org.invalid> wrote:
>>>> Hi Michael,
>>>> 
>>>> understood … I changed the fix according to you proposal and tested it …
>>>> works fine,too:
>>>> 
>>>> https://github.com/ptka/incubator-nuttx/commit/09be64bb1f2fff9f85a392e0fab6915f9083fe2d
>>>> <https://github.com/ptka/incubator-nuttx/commit/09be64bb1f2fff9f85a392e0fab6915f9083fe2d>
>>>> 
>>>> struct cdcecm_driver_s
>>>> {
>>>> /* USB CDC-ECM device */
>>>> 
>>>> struct usbdevclass_driver_s  usbdev;      /* USB device class vtable */
>>>> struct usbdev_devinfo_s      devinfo;
>>>> FAR struct usbdev_req_s     *ctrlreq;     /* Allocated control request
>>>> */
>>>> FAR struct usbdev_ep_s      *epint;       /* Interrupt IN endpoint */
>>>> FAR struct usbdev_ep_s      *epbulkin;    /* Bulk IN endpoint */
>>>> FAR struct usbdev_ep_s      *epbulkout;   /* Bulk OUT endpoint */
>>>> uint8_t                      config;      /* Selected configuration
>>>> number
>>>> */
>>>> 
>>>> aligned_data(2) uint8_t      pktbuf[CONFIG_NET_ETH_PKTSIZE +
>>>>                                     CONFIG_NET_GUARDSIZE];
>>>> 
>>>> struct usbdev_req_s         *rdreq;       /* Single read request */
>>>> 
>>>> 
>>>> /Piet
>>>> 
>>>> 
>>>>> Am 17.01.2022 um 10:42 schrieb Michael Jung <mij...@gmx.net>:
>>>>> 
>>>>> Hi Peter,
>>>>> 
>>>>> good finding!
>>>>> 
>>>>> There is actually a comment in this regard in
>>>>> include/nuttx/net/netdev.h:
>>>>>> The d_buf array must be aligned to two-byte, 16-bit address boundaries
>>>>>> in
>>>>> order to support aligned 16-bit accesses performed by the network.
>>>>> 
>>>>> W.r.t. to your proposed fix I think it would be more appropriate to
>>>>> make
>>>>> the alignment requirement explicit by using the 'aligned_data' macro
>>>>> from
>>>>> include/nuttx/compiler.h.
>>>>> 
>>>>> Thanks!
>>>>> Michael
>>>>> 
>>>>> Am Mo., 17. Jan. 2022 um 09:01 Uhr schrieb Peter Kalbus
>>>>> <p...@mailbox.org.invalid <mailto:p...@mailbox.org.invalid>>:
>>>>> 
>>>>>> Hi all,
>>>>>> 
>>>>>> during the bring-up of the composite-cdcecm a alignment issue result
>>>>>> in
>>>>>> hard faults (always on the used rp2040 based device).
>>>>>> 
>>>>>> ANALYSIS:
>>>>>> 
>>>>>> The root cause seems to be the way the pktbuf is defined in
>>>>>> cdcecm_driver_s (driver/usbdev/cdcecm.c):
>>>>>> 
>>>>>> struct cdcecm_driver_s
>>>>>> {
>>>>>> /* USB CDC-ECM device */
>>>>>> 
>>>>>> struct usbdevclass_driver_s  usbdev;      /* USB device class vtable
>>>>>> */
>>>>>> struct usbdev_devinfo_s      devinfo;
>>>>>> FAR struct usbdev_req_s     *ctrlreq;     /* Allocated control request
>>>>>> */
>>>>>> FAR struct usbdev_ep_s      *epint;       /* Interrupt IN endpoint */
>>>>>> FAR struct usbdev_ep_s      *epbulkin;    /* Bulk IN endpoint */
>>>>>> FAR struct usbdev_ep_s      *epbulkout;   /* Bulk OUT endpoint */
>>>>>> uint8_t                      config;      /* Selected configuration
>>>>>> number */
>>>>>> 
>>>>>> uint8_t                      pktbuf[CONFIG_NET_ETH_PKTSIZE +
>>>>>>                                    CONFIG_NET_GUARDSIZE];
>>>>>> 
>>>>>> 
>>>>>> Due to 'config‘ element ‚ pktbuf‘ in the structure is not aligned in
>>>>>> anyway from the struct itself.
>>>>>> 
>>>>>> The driver structure is allocation during driver initialization in
>>>>>> cdcecm_classobject():
>>>>>> 
>>>>>> /* Initialize the driver structure */
>>>>>> 
>>>>>> self = kmm_zalloc(sizeof(struct cdcecm_driver_s));
>>>>>> if (!self)
>>>>>>  {
>>>>>>    nerr("Out of memory!\n");
>>>>>>    return -ENOMEM;
>>>>>>  }
>>>>>> 
>>>>>> /* Network device initialization */
>>>>>> 
>>>>>> self->dev.d_buf     = self->pktbuf;
>>>>>> 
>>>>>> As ’ self’ points to an aligned address, 'pktbuf' is always aligned at
>>>>>> an
>>>>>> odd address.
>>>>>> 
>>>>>> Once the driver is initialized and processes received data in
>>>>>> cdcecm_receive() the driver creates a hard fault at:
>>>>>> 
>>>>>> #ifdef CONFIG_NET_IPv4
>>>>>> if (BUF->type == HTONS(ETHTYPE_IP))
>>>>>>  {
>>>>>> 
>>>>>> BUF/eth_hdr_s are defined as:
>>>>>> 
>>>>>> #define BUF ((struct eth_hdr_s *)self->dev.d_buf)
>>>>>> 
>>>>>> 
>>>>>> struct eth_hdr_s
>>>>>> {
>>>>>> uint8_t  dest[6]; /* Ethernet destination address (6 bytes) */
>>>>>> uint8_t  src[6];  /* Ethernet source address (6 bytes) */
>>>>>> uint16_t type;    /* Type code (2 bytes) */
>>>>>> };
>>>>>> 
>>>>>> 
>>>>>> Element ’ type’ is always odd aligned and access to it results in all
>>>>>> cases to a hard fault on the used rp2040 based board.
>>>>>> 
>>>>>> PROPOSAL:
>>>>>> 
>>>>>> Assuming the analysis is correct, there could be different options to
>>>>>> fix
>>>>>> there issue.
>>>>>> Proposal would be to let the compiler do the job and not introduce any
>>>>>> special code or elements in the structure to fix it programmatically.
>>>>>> 
>>>>>> Analysing cdcdcm_driver_s in more details:
>>>>>> 
>>>>>> FAR struct usbdev_ep_s      *epbulkout;   /* Bulk OUT endpoint */
>>>>>> uint8_t                      config;      /* Selected configuration
>>>>>> number */
>>>>>> 
>>>>>> uint8_t                      pktbuf[CONFIG_NET_ETH_PKTSIZE +
>>>>>>                                    CONFIG_NET_GUARDSIZE];
>>>>>> 
>>>>>> 
>>>>>> Element 'epbulkout' is a 32bit pointer and thus always aligned to
>>>>>> 32bit.
>>>>>> Element 'config‘ following is also aligned to 32bit —> as it’s only an
>>>>>> uint8_t is doesn’t need to be aligned at all.
>>>>>> Element ‚pktbuf‘ is odd aligned, but needs to be at least 16bit
>>>>>> aligned.
>>>>>> 
>>>>>> Exchanging 'config‘ and 'pktbuf‘ in the structure solves the issue:
>>>>>> 
>>>>>> FAR struct usbdev_ep_s      *epbulkout;   /* Bulk OUT endpoint */
>>>>>> 
>>>>>> uint8_t                      pktbuf[CONFIG_NET_ETH_PKTSIZE +
>>>>>>                                    CONFIG_NET_GUARDSIZE];
>>>>>> 
>>>>>> uint8_t                      config;      /* Selected configuration
>>>>>> number */
>>>>>> 
>>>>>> 
>>>>>> Element ‚pktbuf‘ is now 32bit aligned as it’s following a 32bit
>>>>>> pointer.
>>>>>> 
>>>>>> The change has been tested on an rp2040 based device.
>>>>>> 
>>>>>> The fix can be reviewed at:
>>>>>> https://github.com/ptka/incubator-nuttx/commit/01732850ad345b5e2a9af24f788935d8f7928781
>>>>>> <
>>>>>> https://github.com/ptka/incubator-nuttx/commit/01732850ad345b5e2a9af24f788935d8f7928781
>>>>>> <https://github.com/ptka/incubator-nuttx/commit/01732850ad345b5e2a9af24f788935d8f7928781>
>>>>>>> 
>>>>>> 
>>>>>> Please comment on the analysis and proposed fix.
>>>>>> 
>>>>>> /Piet
>>>> 
>>>> 
>> 
>> 

Reply via email to