2022-06-30 08:37 AM
Hi,
i am having problems with TouchGFX generated Project and LWIP/Ethernet
My Software setup:
STMCubeIDE Version: 1.9.0
TouchGFX Version: 4.19.1
STM32Cube_FW_H7_V1.10.0
My Hardware setup:
STM32H747I-DISCO
I have followed the steps in the ST-article How-to-create-project-for-STM32H7-with-Ethernet-and-LwIP-stack-working (can't add link) but can't ping the board. There is no Ethernet interrupt or RX callback, but GPIOs are set to high speed and ETH global interrupt is enabled and set to priorty 5 - preemption and 0 - subpriority.
Ping works in the attached example from the article, even when I migrate to the new H7-FW (after using the steps under 10. STM32Cube_FW_H7_V1.10.0 (and newer) specific issues).
I think there might be a problem with the MPU region, since I read somewhere that the M4 core is accessing the 0x30040000 with 0x10040000 and I have setup the same address there (sorry i am new to dualcore and mpu configs - see region 4 to 7 in my config). here is my config:
void MPU_Config(void)
{
MPU_Region_InitTypeDef MPU_InitStruct = {0};
/* Disables the MPU */
HAL_MPU_Disable();
/** Initializes and configures the Region and the memory to be protected
*/
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER0;
MPU_InitStruct.BaseAddress = 0x90000000;
MPU_InitStruct.Size = MPU_REGION_SIZE_256MB;
MPU_InitStruct.SubRegionDisable = 0x0;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/** Initializes and configures the Region and the memory to be protected
*/
MPU_InitStruct.Number = MPU_REGION_NUMBER1;
MPU_InitStruct.Size = MPU_REGION_SIZE_128MB;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/** Initializes and configures the Region and the memory to be protected
*/
MPU_InitStruct.Number = MPU_REGION_NUMBER2;
MPU_InitStruct.BaseAddress = 0xD0000000;
MPU_InitStruct.Size = MPU_REGION_SIZE_32MB;
MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/** Initializes and configures the Region and the memory to be protected
*/
MPU_InitStruct.Number = MPU_REGION_NUMBER3;
MPU_InitStruct.BaseAddress = 0x24000000;
MPU_InitStruct.Size = MPU_REGION_SIZE_512KB;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/** Initializes and configures the Region and the memory to be protected
*/
MPU_InitStruct.Number = MPU_REGION_NUMBER4;
MPU_InitStruct.BaseAddress = 0x10000000;
MPU_InitStruct.Size = MPU_REGION_SIZE_256KB;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/** Initializes and configures the Region and the memory to be protected
*/
MPU_InitStruct.Number = MPU_REGION_NUMBER5;
MPU_InitStruct.BaseAddress = 0x10040000;
MPU_InitStruct.Size = MPU_REGION_SIZE_32KB;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/** Initializes and configures the Region and the memory to be protected
*/
MPU_InitStruct.Number = MPU_REGION_NUMBER6;
MPU_InitStruct.BaseAddress = 0x30040000;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL1;
MPU_InitStruct.AccessPermission = MPU_REGION_NO_ACCESS;
MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/** Initializes and configures the Region and the memory to be protected
*/
MPU_InitStruct.Number = MPU_REGION_NUMBER7;
MPU_InitStruct.Size = MPU_REGION_SIZE_256B;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/* Enables the MPU */
HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
}
Another clue I got is this: in the ethernetif.h there is this complete section grayes out, but i am using the GNU Compiler:
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma location = 0x30000260
extern u8_t memp_memory_RX_POOL_base[];
#elif defined ( __CC_ARM ) /* MDK ARM Compiler */
__attribute__((at(0x30000260)) extern u8_t memp_memory_RX_POOL_base[];
#elif defined ( __GNUC__ ) /* GNU Compiler */
__attribute__((section(".Rx_PoolSection"))) extern u8_t memp_memory_RX_POOL_base[];
#endif
So I think the problem could be the structure of the TouchGFX generated Project.
On the left is the TouchGFX generated Project, which links only some files to the CM7 Subproject and on the right is the example project which has the files directly included in the CM7 subproject
Thank you for any help and hints!
2022-06-30 09:45 PM
Regarding MPU: It is important to set correct parameters for TX and RX DMA descriptors:
1. in linker LD file check .lwip_sec section for addresses in use
2. in ethernetif.c you should check corresponding __attribute__((section(".XxDescripSection"))); at DMARxDscrTab[] and DMATxDscrTab[] arrays
3. in main.c check that region set for DMA descriptors in linker LD file have:
attributes. CubeIDE can set single attribute in the beginning of function and then use it for many sections. So check what is set in sections above 4 and if you are going to change it manually, then also think about sections below you have just changed.
2022-07-01 12:57 AM
Thanks for the fast answer!
1. In the linker file .._FLASH.ld I already had added the .lwip section:
.lwip_sec (NOLOAD):
{
. = ABSOLUTE(0x30040000);
*(.RxDescripSection)
. = ABSOLUTE(0x30040060);
*(.TxDescripSection)
. = ABSOLUTE(0x30040200);
*(.Rx_PoolSection)
} > RAM_D2
2. in ethernetif.c DMARxDscrTab[] and DMATxDscrTab[] arrays also seem to be inactive. So I think this could be the error. I noticed before that some defines can't be found because only c files are linked into the project.
3. in main.c these are the regions I had added. Access Permission was set to ALL ACCESS NOT PERMITTED. I changed it, but still can't ping the board.
2022-07-01 01:08 AM
Check what is with your DMA descriptor tables. (Probably you just need to rebuild index - sometimes CubeIDE doesn't highlight code properly until index is rebuilt)
Last section (for __GNUC__) should be enabled. Otherwise your will have compilation errors.
2022-07-01 01:59 AM
Rebuilding the index does not solve the problem. I checked the comiler flag: it is set to __GNUC__ in the project, but the ethernetif.h and .c files are not linked in the project. They are located in the CM7/LWIP/Target/ folder and the STM32H747I-DISCO_CM7 Project has only linked the LwIP files from the Middlewares/Third_Party/LwIP/ folder.
Any advice whats the best way to handle the TouchGFX generated Project? I think it is very unhandy that only some files get linked to the project. For example defines in main.h are not known to files in the project which include main.h. Do I have to add new .c and .h files in the CM7/Core/ folder and link them to the project?
2022-07-01 02:09 AM
Here is my project structure:
Both lwip.c and ethernetif.c are located in LWIP\Target folder and linked to the project:
2022-07-01 02:18 AM
Thanks, now I see it, too! It's the same link in my project and when I open ethernetif.c with the link, the compiler flag for __GNUC__ is recognized.
2022-07-01 02:28 AM
Now use debugger and make sure
1) your Ethernet init functions are called
2) your Ethernet interrupt is fired
2022-07-01 02:47 AM
The Ethernet init function was not called because it was added to the __weak void TouchGFX_Task(void *argument) by CubeIDE. Now the Ethernet interrupt is also called and the ping works :)
Thank you very much!!!
2022-07-01 05:39 AM
Glad I was able to help!
Now you should give your board some traffic load and check it for stability over at least a couple of days. With constant traffic and wrong/minimal lwIP/FreeRTOS settings it could fail any time from several minutes to several hours