Hi, I examined the proposed fix and the root cause of the issue. I found out that all network related types definitions are missing the "packed" attribute hence the crash on certain platforms may happen. Actually we should have begin_packed_struct 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) */ } end_packed_struct;
And the same for all network related types, so we can eliminate problems like this. As an alternative hotfix I can propose move pktbuf[CONFIG_NET_ETH_PKTSIZE + CONFIG_NET_GUARDSIZE]; to be heap allocated (actually currently it already is), so we should remove "pktbuf" from "struct cdcecm_driver_s" and replace "self->dev.d_buf = self->pktbuf;" with "self->dev.d_buf = kmm_zalloc(CONFIG_NET_ETH_PKTSIZE + CONFIG_NET_GUARDSIZE);". The "kmm_free(self->dev.d_buf);" should be added in prior to any "kmm_free(self);". In this case alignment will be handled by memory allocator. Best regards, Petro пн, 17 січ. 2022 р. о 14:53 Kalbus, Peter <p...@mailbox.org.invalid> пише: > 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 > >>>> > >>>> > >> > >> >