It blocked in function vPortStartFirstTask of file portASM.S:
/*
void vPortStartFirstTask( void ); /
.align 4
.global vPortStartFirstTask
.type vPortStartFirstTask, %function
vPortStartFirstTask:
/ This function is called from System Mode to start the FreeRTOS-Kernel.
As described in the portRESTORE_CONTEXT macro, portRESTORE_CONTEXT cannot
be called from the System mode. We, therefore, switch to the Supervisor
mode before calling portRESTORE_CONTEXT. */
CPS #SVC_MODE
portRESTORE_CONTEXT
Hi @Allenhe123
Welcome to the FreeRTOS Community Forums!
Can you debug through the code in vPortStartFirstTask and see in which part of the assembly code, its getting stuck ?
Also can you provide the entire code, or the number of tasks you are creating, which helps us determine if your _STACK_SIZE( 2KB ) and _HEAP_SIZE( 2 KB ) are sufficient.
In the project
two ports ARM_CR5 and ARM_CRx_MPU are added.
You can try removing ARM_CR5 because in this port, MPU is disabled.
configENABLE_FPU is not set in FreeRTOSConfig.h, but you are calling portTASK_USES_FLOATING_POINT() .
This can lead to hanging at CPS #19 (SVC mode) because the system tries to access an uninitialized FPU.
Can you try out these two steps and update the findings?
If i try to add a task in StartupTask function, the code will be stucked in below function:
void * pvPortMalloc( size_t xWantedSize )
void vTaskFunction(void* p) {
printf("hhahahhhah\n");
}
/* Fill in a TaskParameters_t structure to define the task - this is the
structure passed to the xTaskCreateRestricted() function. */
static const TaskParameters_t xTaskDefinition =
{
vTaskFunction, /* pvTaskCode */
"A task", /* pcName */
128, /* usStackDepth - defined in words, not bytes. */
NULL, /* pvParameters */
1, /* uxPriority - priority 1, start in User mode. */
xTaskStack, /* puxStackBuffer - the array to use as the task stack. */
/* xRegions - In this case only one of the three user definable regions is
actually used. The parameters are used to set the region to read only. */
{
/* Base address Length Parameters */
{ cReadOnlyArray, 512, tskMPU_REGION_READ_ONLY },
{ 0, 0, 0 },
{ 0, 0, 0 },
}
};
FUNC(void, OS_CODE)
StartupTask(void)
{
TaskHandle_t xHandle = NULL;
int* p = 0xB7000000;
*p = 0x6688;
taskENTER_CRITICAL();
**xTaskCreateRestricted( &xTaskDefinition, NULL );**
xCreatedEventGroup[EVENT_GROUP_WDG_ID] = xEventGroupCreate();
*p = 0x6699;
ipc_trans_layer_start(0, 0);
*p = 0x7788;
portTASK_USES_FLOATING_POINT();
*p = 0x8888;
taskEXIT_CRITICAL();
*p = 0x9999;
vTaskStartScheduler();
*p = 0x1111;
}
the malloc failed and call vApplicationMallocFailedHook(); which is a function user defined.
So the problem now is the malloc failed, Can any one help to take a look and give some advice? thanks a lot !
Could you please try setting configENABLE_MPU to 0U and verify whether the rest of the code logic functions as expected? If it does, that would confirm the issue is related to the MPU configuration.
Since you’re using MPU, ensure that the heap is in a region accessible to tasks. Otherwise, an MPU fault could block memory allocation.
You are passing xTaskStack as the stack buffer, how is it defined? It needs to be placed in a MPU-accessible region.
thank you, adopt bhoomrs’s advice, I changed configENABLE_MPU = 0 and do some tests, results :
built the project using ARM_CR5, it’s running OK.
built the project using ARM_CRx_MPU, below errors:
undefined reference to FreeRTOS_SWI_Handler' undefined reference to FreeRTOS_Tick_Handler’
The above two functions can be found in ARM_CR5/portASM.S, but disappear in ARM_CRx_MPU/portASM.S.
My current solution is copy the two functions from ARM_CR5/portASM.S to ARM_CRx_MPU/portASM.S. Is it right? Or there are other functions to replace the above two functions when using MPU ?
FreeRTOS_SWI_Handler(Software Interrupt Handler) maps to FreeRTOS_SVC_Handler(Supervisor Call Handler) in ARM_CRx_MPU.
You can use it directly, but keep a lookout for the MPU privilege escalations.
FreeRTOS_Tick_Handler is not implemented in ARM_CRx_MPU and is expected to be provided in the application code. You can use the one provided in ARM_CR5/port.c or here
built the project using ARM_CRx_MPU:
2.1. using FreeRTOS_SVC_Handler to replace FreeRTOS_SWI_Handler;
2.2. using void FreeRTOS_Tick_Handler( void ) as below:
/*
* void vPortStartFirstTask( void );
*/
.align 4
.global vPortStartFirstTask
.type vPortStartFirstTask, %function
vPortStartFirstTask:
/* This function is called from System Mode to start the FreeRTOS-Kernel.
* As described in the portRESTORE_CONTEXT macro, portRESTORE_CONTEXT cannot
* be called from the System mode. We, therefore, switch to the Supervisor
* mode before calling portRESTORE_CONTEXT. */
**CPS #SVC_MODE**
portRESTORE_CONTEXT
The origin code of FreeRTOS_Tick_Handler in our CR5 as below, try this one, still the same error.
void FreeRTOS_Tick_Handler( void )
{
/*
* Set interrupt mask before altering scheduler structures. The tick
* handler runs at the lowest priority, so interrupts cannot already be masked,
* so there is no need to save and restore the current mask value. It is
* necessary to turn off interrupts in the CPU itself while the ICCPMR is being
* updated.
*/
portCPU_IRQ_DISABLE();
portICCPMR_PRIORITY_MASK_REGISTER = ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT );
__asm volatile ( "dsb \n"
"isb \n" ::: "memory" );
portCPU_IRQ_ENABLE();
/* Increment the RTOS tick. */
if( xTaskIncrementTick() != pdFALSE )
{
ulPortYieldRequired = pdTRUE;
}
/* Ensure all interrupt priorities are active again. */
portCLEAR_INTERRUPT_MASK();
configCLEAR_TICK_INTERRUPT();
}
Is this the complete code? Your boot code seem to configure bunch of MPU regions which likely will interfere with the MPU regions configured by FreeRTOS. Why do you have these MPU configurations in the boot code?
Which hardware are you using? Do you have a working bare metal project for your hardware?
In fact this is almost the complete code except few init codes which i think are not related to this issue.
Maybe the configuration code of some MPU regions are just copied from bare metal project which is used to verify the hardware function.
The hardware is ARMv7 R5F, only 1 core.
So i think i can remove the MPU regions in boot.S and take a try?
The Cortex-R5F processor is a Cortex-R5 processor that includes the optional Floating Point Unit (FPU) extension.
Revision: r1p2 .
I have done a try.
If i removed the MPU regions in boot.S, the project will can not run.
With the MPU regions in boot.S, the project will stuck in CPS #SVC_MODE just the same error as above.
PS: I have disabled MPU using: #define configENABLE_MPU 0U
So it seems not related to MPU now?
Since you are not telling the part number, I cannot lookup the datasheet myself. I’ll try to answer based on the information you have provided. Reading this, I assume your hardware has 16 MPU regions. If so, you can update your boot code to use MPU regions numbers 8-15 and set configTOTAL_MPU_REGIONS to 8 so that FreeRTOS will use MPU region numbers 0-7.
If you do not want to use MPU, you need to use ARM_CR5 port. This flag is not used in ARM_CRx_MPU port and therefore, does not disable MPU.
It may be a good idea to first get the non-MPU port working.
#include "FreeRTOSConfig.h"
#ifndef configTOTAL_MPU_REGIONS
#error "Set configTOTAL_MPU_REGIONS to the humber of MPU regions in FreeRTOSConfig.h"
#elif( configTOTAL_MPU_REGIONS == 12 )
#define portMPU_TOTAL_REGIONS ( 12UL )
#elif( configTOTAL_MPU_REGIONS == 16 )
#define portMPU_TOTAL_REGIONS ( 16UL )
#else
#error "Set configTOTAL_MPU_REGIONS to the number of MPU regions in FreeRTOSConfig.h"
#endif /* configTOTAL_MPU_REGIONS */
I have figured out that non-MPU port working fine.
I not very clear what;s the part number mean, i have the Technical Reference Manual pdf, if you need i can provide.