SVC call causing hard fault

Hi all, I have seen similar faults described elsewhere and have tried all the recommendations I found so far so but no luck yet so apologies if this has been covered to death. I am relatively new to using freeRTOS so apologies if I haven’t included all the information The problem: When trying to start the RTOS first task, the processor drops in to ~~~ static void prvPortStartFirstTask( void ) { __asm volatile( ” ldr r0, =0xE000ED08 n” /* Use the NVIC offset register to locate the stack. / ” ldr r0, [r0] n” ” ldr r0, [r0] n” ” msr msp, r0 n” / Set the msp back to the start of the stack. / ” cpsie i n” / Globally enable interrupts. / ” cpsie f n” ” dsb n” ” isb n” ” svc 0 n” / System call to start first task. */ ” nop n” ); } ~~~ and by stepping through the assembly code, I get to svc 0 and then the micro immediately falls in to a hard fault handler. I initially had 3 simple tasks; 1 sets up an LCD and displays a splash screen and 2 blank tasks. This worked, and I stored it on my work respository. When I began to build up one of the blank tasks to send and recieve basic serial commands I ran in to hard fault issues. After some fettling later I can’t even even get past the start first task function. I reverted to my known working version from the repository and still no joy. the #define vPortSVCHandler SVCHandler and xPortPendSVCHandler PendSVHandler are present in the freeRTOSconfig.h (it was autogenerated by CubeMX) I am using: STM32f427 Eclipse with GCC CubeMX FreeRTOS 9 heap4 8k heap size 512byte task size 3 tasks If anyone has any advice or recommendations I would truly apreciate it, I am going round in circles. It is possibly worth noting, I modified the fault handler to help track down the issue using the code bellow but I get to linebx r2 and the compiler jumps to a random line of movs r0, r0which goes on and on. ~~~ void HardFaultHandler(void) { /* USER CODE BEGIN HardFaultIRQn 0 */
__asm__("BKPT");
__asm volatile
(
    " tst lr, #4                                                n"
    " ite eq                                                    n"
    " mrseq r0, msp                                             n"
    " mrsne r0, psp                                             n"
    " ldr r1, [r0, #24]                                         n"
    " ldr r2, handler2_address_const                            n"
    " bx r2                                                     n"
    " handler2_address_const: .word prvGetRegistersFromStack    n"
);
/* USER CODE END HardFaultIRQn 0 */ while (1) { } /* USER CODE BEGIN HardFaultIRQn 1 */ /* USER CODE END HardFault_IRQn 1 */ } void prvGetRegistersFromStack( uint32t *pulFaultStackAddress ) { /* These are volatile to try and prevent the compiler/linker optimising them away as the variables never actually get used. If the debugger won’t show the values of the variables, make them global my moving their declaration outside of this function. */ volatile uint32t r0; volatile uint32t r1; volatile uint32t r2; volatile uint32t r3; volatile uint32t r12; volatile uint32t lr; /* Link register. */ volatile uint32t pc; /* Program counter. / volatile uint32_t psr;/ Program status register. */
r0 = pulFaultStackAddress[ 0 ];
r1 = pulFaultStackAddress[ 1 ];
r2 = pulFaultStackAddress[ 2 ];
r3 = pulFaultStackAddress[ 3 ];

r12 = pulFaultStackAddress[ 4 ];
lr = pulFaultStackAddress[ 5 ];
pc = pulFaultStackAddress[ 6 ];
psr = pulFaultStackAddress[ 7 ];

/* When the following line is hit, the variables contain the register values. */
__asm__("BKPT");
for( ;; );
} ~~~

SVC call causing hard fault

Normally when people report a fault on the SVC 0 line it is not actually that line that is causing the fault. What is actually happening is the SVC 0 line jumps to the SVC handler which starts the first task, and the first task is entered, and it is actually the task that causes the fault…..but the debugger does not follow that sequence and it appears as if it is the SVC 0 line that causes the fault. Could that be happening in your case. Try placing a break point in the SVC handler to see if it ever gets hit. The SVC handler is called vPortSVCHandler() as is implemented in FreeRTOS/source/portable/[compiler]/ARM_CM4F/port.c

SVC call causing hard fault

Hi Richard, thanks for the quick reply, I knew I forgot to add something, I did put a breakpoint in the SVC handler and no dice, I didn’t reach the breakpoint, straight to the fault handler.

SVC call causing hard fault

Is it possible that an interrupt is executing between the cpsie i instruction and the SVC 0 instruction?

SVC call causing hard fault

It’s possible but I don’t think so. the peripherals are configured before the kernel is started with the standard cubeMX generated calls but the interrupts I didn’t think were started until later in the user code. There’s no user code between the set up routines and the call to the RTOS kernel. ~~~ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); /* USER CODE BEGIN Init */ /* USER CODE END Init */ /* Configure the system clock */ SystemClock_Config(); /* USER CODE BEGIN SysInit */ /* USER CODE END SysInit */ /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_DMA_Init(); MX_ADC1_Init(); MX_CRC_Init(); MX_DAC_Init(); MX_I2C1_Init(); MX_I2C2_Init(); MX_SPI1_Init(); MX_SPI4_Init(); MX_UART4_Init(); MX_USART1_UART_Init(); MX_TIM7_Init(); /* USER CODE BEGIN 2 */ // while(1) // { // HALGPIOWritePin(GPIOE, GPIOPIN9, GPIOPINSET); // HALGPIOWritePin(LEDBatteryoutGPIOPort, LEDBatteryoutPin, GPIOPINRESET); // HALDelay(1000); // HALGPIOWritePin(GPIOE, GPIOPIN9, GPIOPINRESET); // HALGPIOWritePin(LEDBatteryoutGPIOPort, LEDBatteryoutPin, GPIOPINSET); // HALDelay(1000); // } /* USER CODE END 2 */ /* Call init function for freertos objects (in freertos.c) */ MX_FREERTOS_Init(); /* Start scheduler */ osKernelStart(); ~~~

SVC call causing hard fault

Quick update: Following on from Richard’s comment about interrupts, i started digging and found some strange things happening with the systick timer (tim6). it appears to be set twice, once from halinit() and once from systemClockconfig(). it also appears to have an interrupt flag set just as the SVC 0 call is made. Currently, I am not seeing any change to the timer 6 configuration when I change the clock times in cubeMX so by increasing the clock frequency in cubeMX, this may be causing the issue seen. I will investigate further.