Please check if xTickCount is incrementing. You can check that by ensuring that xTaskIncrementTick is getting called repeatedly.
Now the issue is:
pvPortMalloc (heap_4.c) will always failed.
I have configured heap size to:
#define configTOTAL_HEAP_SIZE ( 120 * 1024 )
But it still failed.
Could you please give me some advice?
If your pvPortMalloc fails when you believe that there is enough free memory in the heap. It’s likely that the heap management data structures are corrupted.
I would recheck if any of the allocated memory is correctly handled without any overwrites outside of its bounds.
Try stepping through the pvPortMalloc to see where its getting failed.
In the function there is a Conditional judgment statements
:
if( ( xWantedSize > 0 ) && ( xWantedSize <= xFreeBytesRemaining ) )
The result is xWantedSize > xFreeBytesRemaining. And the code run to below code block:
#if ( configUSE_MALLOC_FAILED_HOOK == 1 )
{
if( pvReturn == NULL )
{
**vApplicationMallocFailedHook();**
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
vApplicationMallocFailedHook() will be called.
PS: my repo is here:code
I only create a simple task just for test.
If you want to allocate more memory than you provided, your heap is either too small (you should increase the heap size, assuming you don’t have programmed a memory leak exhausting the heap unexpectedly) or there is a bug in your software causing a wrong (way too large) size given to pvPortMalloc (or something else very strange).
What are the numbers of remaining free and wanted size ? Does it make sense resp. does it match your expectations ? You should or need to have a coarse overview of the allocation / memory consumption profile of your application.
FreeRTOS_test/Init.c at main · Allenhe123/FreeRTOS_test · GitHub line 306, is the only test task that will be created.
If i search pvPortMalloc in the FreeRTOS code, it is called in a lot of places.
The xFreeBytesRemaining is 0x0001dff0 (equal to configTOTAL_HEAP_SIZE) just after pvHeapInit called.
In the error case, xFreeBytesRemaining = 0x00000898, xWantedSize = 0x000021a8.
I am not sure is it make sense. From FreeRTOS perspective, is it need to allocate 0x000021a8 size memory(used to FreeRTOS 11.1 kernel)?
While you are executing these lines, can you examine the call stack to see which call to pvPortMalloc is setting xWantedSize to 0x000021a8 (8616bytes)? Thats an unsual allocation.
Sure, I will check that tomorrow, thank you for your advice.
It’s 8616 bytes (ca. 8.5k) , right ? Quite a lot with respect to 120k total heap size (in repo it’s just 40k ?)
Will be interesting to see where this tried to be allocated.
#if ( ( portUSING_MPU_WRAPPERS == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) )
static TCB_t * prvCreateRestrictedTask( const TaskParameters_t * const pxTaskDefinition,
TaskHandle_t * const pxCreatedTask )
{
TCB_t * pxNewTCB;
configASSERT( pxTaskDefinition->puxStackBuffer );
if( pxTaskDefinition->puxStackBuffer != NULL )
{
/* MISRA Ref 11.5.1 [Malloc memory assignment] */
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-115 */
/* coverity[misra_c_2012_rule_11_5_violation] */
pxNewTCB = ( TCB_t * ) pvPortMalloc( sizeof( TCB_t ) );
...
}
I have locate the call stack, it is pvPortMalloc called in above code block.
The input param for pvPortMalloc is 0x0000219c, after alignment becomes to 0x000021a8.
I also checked the size of sizeof( TCB_t ), it is 0x0000219c.
It seems nothing wrong.
The latest configure files have not been pushed.
I also checked the size of sizeof( TCB_t ) , it is 0x0000219c.
Check the TCB_t to see what configuration is contributing to that increased size. Without using configNUM_THREAD_LOCAL_STORAGE_POINTERS, and configNUMBER_OF_CORES and configTASK_NOTIFICATION_ARRAY_ENTRIES set to 1, FreeRTOS V11.1.0 sizeof( TCB_t ) evaluates to around 988 bytes on my setup with configENABLE_MPU enabled.
portUSING_MPU_WRAPPERS was configured to 1,
so tskTCB has a
xMPU_SETTINGS xMPUSettings;
typedef struct MPU_SETTINGS
{
xMPU_REGION_REGISTERS xRegion[ portTOTAL_NUM_REGIONS_IN_TCB ];
uint32_t ulTaskFlags;
xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo;
uint32_t ulContext[ CONTEXT_SIZE ]; /**< Buffer used to store task context. */
#if( configENABLE_ACCESS_CONTROL_LIST == 1 )
uint32_t ulAccessControlList[ ( configPROTECTED_KERNEL_OBJECT_POOL_SIZE
/ portACL_ENTRY_SIZE_BITS )
+ 1UL ];
#endif
} xMPU_SETTINGS;
typedef struct SYSTEM_CALL_STACK_INFO
{
uint32_t * pulTaskStackPointer; /**< Stack Pointer of the task when it made a FreeRTOS System Call. */
uint32_t * pulLinkRegisterAtSystemCallEntry; /**< Link Register of the task when it made a FreeRTOS System Call. */
uint32_t * pulSystemCallStackPointer; /**< Stack Pointer to use for executing a FreeRTOS System Call. */
uint32_t * pulSystemCallExitAddress; /**< System call exit address. */
uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; /**< Buffer to be used as stack when performing a FreeRTOS System Call. */
} xSYSTEM_CALL_STACK_INFO;
configSYSTEM_CALL_STACK_SIZE = 2048, so the size of the tskTCB is very big.
Could you please give some advice?
Try reducing the system call stack size, maybe:
#define configSYSTEM_CALL_STACK_SIZE ( 128 )
Also, since you are already defining StaticTask_t pxTaskBuffer; in your code, you can use xTaskCreateRestrictedStatic instead of xTaskCreateRestricted so that pxTaskBuffer can be used to hold the task’s data structure instead of dynamically allocating.
Thank you .
Adopt your advice, the pvPortMalloc works fine.
But it ran into another error:
.section .freertos_vectors, "a"
__vector_table:
LDR pc,=ResetHandler
LDR pc,=FreeRTOS_Undefined
LDR pc,=FreeRTOS_SVC_Handler
LDR pc,=FreeRTOS_PrefetchAbortHandler
LDR pc,=FreeRTOS_DataAbortHandler
NOP /* Placeholder for address exception vector*/
LDR pc,=FreeRTOS_IRQ_Handler
LDR pc,=FreeRTOS_FIQHandler
ResetHandler was called always.
And Could you tell me how to define function vApplicationIRQHandler which is used to handle IRQ and is called in portASM.S on FreeRTOS v11.1.
Here is an example - FreeRTOS/FreeRTOS/Demo/CORTEX_MPU_R4F_TI_RM46_HERCULES_GCC/source/main.c at main · FreeRTOS/FreeRTOS · GitHub. Note that what goes in the definition will depend on your hardware.
An interrupt request (IRQ) is a signal sent from a connected hardware device in order to run some routine on the processor. Each IRQ channel has a unique data line, and the channel represents some physical connection between the processor and hardware. Some IRQs may be sent by the processor itself.
IRQs allows boards to define their own interrupts, and vApplicationIRQHandler() maps the IRQ channel to application-specific code.
In Gaurav’s example, there are 127 IRQ channels on this Texas Instruments board, but this demo is only interested in two of them: the timer controlling the FreeRTOS task tick and the demo’s software interrupt, used to unblock a demo task.
I have fixed the IRQ issue.
It can run into vApplicationIRQHandler function now.
But i ran into another problem:
It always ran into funciton ResetHandler:
.section .freertos_vectors, "a"
__vector_table:
LDR pc,=ResetHandler
LDR pc,=FreeRTOS_Undefined
LDR pc,=FreeRTOS_SVC_Handler
LDR pc,=FreeRTOS_PrefetchAbortHandler
LDR pc,=FreeRTOS_DataAbortHandler
NOP /* Placeholder for address exception vector*/
LDR pc,=FreeRTOS_IRQ_Handler
LDR pc,=FreeRTOS_FIQHandler
When it enters ResetHandler, i dump the R14 value is 0x05107734.
The disassemble code locates on out.s
sections:
.privileged_functions :
{
. = ALIGN(4);
KEEP(*(.intvecs))
KEEP (*(.freertos_vectors))
KEEP (*(.vectors))
. = ALIGN(4);
KEEP(*(privileged_functions))
. = ALIGN(4);
/* Fill rest of the region with a known value */
FILL(0xADDEADDE);
/* Ensure that non-privileged code is placed after the region reserved for
* privileged kernel code. This is done for MPU Region Alignment */
/* Note that dot (.) actually refers to the byte offset from the start of
* the current section (.privileged_functions in this case). As a result,
* setting dot (.) to a value sets the size of the section. */
. = __privileged_functions_region_size__;
} >SRAM
.freertos_system_calls :
{
. = ALIGN(4);
/* Place the FreeRTOS System Calls first in the unprivileged region. */
__syscalls_flash_start__ = .;
*(freertos_system_calls)
__syscalls_flash_end__ = .;
. = ALIGN(4);
} >SRAM
.text :
{
. = ALIGN(4);
*(.boot)
. = ALIGN(4);
*(.text.freertos_system_calls)
. = ALIGN(4);
*(.text)
*(.text.*)
*(.gnu.linkonce.t.*)
*(.plt)
*(.gnu_warning)
*(.gcc_execpt_table)
*(.glue_7)
*(.glue_7t)
*(.vfp11_veneer)
*(.ARM.extab)
*(.gnu.linkonce.armextab.*)
} > SRAM
My sections as above, i am not sure is it right.
Could you help to take a look and give some advice, thanks a lot.
Seems like your device is resetting. You need to find the cause of reset.
The user defined configSETUP_TICK_INTERRUPT() function has been called periodically, but when taskYIELD_WITHIN_API() was called it ran into ResetHandler(). So the user defined configCLEAR_TICK_INTERRUPT() function was not called. As taskYIELD_WITHIN_API() points to vPortYield() in freertos_system_calls section, i doubt it related to sections definition
in ld script.