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