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