I am looking for debugging suggestions.
I have a system which works perfectly. I am #including a file, appname.ini, containing
static char appnamestring [] = "appname_1.1"; // max 32 bytes
It is returned by this function
// Function returns a pointer to the customer application string.
// This is the customer application name - max 32 bytes
char * get_appname(void)
{
#include "appname.ini"
return (char*) (appnamestring);
}
It is read-only so it would be sensible to make it "static const" but that blows up large chunks of the project, namely ETH and USB.
I know what "const" does: it leaves the string in flash and does not copy it to ram. So all the workspace locations in RAM shift down by 8 bytes (in this case - I used a shorter string)
Doing a diff on two .map files, this is all I see. Everything is there on the duff version. Just the addresses are lower on the duff one (the upper one).
The weird thing is that both ETH and USB die at the same time. All buffers that should be aligned are 4-aligned; in fact lots of stuff is 4-aligned (see the linkfile above). This box has been in development (in various guises; starting with the ST DISCO board) for about 8 years. Other issues e.g. DMA cannot access CCM (on the 32F4xx) should be OK by a) design and b) extensive devt over time.
I am sure this is something very simple, but ETH and USB cannot be debugged from first principles, with breakpoints, partly due to protocol timeouts and partly due to sheer complexity. ETH, like LWIP, runs as an RTOS task. USB is entirely interrupt-driven and there is an RTOS task which implements a VCP and MSC (the latter with FatFS).
Simplistically, the use of "const" breaks a huge amount of stuff. But there is another function which works on a similar string, but longer, which uses "static const", and that works. I also use const all over the place, for R/O strings.
Putting debugs in ETH shows no incoming data is seen by this function, which is pretty basic! Data is seen fine otherwise
HAL_StatusTypeDef IF_HAL_ETH_GetReceivedFrame(ETH_HandleTypeDef *heth)
{
uint32_t framelength = 0U;
/* Check if segment is not owned by DMA */
/* if (((heth->RxDesc->Status & ETH_DMARXDESC_OWN) == (uint32_t)RESET) && ((heth->RxDesc->Status & ETH_DMARXDESC_LS) != (uint32_t)RESET)) */
//__DMB();
if(((heth->RxDesc->Status & ETH_DMARXDESC_OWN) == (uint32_t)RESET))
{
/* Check if last segment */
if(((heth->RxDesc->Status & ETH_DMARXDESC_LS) != (uint32_t)RESET))
{
/* increment segment count */
(heth->RxFrameInfos).SegCount++;
/* Check if last segment is first segment: one segment contains the frame */
if ((heth->RxFrameInfos).SegCount == 1U)
{
(heth->RxFrameInfos).FSRxDesc =heth->RxDesc;
}
heth->RxFrameInfos.LSRxDesc = heth->RxDesc;
/* Get the Frame Length of the received packet: substruct 4 bytes of the CRC */
framelength = (((heth->RxDesc)->Status & ETH_DMARXDESC_FL) >> ETH_DMARXDESC_FRAMELENGTHSHIFT) - 4U;
heth->RxFrameInfos.length = framelength;
/* Get the address of the buffer start address */
heth->RxFrameInfos.buffer = ((heth->RxFrameInfos).FSRxDesc)->Buffer1Addr;
/* point to next descriptor */
heth->RxDesc = (ETH_DMADescTypeDef*) ((heth->RxDesc)->Buffer2NextDescAddr);
/* Return function status */
return HAL_OK;
}
/* Check if first segment */
else if((heth->RxDesc->Status & ETH_DMARXDESC_FS) != (uint32_t)RESET)
{
(heth->RxFrameInfos).FSRxDesc = heth->RxDesc;
(heth->RxFrameInfos).LSRxDesc = NULL;
(heth->RxFrameInfos).SegCount = 1U;
/* Point to next descriptor */
heth->RxDesc = (ETH_DMADescTypeDef*) (heth->RxDesc->Buffer2NextDescAddr);
}
/* Check if intermediate segment */
else
{
(heth->RxFrameInfos).SegCount++;
/* Point to next descriptor */
heth->RxDesc = (ETH_DMADescTypeDef*) (heth->RxDesc->Buffer2NextDescAddr);
}
}
/* Return function status */
return HAL_ERROR;
}
That suggests that ETH is just broken in some way. I am suspecting DMA...
Obviously I will poke about lots more but is this correct GCC format for alignment?
__ALIGN_BEGIN ETH_DMADescTypeDef DMARxDscrTab[ETH_RXBUFNB] __ALIGN_END;/* Ethernet Rx MA Descriptor */
__ALIGN_BEGIN ETH_DMADescTypeDef DMATxDscrTab[ETH_TXBUFNB] __ALIGN_END;/* Ethernet Tx DMA Descriptor */
__ALIGN_BEGIN uint8_t Rx_Buff[ETH_RXBUFNB][ETH_RX_BUF_SIZE] __ALIGN_END; /* Ethernet Receive Buffer */
__ALIGN_BEGIN uint8_t Tx_Buff[ETH_TXBUFNB][ETH_TX_BUF_SIZE] __ALIGN_END; /* Ethernet Transmit Buffer */