Hardfault observed in BufferAllocation under FREERTOS IP Stack

ingamow wrote on Friday, May 24, 2019:

Hi,
I’ve currently updated the FreeRTOS version from v8.2.1 to v10.2.0 on my Cortex-M0 based project.
Along with that, the existent LWIP stack was replaced by FreeRTOS IP Stack.
Everything worked fine. But Stability tests revealed a critical bug. It was a Hardfault. (A configAssert call probably)
I went on to debug that, the link register pointed to the below section in BufferAllocation2.c (We are using this and heap4.c)

FreeRTOS-Plus-TCP/portable/BufferManagement/BufferAllocation2.c:229
}
**
** / If there is a semaphore available, there is a network buffer available. /
** if( xSemaphoreTake( xNetworkBufferSemaphore, xBlockTimeTicks ) == pdPASS )
917c2: 4b1d ldr r3, [pc, #116] ; (91838 <pxGetNetworkBufferWithDe
scriptor+0x8c>)
917c4: 6818 ldr r0, [r3, #0]
917c6: f7fa f924 bl 8ba12
917ca: 2801 cmp r0, #1
917cc: d130 bne.n 91830 <pxGetNetworkBufferWithDescriptor+0x84>
** THIS WAS THE LINE LINK REGISTER POINTED TO.

As I am a newbie to FreeRTOS, I’ve literally no idea how this happens, Please Help.

heinbali01 wrote on Friday, May 24, 2019:

Hi,

It was a Hardfault. (A configAssert call probably)

Was it is a hard-fault or a configAssert()? The latter is easier to solve.
The former will end-up in HardFault_Handler(). Both end in a for-ever-loop.

Do you haveconfigAssert() properly defined?

Often in NetworkInterface.c, you will see calls to uxGetNumberOfFreeNetworkBuffers() and uxGetMinimumFreeNetworkBuffers(). It produces logging when the levels get low. Do you have that logging enabled?
And while you are testing, it is also good to keep an aye on the available heap memory. Both heap_4 and heap_5 are very good. I like heap_5 because you can determine dynamically how much RAM is actually available.

Can you confirm that xNetworkBufferSemaphore is created and valid?
You are not allocating a Network Buffer or using the +TCP API’s before FreeRTOS_IPInit() has successfully finished?

In more general terms: problems with Network Buffers are usually caused by:

  • Forgetting to release buffers
  • Releasing a buffer more than one time
  • Accessing more memory in pucEthernetBuffer than allocated

The free network buffers are stored in a List_t, which is guarded by a counting semaphore. Updates to List_t need critical sections.

ingamow wrote on Friday, May 24, 2019:

Hi,

You are not allocating a Network Buffer or using the +TCP API’s before FreeRTOS_IPInit() has successfully finished?

It seemed, the buffer allocation was happening even before a call to FreeRTOS_IPInit().
Fixing this, sort of solved the issue. Need to do more stability tests to confirm it.
Anyway thanks so much for your feedback Mr. Hein Tibosch

heinbali01 wrote on Saturday, May 25, 2019:

Glad you’ve found where the problem is, and thanks for taking the effort to report back.

It looks like you don’t have configASSERT() enabled. xQueueSemaphoreTake() is called while pxQueue is NULL. But also with configASSERT() enabled, your program would get stuck.

BufferAllocation_1.c does check if xNetworkBufferSemaphore has been created, and I will propose to make the same check in BufferAllocation_2.c. See my pull request here