2020-03-02 09:06 AM
When I burn BLE_Ota_reference.hex and try to put my app seems that SysTick_Handler() is never called and after a while the PC goes to a strange location at 0x0800433e. This is outside 0x08007000.
The application is ok when I link everything at the default address 0x08000000 but when I change to 0x08007000 an put the BLE_Ota_reference.hex it behaves as described in the above line.
I attach my linker script. Any help would be appreciated.
I tried with two different versions of GCC in Linux just to check if it's something weird with the compiler.
/* Entry Point */
ENTRY(Reset_Handler)
/* Highest address of the user mode stack */
_estack = 0x20030000; /* end of RAM */
/* Generate a link error if heap and stack don't fit into RAM */
_Min_Heap_Size = 0x400; /* required amount of heap */
_Min_Stack_Size = 0x1000; /* required amount of stack */
/* Specify the memory areas */
MEMORY
{
FLASH (rx) : ORIGIN = 0x08007000, LENGTH = 484k
/*RAM1 (xrw) : ORIGIN = 0x20000004, LENGTH = 191k*/
RAM1 (xrw) : ORIGIN = 0x20000004, LENGTH = 0x2FFFC
RAM_SHARED (xrw) : ORIGIN = 0x20030000, LENGTH = 10K
}
/* Define output sections */
SECTIONS
{
/* The startup code goes first into FLASH */
.isr_vector :
{
. = ALIGN(4);
KEEP(*(.isr_vector)) /* Startup code */
. = ALIGN(4);
} >FLASH
.ota_region 0x08007140:
{
KEEP(*(TAG_OTA_START))
. = ALIGN(4);
} >FLASH
/* The program code and other data goes into FLASH */
.text :
{
. = ALIGN(4);
*(.text) /* .text sections (code) */
*(.text*) /* .text* sections (code) */
*(.glue_7) /* glue arm to thumb code */
*(.glue_7t) /* glue thumb to arm code */
*(.eh_frame)
KEEP (*(.init))
KEEP (*(.fini))
. = ALIGN(4);
_etext = .; /* define a global symbols at end of code */
} >FLASH
/* Constant data goes into FLASH */
.rodata :
{
. = ALIGN(4);
*(.rodata) /* .rodata sections (constants, strings, etc.) */
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
. = ALIGN(4);
} >FLASH
.ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH
.ARM : {
__exidx_start = .;
*(.ARM.exidx*)
__exidx_end = .;
} >FLASH
.preinit_array :
{
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array*))
PROVIDE_HIDDEN (__preinit_array_end = .);
} >FLASH
.init_array :
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array*))
PROVIDE_HIDDEN (__init_array_end = .);
} >FLASH
.fini_array :
{
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT(.fini_array.*)))
KEEP (*(.fini_array*))
PROVIDE_HIDDEN (__fini_array_end = .);
} >FLASH
.ota_region_end :
{
. = ALIGN(4);
KEEP(*(TAG_OTA_END))
. = ALIGN(4);
} >FLASH
/* used by the startup to initialize data */
_sidata = LOADADDR(.data);
/* Initialized data sections goes into RAM, load LMA copy after code */
.data :
{
. = ALIGN(4);
_sdata = .; /* create a global symbol at data start */
*(.data) /* .data sections */
*(.data*) /* .data* sections */
. = ALIGN(4);
_edata = .; /* define a global symbol at data end */
} >RAM1 AT> FLASH
/* Uninitialized data section */
. = ALIGN(4);
.bss :
{
/* This is used by the startup in order to initialize the .bss secion */
_sbss = .; /* define a global symbol at bss start */
__bss_start__ = _sbss;
*(.bss)
*(.bss*)
*(COMMON)
. = ALIGN(4);
_ebss = .; /* define a global symbol at bss end */
__bss_end__ = _ebss;
} >RAM1
/* User_heap_stack section, used to check that there is enough RAM left */
._user_heap_stack :
{
. = ALIGN(8);
PROVIDE ( end = . );
PROVIDE ( _end = . );
. = . + _Min_Heap_Size;
. = . + _Min_Stack_Size;
. = ALIGN(8);
} >RAM1
/* Remove information from the standard libraries */
/DISCARD/ :
{
libc.a ( * )
libm.a ( * )
libgcc.a ( * )
}
.ARM.attributes 0 : { *(.ARM.attributes) }
MAPPING_TABLE (NOLOAD) : { *(MAPPING_TABLE) } >RAM_SHARED
MB_MEM1 (NOLOAD) : { *(MB_MEM1) } >RAM_SHARED
MB_MEM2 (NOLOAD) : { _sMB_MEM2 = . ; *(MB_MEM2) ; _eMB_MEM2 = . ; } >RAM_SHARED
TAG_OTA_END(NOLOAD) : { KEEP (*(TAG_OTA_END)) } >FLASH
}
Also this is the main function (entry point)
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* 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_I2C1_Init();
MX_RF_Init();
MX_RTC_Init();
MX_USART1_UART_Init();
MX_TIM2_Init();
MX_ADC1_Init();
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */
/* Init code for STM32_WPAN */
APPE_Init();
..... continues
}
Thanks
2020-03-02 09:21 AM
2020-03-03 06:31 AM
I would say first: did you read AN5247 “Over-the-air application and wireless firmware update�?.
The application is slightly modified when prepared to be uploaded OTA.
This is why there are 2 versions of the BLE_HeartRate and BLE_p2pServer applications renamed.
Please check the files associated to these 2 examples.
In the app_ble.c file, the few lines below are key for the OTA loader to calculate the start of the binary image that just got uploaded over the air.
/**
* These are the two tags used to manage a power failure during OTA
* The MagicKeywordAdress shall be mapped @0x140 from start of the binary image
* The MagicKeywordvalue is checked in the ble_ota application
*/
PLACE_IN_SECTION("TAG_OTA_END") const uint32_t MagicKeywordValue = 0x94448A29 ;
PLACE_IN_SECTION("TAG_OTA_START") const uint32_t MagicKeywordAddress = (uint32_t)&MagicKeywordValue;
Did you include these lines in your own application?
2020-03-03 06:36 AM
OTA version of an application is almost identical to the original application, the differences are:
• Use special tags (to manage end data transfer and data consistency):
– TAG_OTA_END : The Magic Keyword value is checked in the thread_ota application
– TAG_OTA_START : The Magic Keyword address shall be mapped at 0x140 from start of the binary image
Therefore, by reading memory content at 0x140 it must be equal to Magic keyword value 0x94448A29.
• Scatter file must be updated to place the sections above
Example for IAR:
Vector table and ROM start @ moved to 0x08010000:
define symbol __ICFEDIT_intvec_start__ = 0x08010000;
define symbol __ICFEDIT_region_ROM_start__ = 0x08010000;
define region OTA_TAG_region = mem:
[from (__ICFEDIT_region_ROM_start__ + 0x140) to (__ICFEDIT_region_ROM_start__ + 0x140 + 4)];
keep { section TAG_OTA_START};
keep { section TAG_OTA_END };
place in OTA_TAG_region { section TAG_OTA_START };
place in ROM_region { readonly, last section TAG_OTA_END };
2020-03-03 10:59 PM
@Remi QUINTIN yes of course I've read AN5247 and of course there is this symbols defined in the expected location.
Take a look to the GNU LD script I attached, there is defined the expected memory positions and also in code I'm forcing it
...
PLACE_IN_SECTION("TAG_OTA_START") const uint32_t MagicKeywordAddress = (uint32_t)&MagicKeywordValue;
...
Any other point I can check?
2020-03-04 06:37 AM
Just to confirm one point: Did you manage to correctly uploaded you application on the STM32WB over the air?
2020-03-04 01:02 PM
@Remi QUINTIN unfortunately no. It only works with the ones that are compiled and distributed by ST.
I tried to upload with the ST App in Android but it behaves in the same way that when I upload it with STMCubeProgrammer at address 0x08007000.
Maybe the Ota_reference firmware leaves the microcontroller in some state that I have to reset but it's strange because as you see I call HAL_init() and all the initialisation functions.
I tested it with one application that does nothing, it only create a P2P server. All the sources are generated by the CubeMX (a modified the linker file to put the OTA tags and the linking address) and happens the same. It jumps to strange location at 0x08004xxx after a few instructions inside main function.
I don't know what more I can do.
2020-03-06 07:07 AM
Hello,
I believe your vector table is not at the correct location.
When building an application that would link @0x08000000 without OTA, the vector table is at the same location ( 0x08000000).
When building an application with OTA, the vector table shall be moved to 0x08007000.
In our current implementation, the BLE_OTA sets the vector table at the correct location before jumping to the application.
This means the application shall not modify this address.
The vector table address is defined with SCB->VTOR in the file system_stm32wbxx.c
By default, SCB->VTOR in the file system_stm32wbxx.c is modified in our templates.
If you compare the BLE_HearRate_ota and BLE_HearRate example, you will see that the only code change lays in system_stm32wbxx.c where the SCB->VTOR configuration has been removed in BLE_HearRate_ota . project.
Regards.
2020-03-07 02:25 PM
Hi,
Yes! Shame on me for not comparing both applications BLE_HearRate and BLE_HearRate_ota. I would have seen that change.
Thank you so much @Christophe Arnal and @Remi QUINTIN
Best regards