FreeRTOS not initializing after jumping from bootloader

mslavov wrote on Friday, September 28, 2018:

Hello,
I have been developing a firmware application for our STM32F746 - based product.
The idea idea to have a bootloader code that can do firmware update and/or jump to the application.
I have been using IAR Embedded Workbench for my development, with Cortex-M7 / ST STM32F746VG as target CPU
The bootloader code is loaded at address 0x08000000, and the application - at address 0x08080000 in internal flash.

This is my initial buttloader code; it is not using any external libraries, and not doing any extra operations yet (this would be added later):

//------
/*
STM32F746
Flash: 0x08000000 - 0x080FFFFF (1 MB)
Bootloader: 0x08000000 - 0x0807FFFF (5212KB)
Application: 0x08080000 - 0x080FFFFF (512KB)
/
#include <stdio.h>
*
#include <stdint.h>
#include <intrinsics.h>
#include “stm32f7xx.h” // STM32F746VG Cortex-M7 Device
#include <core_cm7.h> // STM32F746VG Cortex-M7 Core

typedef void (application_t) (void);

extern const uint32_t app_vector; // Application vector address symbol from
// the linker configuration file: 0x08080000

typedef struct vector
{
uint32_t stack_addr; // intvec[0] is initial Stack Pointer
application_t *func_p; // intvec[1] is initial Program Counter
} vector_t;

int main(void)
{
const vector_t vector_p = (vector_t) &app_vector;
volatile uint32_t stack_arr[100] = {0}; // Allocate some stack just to show that
// the SP should be reset before the jump - or the
// stack won’t be configured correctly.
__enable_interrupt();
printf(“Hello from bootloader!\n”);
__disable_interrupt(); // 1. Disable interrupts
__set_SP(vector_p->stack_addr); // 2. Configure stack pointer
SCB->VTOR = (uint32_t) &app_vector; // 3. Configure VTOR
vector_p->func_p(); // 4. Jump to application
}
//------

And this is my application’ main() function; it is using STM HALL library ant FreeRTOS libtrary (it is a multitasking application)
//------
int main(void)
{
printf(“Hello from application!\n”);

/* Enable the CPU Cache */
CPU_CACHE_Enable();

/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();

/* Configure the system clock */
SystemClock_Config();

/* Several modules initialization */
/* ...... */

/* Call init function for freertos objects (in freertos.c) */
MX_FREERTOS_Init();

/* Start scheduler */
osKernelStart();

/* We should never get here as control is now taken by the scheduler */
while ( 1 );

}
//------

The jump to application is successfull, and everything executes ok until “MX_FREERTOS_Init();”
I was able to trace the issue to:
MX_FREERTOS_Init() ->
myMutex01Handle = osMutexCreate(osMutex(myMutex01)); ->
return xSemaphoreCreateMutex(); = xQueueCreateMutex( queueQUEUE_TYPE_MUTEX ); ->
xQueueGenericCreate( uxMutexLength, uxMutexSize, ucQueueType ); ->
pvPortMalloc( sizeof( Queue_t ) + xQueueSizeInBytes ); ->
( void ) xTaskResumeAll(); ->
taskENTER_CRITICAL() = portENTER_CRITICAL() = vPortEnterCritical() ->
portDISABLE_INTERRUPTS(); // stalls here!

I broke the last macro into containing functions:
__disable_interrupt();
__set_BASEPRI( configMAX_SYSCALL_INTERRUPT_PRIORITY );
__DSB();
__ISB();
__enable_interrupt();

The code run stalls in the last instruction: __enable_interrupt();

Any idea what can be frong?

Note: If the application is loaded at address 0x08000000 (no bootloader), it runs OK.

-Thanks!

rtel wrote on Sunday, September 30, 2018:

As the issue occurs when you enable the interrupt - is it possible that as soon as interrupts are enabled an interrupt actually executes, but not an interrupt that you expect? Perhaps using the wrong vector table, or something similar?