You didn’t say what problem you are facing, so it’s hard to suggest a solution. However, often reports of the svc 0 failing turn out to be that svc successfully starts a task, and the task crashes, but the debugger is still pointing at the svc instruction making it appear as if it was that instruction that failed.
“on all forums” this is why we try and keep this forum the focus point for FreeRTOS support, as this is where the developers, consultants, trainers, tenured users, etc can pass on their FreeRTOS expertise.
Thanks for the quick reply. Appreciate your efforts here.
Yes, that is the common answer. But, shouldn’t be in my case else I would be damned.
My tasks are pretty lame, infact the default one that is created by CubeMX. infact loop with waits on 1 Systick
Giving more details to help me resolve faster.
static void prvPortStartFirstTask( void )
{
/* Start the first task. This also clears the bit that indicates the FPU is
in use in case the FPU was used before the scheduler was started - which
would otherwise result in the unnecessary leaving of space in the SVC stack
for lazy saving of FPU registers. */
__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. */
" mov r0, #0 \n" /* Clear the bit that indicates the FPU is in use, see comment above. */
" msr control, r0 \n"
" cpsie i \n" /* Globally enable interrupts. */
" cpsie f \n"
" dsb \n"
" isb \n"
" svc 0 \n" /* System call to start first task. */
" nop \n"
);
}
The application crashes after executing svc 0.
The SVC_handler in my project points to vPortSVCHandler() in my case and is not redefined by the STM32 HAL.
The prvPortStartFirstTask() points to address 0x1FF09800 to locate the stack
General Registers
General Purpose and FPU Register Group
r0
0x0
r1
0xf00000
r2
0xe000ef34
r3
0xc0000000
r4
0x2404ffc8
r5
0x8004ce0
r6
0x0
r7
0x2404ff60
r8
0x0
r9
0x0
r10
0x0
r11
0x0
r12
0x0
sp
0x24003f40
lr
0x80044fd
pc
0x80043da
xpsr
0x61000000
d0
0x0
d1
0x0
d2
0x0
d3
0x0
d4
0x0
d5
0x0
d6
0x0
d7
0xffffffff00000000
d8
0x0
d9
0x0
d10
0x0
d11
0x0
d12
0x0
d13
0x0
d14
0x0
d15
0xffffffff00000000
fpscr
0x0
msp
0x24003f40
psp
0x0
primask
0x0
basepri
0x50
faultmask
0x0
control
0x0
s0
0x0
s1
0x0
s2
0x0
s3
0x0
s4
0x0
s5
0x0
s6
0x0
s7
0x0
s8
0x0
s9
0x0
s10
0x0
s11
0x0
s12
0x0
s13
0x0
s14
0x0
s15
0xffffffff
s16
0x0
s17
0x0
s18
0x0
s19
0x0
s20
0x0
s21
0x0
s22
0x0
s23
0x0
s24
0x0
s25
0x0
s26
0x0
s27
0x0
s28
0x0
s29
0x0
s30
0x0
s31
0xffffffff
Does this issue ring a bell and with numerous posts around the same issue looks like it a very common issue faced?
Btw, using STM Cube IDE 1.3.1 with STMCubeMx 6.2.1
well. I see the IVT table is populated.
But noticed one more behavior, on switching the Timebase Source in SYS to one of the timer (Timer 3 in my case), I see that the initialization of the timer itself fails?
Do we have issues with the generated code from CubeMX in some versions?
HAL_StatusTypeDef HAL_TIM_Base_Start_IT(TIM_HandleTypeDef *htim)
{
uint32_t tmpsmcr;
/* Check the parameters */
assert_param(IS_TIM_INSTANCE(htim->Instance));
/* Check the TIM state */
if (htim->State != HAL_TIM_STATE_READY)
{
return HAL_ERROR;
}
/* Set the TIM state */
htim->State = HAL_TIM_STATE_BUSY;
/* Enable the TIM Update interrupt */
__HAL_TIM_ENABLE_IT(htim, TIM_IT_UPDATE);
/* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */
if (IS_TIM_SLAVE_INSTANCE(htim->Instance))
{
tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS;
if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr))
{
__HAL_TIM_ENABLE(htim); ---------> fails at this line
}
}
else
{
__HAL_TIM_ENABLE(htim);
}
/* Return function status */
return HAL_OK;
}
The application breaks at this line __HAL_TIM_ENABLE(htim);
I don’t know of any issues in cubemx that prevent freertos starting. Wondering if somehow your SCB->VTOR is not set correctly. Normally the startup code provided by ST sets it properly for you. It should point to your vector table.
@jefftenney@RAc any more suggestion that I can try?
Read the SVC interrupt priority it is set to 0 and basepri after registering the first task sets to a value 0x50.
The basepri value is populated by FreeRTOSConfig
/* The highest interrupt priority that can be used by any interrupt service
routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL
INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER
PRIORITY THAN THIS! (higher priorities are lower numeric values. */
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5
/* Interrupt priorities used by the kernel port layer itself. These are generic
to all Cortex-M ports, and do not rely on any particular library functions. */
#define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
Does this make sense as basepri will block SVC interrupt handling with the value it hold.
No need to worry about that when SVC uses priority 0. If BASEPRI is set to 0x50, then interrupts from 0x50 to 0xFF (or, as unshifted priorities, 5 through 15) are masked. Priority 0 (the highest priority) remains unmasked (and, in fact, cannot be masked by BASEPRI anyway).
The next thing for you to check is SCB->VTOR. Can you use the debugger to see if it is actually pointing to your vector table? You can determine the true location of your vector table in your linker file or in a map file, for example. Or, you can visually inspect the 32-bit words that start wherever VTOR points to see if they seem like reasonable vectors. You can put a breakpoint at the beginning of main to do this inspection.
If SCB->VTOR is not set correctly, the CPU will not lookup the correct interrupt vectors.
To me it looks as if your logic never makes it as far as vTaskStartScheduler(), which would explain why your svc handler is not invoked and would in turn make interrupt configuration not a prime suspect.
One of my top gripes about the ST HAL is that it uses a timer interrupt for its own bookkeeping, meaning interrupts must be enabled for the HAL to work before FreeRTOS is started. Sure recipe for desaster. What priority is the HAL timer isr set to? Can you reconfigure it to be > MAX_SYSCALL and make sure that interrupts are enabled by the HAL only on a level > MAX_SYSCALL instead globally?
it does makes it prvPortStartFirstTask(); called in xPortStartScheduler() and executes till the asm call “svc 0” and then never invokes the SVCHandler() and hence the configured tasks don’t execute which makes sense.
I think the only issue to check why SVCHandler is not called. I strongly suspect the autogenerated FreeRTOSConfig.h file. Skinning the cat now with comments from Jeff
Seems clear the problem is SCB->VTOR not being set correctly. Per the screenshots, SCB->VTOR is set to 0x1FF09800. The reference manual indicates that address is in “system” memory. So that isn’t right for your application.
You can try this statement at the beginning of main():
SCB->VTOR = 0x08000000;
There are a couple of assumptions in this value (0x08000000), but based on your other posts I think it is right.
@rlobo From your earlier posts you are using STM32H725IGTx and you created the project from CubeMX 6.2.1. It would be interesting to see your project as @aggarg requested.
There may be an oversight in the ST startup code, not setting SCB->VTOR. The value 0x1FF09800 appears to be left over from the ST BSL, which starts the MCU from power-on reset under many circumstances.
Based on similar forum posts, I wonder if the port should verify the installation of the PendSV and SVCall handlers. In doing so, it would also verify VTOR is set properly. See this commit for example. Does this seem worth doing across the various Cortex M ports?