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!