Hi,
I am having issues with threadX tx_byte_allocate throwing a hard fault exception.
This only happens after some time of byte allocate and release. There are still plenty of available bytes according to the pool. But somehow in _tx_byte_pool_search it encounters some problem.
I am not posting the entire source code here as that will be huge.
For reference only, I am using STM32H753. I created a byte pool using DTCRAM (128K).
Linker snippet:
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
.ram_dtcmram :
{
*(.ram_dtcmram)
} >RAM
Code Snippet
#define RAM_DTCMRAM \
attribute((section(".ram_dtcmram")))
#define GENERIC_MEM_ALLOCATION (0x20000-0x1000)
static u8 m_genericMemBytePoolBuffer[GENERIC_MEM_ALLOCATION] RAM_DTCMRAM;
static TX_BYTE_POOL m_genericMemBytePool RAM_D3;
bool Hal_MemPool_Init(void)
{
if (tx_byte_pool_create(&m_genericMemBytePool, "Generic memory pool", m_genericMemBytePoolBuffer , GENERIC_MEM_ALLOCATION) != TX_SUCCESS){
return FALSE;
}
return TRUE;
}
This is the screenshot of the pool when the hard fault happens. byte pool available is still more than 50k
Below are the local variables during the fault. As you can see current pointer goes to 0x2492bc7e. That memory is not available for H753 and obviously will throw a hard fault error trying to access this memory.
Specifically on line below inside the do while(examine_blocks != ((UINT) 0)) loop
work_ptr = TX_UCHAR_POINTER_ADD(current_ptr, (sizeof(UCHAR *)));
free_ptr = TX_UCHAR_TO_ALIGN_TYPE_POINTER_CONVERT(work_ptr);
if ((*free_ptr) == TX_BYTE_BLOCK_FREE) //<-----------HARD FAULT
Now my question is why? Clearly, I have enough available bytes in the pool. You can also see below that the memory required is only 256 bytes. Even if the memory gets fragmented, I am pretty confident there is a block with 256 bytes free on it. Besides, ThreadX is supposed to merge those splits or fragments. Which is also stated in the pool above (tx_byte_pool_performance_merge_count)
Version of ThreadX is
Not that it matters I think, I made the pool m_genericMemBytePool the same RAM as the m_genericMemBytePoolBuffer to dtcmram. Same outcome.
Thanks,
Carlo