Skip to main content
Visitor II
March 11, 2024
Solved

MQTT pbuf_free: p->ref > 0 error

  • March 11, 2024
  • 2 replies
  • 2351 views

I am working on an STM32f767 project with LWIP and MQTT. Everything seemed to work for a while but eventually, I received the following assert:  "pbuf_free: p->ref > 0..." which caused it to crash sometimes; but sometimes it will continue to work without any issue.  Has anyone had a similar issue?

According to LWIP_IAP example, memory location 0x20048000 is labeled as ethernet rx buffer location; however, I could not find where this location is linked to the ethernet rx buffer. for example, 0x2007C000 memory location in the linker file for RxDescripSection & TxDecripSection. And does the size of the MPU region have to be equal to or greater than MEM_SIZE defined in opt.h?

 

My settings: 

LinkerScript.ld

Memory_B1(xrw) : ORIGIN = 0x2004C000, LENGTH = 0xA0

Memory_B2(xrw) : ORIGIN = 0x2004C0A0, LENGTH = 0xA0

 

.RxDecripSection (NOLOAD) : { *(.RxDescripSection) } >Memory_B1

.TxDecripSection (NOLOAD) : { *(.DMATxDscrTab_section) } >Memory_B2

.ARM.attributes 0 : { *(.ARM.attributes) }

 

main.c 

 

/* Configure the MPU as Normal Non Cacheable for Ethernet Buffers in the SRAM2 */

MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.BaseAddress = 0x20048000;
MPU_InitStruct.Size = MPU_REGION_SIZE_16KB;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER1;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL1;
MPU_InitStruct.SubRegionDisable = 0x00;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;

HAL_MPU_ConfigRegion(&MPU_InitStruct);

 

/* Configure the MPU as Device for Ethernet Descriptors in the SRAM2 */
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.BaseAddress = 0x2004C000;
MPU_InitStruct.Size = MPU_REGION_SIZE_1KB;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER2;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.SubRegionDisable = 0x00;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE

HAL_MPU_ConfigRegion(&MPU_InitStruct);

 

    This topic has been closed for replies.
    Best answer by STea

    Hello @cleonb322 ,

    based on the example LwIP_HTTP_Server_Netconn_RTOS  your MPU configuration should be as follows as you are using an STM32F767 check RM0410

    STea_0-1720191391274.png

    static void MPU_Config(void)
    {
     MPU_Region_InitTypeDef MPU_InitStruct;
    
     /* Disable the MPU */
     HAL_MPU_Disable();
    
     /* Configure the MPU as Strongly ordered for not defined regions */
     MPU_InitStruct.Enable = MPU_REGION_ENABLE;
     MPU_InitStruct.BaseAddress = 0x00;
     MPU_InitStruct.Size = MPU_REGION_SIZE_4GB;
     MPU_InitStruct.AccessPermission = MPU_REGION_NO_ACCESS;
     MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
     MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
     MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
     MPU_InitStruct.Number = MPU_REGION_NUMBER0;
     MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
     MPU_InitStruct.SubRegionDisable = 0x87;
     MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
    
     HAL_MPU_ConfigRegion(&MPU_InitStruct);
    
     /* Configure the MPU as Normal Non Cacheable for Ethernet Buffers in the SRAM2 */
     MPU_InitStruct.Enable = MPU_REGION_ENABLE;
     MPU_InitStruct.BaseAddress = 0x20078000;
     MPU_InitStruct.Size = MPU_REGION_SIZE_16KB;
     MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
     MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
     MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
     MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
     MPU_InitStruct.Number = MPU_REGION_NUMBER1;
     MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL1;
     MPU_InitStruct.SubRegionDisable = 0x00;
     MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
    
     HAL_MPU_ConfigRegion(&MPU_InitStruct);
    
     /* Configure the MPU as Device for Ethernet Descriptors in the SRAM2 */
     MPU_InitStruct.Enable = MPU_REGION_ENABLE;
     MPU_InitStruct.BaseAddress = 0x2007C000;
     MPU_InitStruct.Size = MPU_REGION_SIZE_1KB;
     MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
     MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;
     MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
     MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
     MPU_InitStruct.Number = MPU_REGION_NUMBER2;
     MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
     MPU_InitStruct.SubRegionDisable = 0x00;
     MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
    
     HAL_MPU_ConfigRegion(&MPU_InitStruct);
     
     /* Enable the MPU */
     HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
    }

    The MPU configuration you are using is valid for stm32f75xx and stm32f74xx check RM0385

    STea_1-1720191644932.png


    Regards

     

    2 replies

    STeaAnswer
    ST Employee
    July 5, 2024

    Hello @cleonb322 ,

    based on the example LwIP_HTTP_Server_Netconn_RTOS  your MPU configuration should be as follows as you are using an STM32F767 check RM0410

    STea_0-1720191391274.png

    static void MPU_Config(void)
    {
     MPU_Region_InitTypeDef MPU_InitStruct;
    
     /* Disable the MPU */
     HAL_MPU_Disable();
    
     /* Configure the MPU as Strongly ordered for not defined regions */
     MPU_InitStruct.Enable = MPU_REGION_ENABLE;
     MPU_InitStruct.BaseAddress = 0x00;
     MPU_InitStruct.Size = MPU_REGION_SIZE_4GB;
     MPU_InitStruct.AccessPermission = MPU_REGION_NO_ACCESS;
     MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
     MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
     MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
     MPU_InitStruct.Number = MPU_REGION_NUMBER0;
     MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
     MPU_InitStruct.SubRegionDisable = 0x87;
     MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
    
     HAL_MPU_ConfigRegion(&MPU_InitStruct);
    
     /* Configure the MPU as Normal Non Cacheable for Ethernet Buffers in the SRAM2 */
     MPU_InitStruct.Enable = MPU_REGION_ENABLE;
     MPU_InitStruct.BaseAddress = 0x20078000;
     MPU_InitStruct.Size = MPU_REGION_SIZE_16KB;
     MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
     MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
     MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
     MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
     MPU_InitStruct.Number = MPU_REGION_NUMBER1;
     MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL1;
     MPU_InitStruct.SubRegionDisable = 0x00;
     MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
    
     HAL_MPU_ConfigRegion(&MPU_InitStruct);
    
     /* Configure the MPU as Device for Ethernet Descriptors in the SRAM2 */
     MPU_InitStruct.Enable = MPU_REGION_ENABLE;
     MPU_InitStruct.BaseAddress = 0x2007C000;
     MPU_InitStruct.Size = MPU_REGION_SIZE_1KB;
     MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
     MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;
     MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
     MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
     MPU_InitStruct.Number = MPU_REGION_NUMBER2;
     MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
     MPU_InitStruct.SubRegionDisable = 0x00;
     MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
    
     HAL_MPU_ConfigRegion(&MPU_InitStruct);
     
     /* Enable the MPU */
     HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
    }

    The MPU configuration you are using is valid for stm32f75xx and stm32f74xx check RM0385

    STea_1-1720191644932.png


    Regards

     

    cleonb322Author
    Visitor II
    October 22, 2024

    Thank you for the help. it no longer crashes but I still receive "pbuf_free: p->ref > 0" occasionally on the debug console. Do you know of other potential causes of the issue?

    ST Employee
    October 22, 2024

    Hello @cleonb322 ,

    This most probably related to LWIP memory management and since it is not systematic maybe it can be a problem of alignment or luck of allocated memory.

    As far as I recall there are two routes to manage memory in LWIP either dynamically or statically and this could be adjusted by the user.
    have a look at sections 3.2 and 4 of UM1713 .

    Regards

     

    cleonb322Author
    Visitor II
    October 22, 2024

    I forget to update this:  #define LWIP_RAM_HEAP_POINTER (0x20078000) in iwapopts.h