ARMmbed / mbed-os

Arm Mbed OS is a platform operating system designed for the internet of things
https://mbed.com
Other
4.66k stars 2.97k forks source link

STM32WB55RG - STM_OTA BLE don't update firmware #11864

Closed pawelm87 closed 4 years ago

pawelm87 commented 4 years ago

Description of defect

STM_OTA is a kind of BLE bootloader which is given by ST with STM32WB55. STM_OTA is load in start memory blocks from address 0x08000000 to 0x08006000, but user app (my app, not example) will be loaded in memory from index 0x08007000 to end. When I used STM_OTA from ST and tried to load the Mbed program (with shifted RAM and ROM), after loading I see that the memory is empty. This is the main problem for me. When I used example bin file everything work perfect (I have STM_OTA and example program in memory STM32WB55).

Example: image

Target(s) affected by this defect ?

Nucleo-WB55RG - STM32WB55RG USB Dongle - STM32WB55CG

Toolchain(s) (name and version) displaying this defect ?

Mbed Studio: 0.7.0

What version of Mbed-os are you using (tag or sha) ?

mbed-os 5.14

What version(s) of tools are you using. List all that apply (E.g. mbed-cli)

Mbed Studio: 0.7.0

STM32CubeProgrammer v2.2.0 STM32CubeMonitor-RF v2.4.0

download example en.stm32cubewb 1.2.0

How is this defect reproduced ?

In all STM32WB55 is loaded "stm32wb5x_FUS_fw.bin" and "stm32wb5x_BLE_Stack_fw.bin" in version 1.2.0. CPU and BLE work correct.

To P-NUCLEO-WB55.USBDongle load "BLE_TransparentModeVCP_reference.hex" from folder: en.stm32cubewb\STM32Cube_FW_WB_V1.2.0\Projects\P-NUCLEO-WB55.USBDongle\Applications\BLE\BLE_TransparentModeVCP\Binary (programme USB Dongle in USB-DFU mode with STMCubeProgrammer - move the BOOT0 switch to 1, once programmed move back switch to 0)

To P-NUCLEO-WB55.Nucleo load "BLE_Ota_reference.hex" from folder: en.stm32cubewb\STM32Cube_FW_WB_V1.2.0\Projects\P-NUCLEO-WB55.Nucleo\Applications\BLE\BLE_Ota\Binary and reset device. It will be write in start memory block.

Open STM32CubeMonitor-RF

Program will be loaded to memory from start address (0x7000). It can check in STM32CubeProgrammer image

Ok It work on example.

Now I started write my code in MbedStudio. First I loaded example "BLE_GattServer", and shift RAM and ROM space (It is described in datasheet AN5247 for EWARM IDE)

image In mbed-os I overwrite file:

; #if !defined(MBED_APP_SIZE) ; 768KB FLASH ; #define MBED_APP_SIZE 0xC0000 ; 768KB FLASH - 0x7000 = 0xB9000

define MBED_APP_SIZE 0xB9000 ; <- new walue

; #endif

if !defined(MBED_BOOT_STACK_SIZE)

define MBED_BOOT_STACK_SIZE 0x400

endif

define Stack_Size MBED_BOOT_STACK_SIZE

; 768KB FLASH (0xC0000) + 192KB SRAM (0x30000) + Shared mem LR_IROM1 MBED_APP_START MBED_APP_SIZE { ; load region size_region

ER_IROM1 MBED_APP_START MBED_APP_SIZE { ; load address = execution address .o (RESET, +First) (InRoot$$Sections) .ANY (+RO) }

; Total: 79 vectors = 316 bytes (0x13C) to be reserved in RAM ; RW_IRAM1 (0x20000000+0x13C) (0x30000-0x13C-Stack_Size) { ; RW data RW_IRAM1 (0x20000004+0x13C) (0x30000-0x13C-Stack_Size-0x4) { ; RW data -< new value .ANY (+RW +ZI) }

ARM_LIB_STACK (0x20000000+0x30000) EMPTY -Stack_Size { ; stack }

; SRAM2 - Shared memory RW_IRAM2a 0x20030000 0x00002800 { ; RW data (MAPPING_TABLE) (MB_MEM1) } RW_IRAM2b 0x20038000 0x00005000 { ; RW data *(MB_MEM2) } }

Additionally I change "cmsis_nvic.h":

ifndef MBED_CMSIS_NVIC_H

define MBED_CMSIS_NVIC_H

// CORE: 16 vectors = 64 bytes from 0x00 to 0x3F // MCU Peripherals: 63 vectors = 252 bytes from 0x40 to 0x13B // Total: 16+63=79 vectors = 316 bytes (0x13C) to be reserved in RAM

define NVIC_NUM_VECTORS 79

define NVIC_RAM_VECTOR_ADDRESS 0x20000004 // Vectors positioned at start of RAM <- new value

endif

and "flash_data.h":

ifndef MBED_FLASH_DATA_H

define MBED_FLASH_DATA_H

if DEVICE_FLASH

ifdef FLASH_SIZE

undef FLASH_SIZE

endif

// Only the first the application side is accessible.

define FLASH_SIZE ((uint32_t)0xB9000) // (768 Kbytes - 0x7000) <- new value

endif

endif


In BLE_GattServer project I overwrite "main.cpp":
- add define  
`#define BLE_CFG_OTA_REBOOT_CHAR 1`
- line 51 
`_hour_char("0000FE11-8e22-4541-9d4c-21edae82ed19", 3), // request reboot`
- line 339 -342           

/ Properties / //GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE , //GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY | //GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE,



After that I build program and update firmware by OTA. Run STM32CubeMonitor-RF, scan, connect and choose my bin file with program (BLE_Gatt_Server). Wait a few secount to finish loading ("Done"). 
![image](https://user-images.githubusercontent.com/35663020/68855237-2155d100-06de-11ea-87bc-17a74d9070c3.png)

My program dont run, I check memory by STM32CubeProgrammmer and I see that there is only STM_OTA, my program didn't load to memory (after index 0x08007000 was FF:FF...) 
![image](https://user-images.githubusercontent.com/35663020/68855306-3f233600-06de-11ea-8ef5-fbac44bffd88.png)

When I come bact to default value of RAM and ROM, I building and programing STM32WB55 not by OTA but by STM32CubeProgrammer (0x08000000), the program work fine.

I don't sure where correctly add new characteristic "ble_conf.h" is only in example project, so I decided add it to main file and "hw_conf.h" in **mbed-os\targets\TARGET_STM\TARGET_STM32WB\device**

Why I cannot load program by STM_OTA, why after loading memory is empty. Maybe I wrong change linker file or something else. Somebody can confirm this problem and help my with this case ? 
0xc0170 commented 4 years ago

cc @ARMmbed/team-st-mcd Please review

LMESTM commented 4 years ago

Hi @pawelm87

Thanks for the detailed description. I'm not sure about what's wrong, but I'm just proposing a few ideas:

1) linker script and magic key

In en.stm32cubewb\STM32Cube_FW_WB_V1.2.0\Projects\P-NUCLEO-WB55.Nucleo\Applications\BLE\BLE_HeartRate_ota\EWARM\stm32wb55xx_flash_cm4_ota.icf

There is a definition of a specific section:

keep { section TAG_OTA_START};
keep { section TAG_OTA_END };
place in OTA_TAG_region   { section TAG_OTA_START };

This sections needs to contain magic keys that are defined in app_ble.c of BLE_HeartRate_ota application example:

PLACE_IN_SECTION("TAG_OTA_END") const uint32_t MagicKeywordValue = 0x94448A29 ;
PLACE_IN_SECTION("TAG_OTA_START") const uint32_t MagicKeywordAddress = (uint32_t)&MagicKeywordValue;

I guess this is being checked to verify that the firmware being downloaded is valid.

2) RAM alignment This may be needed only at a later stage, but in mbed we need RAM to be 8 bytes aligned, so I would suggest to rework :

RW_IRAM1 (0x20000004+0x13C) (0x30000-0x13C-Stack_Size-0x4) { ; RW data -< new value

Hope this helps, Laurent

ciarmcom commented 4 years ago

Internal Jira reference: https://jira.arm.com/browse/MBOTRIAGE-2335

pawelm87 commented 4 years ago

@LMESTM thanks for the answer.

Ok this mayby a problem, but where can I change it in mbed linek file and libs ? Mbed linker file describe start addres for app and size but not start and end address of app. So this is the problem, in where place linker script I can add TAG?

Example linker from en.stm32cubewb is prepared for diffrent compiler not mbed.

/**
 * 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;

I insert this section to file "stm32wb_HCIDriver.cpp" because this file contains BLE configuration. It is correct place ? What describe this parameter "MagicKeywordValue = 0x94448A29"

This is another example from this folder:

; *************************************************************
; *** Scatter-Loading Description File generated by **uVision** ***
; *************************************************************

LR_IROM1 0x08007000 0x184 {    ; load region size_region
  ER_IROM1_LOW 0x08007000 0x184  {  ; load address = execution address
   *.o(RESET, +First)
   *.o(TAG_OTA_START) 
  }
  RW_IRAM1     0x20000004 0x2FFFC  {  ; RW data
   .ANY (+RW +ZI)
  }
  RW_RAM_SHARED 0x20030000 0x2800  {  ; RW data
   *(MAPPING_TABLE)
   *(MB_MEM1)
   *(MB_MEM2)
  }
  }
LR_IROM3 0x08007184 0x78E7C {
  ER_IROM1_HIGH 0x08007184 0x78E7C {  ; load address = execution address   

    *(InRoot$$Sections)
    .ANY (+RO)  
    *.o(TAG_OTA_END)       
  }
  }

There is two space for ROM space in mbed linker I have only one ROM space. Would You describe this parameter/ address ? It maybe I try rewrite script "0x184" "0x78E7C" "0x08007184"

In this line: RW_IRAM1 (0x20000004+0x13C) (0x30000-0x13C-Stack_Size-0x4) { ; RW data -< new value I shift RAM by 4 bytes. Do You mean that I need shift by 8 bytes? RW_IRAM1 (0x20000008+0x13C) (0x30000-0x13C-Stack_Size-0x8) { ; RW data -< new value Now is ok?

LMESTM commented 4 years ago

@LMESTM thanks for the answer.

Ok this mayby a problem, but where can I change it in mbed linek file and libs ? Mbed linker file describe start addres for app and size but not start and end address of app. So this is the problem, in where place linker script I can add TAG?

The TAG is fixed at a fixed address inside the application memory. (0x140 after APP start). You'll need to add something like the below lines in your code :

define region OTA_TAG_region   = mem:[from (__region_ROM_start__ + 0x140)   to (__region_ROM_end__+ 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 };

Example linker from en.stm32cubewb is prepared for diffrent compiler not mbed.

What do you mean ? Several toolchains are supported in mbed, see here: https://github.com/ARMmbed/mbed-os/tree/master/targets/TARGET_STM/TARGET_STM32WB/TARGET_STM32WB55xG/device Each directory contains the linker script for the corresponding toolchain

/**
 * 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;

I insert this section to file "stm32wb_HCIDriver.cpp" because this file contains BLE configuration. It is correct place ? What describe this parameter "MagicKeywordValue = 0x94448A29"

Looks like a good place yes. I don't know what the magic value is. I don't have more information that the one from the application note and example. I guess the OTA application will check if the magic work is there and only flash the .bin if correctly detected. Because your bin didn't have a Magicword it would explain why there is nothing in Flash in 0x7000 after you finish loading.

This is another example from this folder:

; *************************************************************
; *** Scatter-Loading Description File generated by **uVision** ***
; *************************************************************

LR_IROM1 0x08007000 0x184 {    ; load region size_region
  ER_IROM1_LOW 0x08007000 0x184  {  ; load address = execution address
   *.o(RESET, +First)
   *.o(TAG_OTA_START) 
  }
  RW_IRAM1     0x20000004 0x2FFFC  {  ; RW data
   .ANY (+RW +ZI)
  }
  RW_RAM_SHARED 0x20030000 0x2800  {  ; RW data
   *(MAPPING_TABLE)
   *(MB_MEM1)
   *(MB_MEM2)
  }
  }
LR_IROM3 0x08007184 0x78E7C {
  ER_IROM1_HIGH 0x08007184 0x78E7C {  ; load address = execution address   

    *(InRoot$$Sections)
    .ANY (+RO)  
    *.o(TAG_OTA_END)       
  }
  }

Corresponding scatter file in MBED is here: https://github.com/ARMmbed/mbed-os/blob/master/targets/TARGET_STM/TARGET_STM32WB/TARGET_STM32WB55xG/device/TOOLCHAIN_ARM_STD/stm32wb55xx.sct

There is two space for ROM space in mbed linker I have only one ROM space. Would You describe this parameter/ address ? It maybe I try rewrite script "0x184" "0x78E7C" "0x08007184"

I think that defining 2 spaces is just an implementation choice with ARM scatter files to introduce the OTA TAG memory location.

In this line: RW_IRAM1 (0x20000004+0x13C) (0x30000-0x13C-Stack_Size-0x4) { ; RW data -< new value I shift RAM by 4 bytes. Do You mean that I need shift by 8 bytes? RW_IRAM1 (0x20000008+0x13C) (0x30000-0x13C-Stack_Size-0x8) { ; RW data -< new value Now is ok?

I think it is better yes. I am not sure what those first (4 or 8) bytes are reserved for though.

pawelm87 commented 4 years ago

@LMESTM I use MbedStudio 0.7.0 (ARM Compiler 6.11), and my linker is in folder TOOLCHAIN_ARM_STD. I think that code for linker what You wrote abowe is for TOOLCHAIN_IAR ?

LMESTM commented 4 years ago

@pawelm87 Ok sorry. Well the point is to define the TAG_OTA sections in the linker scripts, using Cube reference and merging into mbed linker scripts => this sections of 4 bytes each contain data that is needed for the OTA case. I hope you can give it a try ... The 1st TAG is at fixed address and contains the last address of the application. The 2nd TAG allows to verify that the last bytes of the application contains what it is expected to contain: a magic word. If this matches well the OTA SW can be confident that the file transfer went well

pawelm87 commented 4 years ago

Ok I try do it but mbed give me a error when I build program.

I used example for uVision because there linker script is quite similat with my linker. When I try split ER_IROM1 to two different space I got error...

; #if !defined(MBED_APP_START)
; #define MBED_APP_START 0x08000000
#define MBED_APP_START 0x08007000
; #endif

; #if !defined(MBED_APP_SIZE)
; 768KB FLASH
; #define MBED_APP_SIZE 0xC0000
; 768KB FLASH - 0x7000 = 0xB9000
#define MBED_APP_SIZE 0xB9000
; #endif

#if !defined(MBED_BOOT_STACK_SIZE)
  #define MBED_BOOT_STACK_SIZE 0x400
#endif

#define Stack_Size MBED_BOOT_STACK_SIZE

; 768KB FLASH (0xC0000) + 192KB SRAM (0x30000) +  Shared mem
LR_IROM1 MBED_APP_START 0x184  {    ; load region size_region

  ER_IROM1_LOW MBED_APP_START 0x184  {  ; load address = execution address
   *.o (RESET, +First)
   *.o(TAG_OTA_START) 
  }

  ; Total: 79 vectors = 316 bytes (0x13C) to be reserved in RAM
  ; RW_IRAM1 (0x20000000+0x13C) (0x30000-0x13C-Stack_Size)  {  ; RW data
  RW_IRAM1 (0x20000004+0x13C) (0x30000-0x13C-Stack_Size-0x4)  {  ; RW data -< new value
  .ANY (+RW +ZI)
  }

  ARM_LIB_STACK (0x20000000+0x30000) EMPTY -Stack_Size { ; stack
  }

  ; SRAM2 - Shared memory
  RW_IRAM2a 0x20030000 0x00002800  {  ; RW data
    *(MAPPING_TABLE)
    *(MB_MEM1)
  }
  RW_IRAM2b 0x20038000 0x00005000  {  ; RW data
   *(MB_MEM2)
  }
}
LR_IROM3 (MBED_APP_START + 0x184) (MBED_APP_SIZE - 0x184) {
  ER_IROM1_HIGH (MBED_APP_START + 0x184) (MBED_APP_SIZE - 0x184) {  ; load address = execution address   

    *(InRoot$$Sections)
    .ANY (+RO)  
    *.o(TAG_OTA_END)       
  }
  }

Error in MbedStudio

"BUILD/NUCLEO_WB55RG/ARMC6/.link_script.sct", line 61 (column 8): Warning: L6314W: No section matches pattern *.o(TAG_OTA_START).
"BUILD/NUCLEO_WB55RG/ARMC6/.link_script.sct", line 87 (column 9): Warning: L6314W: No section matches pattern *.o(TAG_OTA_END).
Error: L6220E: Load region LR_IROM1 size (488 bytes) exceeds limit (388 bytes). Region contains 75 bytes of padding and 0 bytes of veneers (total 75 bytes of linker generated content).
Error: L6221E: Load region LR_IROM1 with Load range [0x08007000,0x080071e8) overlaps with Load region LR_IROM3 with Load range [0x08007184,0x0802dc84).
Finished: 0 information, 13 warning and 2 error messages.
LMESTM commented 4 years ago

I'm not expert in ARM linker scripts :-(

What you need to reach is:

The sum of TAG_OTA_START & RESET sections size is supposed to fit into 0x140 ... but it seems this is not the case ... you may need to check what they contain. I'm forwarding your questions internally to see if they can provide help

Also the map file can provide you useful information to understand what's wrong ...

LMESTM commented 4 years ago

Extra proposal - to get more information on how to add the proper TAGs in the linker scripts and what they are meant for, I would suggest you to ask your questions in: https://community.st.com/s/topic/0TO0X0000003fOMWAY/stm32wb

The questions there should be more about the CubeFW than the mbed linker scripts, but you can get more detailed information about needs to be done and the reference implementation on various linker scripts.

pawelm87 commented 4 years ago

Ok I success compile example program using this the linker script ( add TAG_OTA_STAR and TAG_OTA_END) and split it (0x1ec) without conflict :

; #if !defined(MBED_APP_START)
; #define MBED_APP_START 0x08000000
#define MBED_APP_START 0x08007000
; #endif

; #if !defined(MBED_APP_SIZE)
; 768KB FLASH
; #define MBED_APP_SIZE 0xC0000
; 768KB FLASH - 0x7000 = 0xB9000
#define MBED_APP_SIZE 0xB9000
; #endif

#if !defined(MBED_BOOT_STACK_SIZE)
  #define MBED_BOOT_STACK_SIZE 0x400
#endif

#define Stack_Size MBED_BOOT_STACK_SIZE

; 768KB FLASH (0xC0000) + 192KB SRAM (0x30000) +  Shared mem
LR_IROM1 MBED_APP_START 0x1ec  {    ; load region size_region

  ER_IROM1_LOW MBED_APP_START 0x1ec  {  ; load address = execution address
   *.o (RESET, +First)
   *.o (TAG_OTA_START) 
  }

  ; Total: 79 vectors = 316 bytes (0x13C) to be reserved in RAM
  ; RW_IRAM1 (0x20000000+0x13C) (0x30000-0x13C-Stack_Size)  {  ; RW data
  RW_IRAM1 (0x20000004+0x13C) (0x30000-0x13C-Stack_Size-0x4)  {  ; RW data -< new value
  .ANY (+RW +ZI)
  }

  ARM_LIB_STACK (0x20000000+0x30000) EMPTY -Stack_Size { ; stack
  }

  ; SRAM2 - Shared memory
  RW_IRAM2a 0x20030000 0x00002800  {  ; RW data
    *(MAPPING_TABLE)
    *(MB_MEM1)
  }
  RW_IRAM2b 0x20038000 0x00005000  {  ; RW data
   *(MB_MEM2)
  }
}
LR_IROM3 (MBED_APP_START + 0x1ec) (MBED_APP_SIZE - 0x1ec) {
  ER_IROM1_HIGH (MBED_APP_START + 0x1ec) (MBED_APP_SIZE - 0x1ec) {  ; load address = execution address   

    *(InRoot$$Sections)
    .ANY (+RO)  
    *.o (TAG_OTA_END)       
  }
  }
Total Static RAM memory (data + bss): 19197(+0) bytes
Total Flash memory (text + data): 159284(+0) bytes
Image: BUILD/NUCLEO_WB55RG/ARMC6\BLE_GattSerever.bin

but I got two file :/

PS C:\...\Mbed studio\BLE_GattSerever\BUILD\NUCLEO_WB55RG\ARMC6\BLE_GattSerever.bin> ls

    Directory: C:\...\Mbed studio\BLE_GattSerever\BUILD\NUCLEO_WB55RG\ARMC6\BLE_Gat
    tSerever.bin

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----       18.11.2019     09:32         158464 ER_IROM1_HIGH
-a----       18.11.2019     09:32               492 ER_IROM1_LOW

For me this is strange because they are not bin files, and I cannot upload them in one moment to the MCU. Any ideas?

LMESTM commented 4 years ago

Hi ,

I would suggest that you report the issue (i.e. that splitting into 2 regions end up with 2 binaries which is not what you want to achieve) in the suggested forum.

If you want to fix it in the meantime you could

0xc0170 commented 4 years ago

Is there anything that should be fixed in Mbed OS. @LMESTM ?

LMESTM commented 4 years ago

@0xc0170 I'd like to know the outcomes of @pawelm87 tests so that we an understand if there is anything that we can retrofit in mbed-os or if it's too specific ...

pawelm87 commented 4 years ago

@LMESTM and @0xc0170 I tried to do the following to fix it:

When I work with BLE_GattServer example without OTA and I shift RAM in linker script :

   ; RW_IRAM1 (0x20000000+0x13C) (0x30000-0x13C-Stack_Size)  {  ; RW data
   RW_IRAM1 (0x20000000+0x13C+0x4) (0x30000-0x13C-Stack_Size+0x4)  {  ; RW data

program work. But when I change RAM address in "cmsis_nvic.h" in the target folder: #define NVIC_RAM_VECTOR_ADDRESS 0x20000004 after programming, program don't work.

1. Now I tested OTA: I rewrite linker script:

; #if !defined(MBED_APP_START)
; #define MBED_APP_START 0x08000000
 #define MBED_APP_START 0x08007000 
; #endif

; #if !defined(MBED_APP_SIZE)
; 768KB FLASH
; #define MBED_APP_SIZE 0xC0000
 #define MBED_APP_SIZE 0xB9000
; #endif

#if !defined(MBED_BOOT_STACK_SIZE)
  #define MBED_BOOT_STACK_SIZE 0x400
#endif

#define Stack_Size MBED_BOOT_STACK_SIZE

; 768KB FLASH (0xC0000) + 192KB SRAM (0x30000) +  Shared mem
LR_IROM1 MBED_APP_START 0x1EC  {    ; load region size_region

  ER_IROM1_LOW MBED_APP_START 0x1EC  {  ; load address = execution address
   *.o (RESET, +First)
   ; *(InRoot$$Sections)
   ; .ANY (+RO)
   *.o(TAG_OTA_START) 
  }

  ; Total: 79 vectors = 316 bytes (0x13C) to be reserved in RAM
  ; RW_IRAM1 (0x20000000+0x13C) (0x30000-0x13C-Stack_Size)  {  ; RW data
   RW_IRAM1 (0x20000000+0x13C+0x4) (0x30000-0x13C-Stack_Size-0x4)  {  ; RW data
  .ANY (+RW +ZI)
  }

  ARM_LIB_STACK (0x20000000+0x30000) EMPTY -Stack_Size { ; stack
  }

  ; SRAM2 - Shared memory
  RW_IRAM2a 0x20030000 0x00002800  {  ; RW data
    *(MAPPING_TABLE)
    *(MB_MEM1)
  }
  RW_IRAM2b 0x20038000 0x00005000  {  ; RW data
   *(MB_MEM2)
  }
}

LR_IROM3 0x080071EC 0xB8E14 { ; 0xC0000 - 0x7000 - 0x1EC, 0x1EC -> if less, mbed prints error about memory overlaps
  ER_IROM1_HIGH 0x080071EC 0xB8E14 {  ; load address = execution address   
    *(InRoot$$Sections)
    .ANY (+RO)  
    *.o(TAG_OTA_END)       
  }
  }

edit file "flash_data.h"

#define FLASH_SIZE    ((uint32_t)0xB9000) // 768 Kbytes from 0xC0000 to 0xB9000

edit file "cmsis.nvic.h"

#define NVIC_RAM_VECTOR_ADDRESS 0x20000004  // Vectors positioned at start of RAM from 0x20000000 to x20000004

add place section to "stm32_HCIDriver.cpp":

PLACE_IN_SECTION("TAG_OTA_END") const uint32_t MagicKeywordValue = 0x94448A29 ;
PLACE_IN_SECTION("TAG_OTA_START") const uint32_t MagicKeywordAddress = (uint32_t)&MagicKeywordValue;

Now I build the program and I got two file:

27.11.2019  10:12           158 648   ER_IROM1_HIGH
27.11.2019  10:12                  488   ER_IROM1_LOW

I merge this file to one in cmd console:

COPY /B ER_IROM1_LOW +  ER_IROM1_HIGH 1.bin

In "STM32 ST-LINK Utility" I check "MagicKeywordValue" and "MagicKeywordAddress" and above values are not there. image

image

After that, I upload my bin file to nucleo, but STM_OTA reject it because probably doesn't find "MagicKeywordValue" and "MagicKeywordAddress" in code. So this flow work doesn't work.

2. I edit linker script:

; #if !defined(MBED_APP_START)
#define MBED_APP_START 0x08007000
; #endif

; #if !defined(MBED_APP_SIZE)
; 768KB FLASH
#define MBED_APP_SIZE 0xB9000
; #endif

#if !defined(MBED_BOOT_STACK_SIZE)
  #define MBED_BOOT_STACK_SIZE 0x400
#endif

#define Stack_Size MBED_BOOT_STACK_SIZE

; 768KB FLASH (0xC0000) + 192KB SRAM (0x30000) +  Shared mem
LR_IROM1 MBED_APP_START MBED_APP_SIZE  {    ; load region size_region

  ER_IROM1 MBED_APP_START MBED_APP_SIZE  {  ; load address = execution address
   *.o (RESET, +First)
   *(InRoot$$Sections)
   .ANY (+RO)
  }

  ; Total: 79 vectors = 316 bytes (0x13C) to be reserved in RAM
  ; RW_IRAM1 (0x20000000+0x13C) (0x30000-0x13C-Stack_Size)  {  ; RW data
  RW_IRAM1 (0x20000000+0x13C+0x4) (0x30000-0x13C-Stack_Size-0x4)  {  ; RW data
  .ANY (+RW +ZI)
  }

  ARM_LIB_STACK (0x20000000+0x30000) EMPTY -Stack_Size { ; stack
  }

  ; SRAM2 - Shared memory
  RW_IRAM2a 0x20030000 0x00002800  {  ; RW data
    *(MAPPING_TABLE)
    *(MB_MEM1)
  }
  RW_IRAM2b 0x20038000 0x00005000  {  ; RW data
   *(MB_MEM2)
  }
}

edit file "flash_data.h"

#define FLASH_SIZE    ((uint32_t)0xB9000) // 768 Kbytes from 0xC0000 to 0xB9000

edit file "cmsis.nvic.h"

#define NVIC_RAM_VECTOR_ADDRESS 0x20000004  // Vectors positioned at start of RAM from 0x20000000 to x20000004

Now in "main.cpp" file I add a piece of code:

int MagicKeywordAdress __attribute__((section(".ARM.__at_0x08007140"))) = 0x0802DDA8;
int MagicKeywordValue  __attribute__((section(".ARM.__at_0x0802DDA8"))) = 0x94448A29;

0x08026E58 - it is example value

Again, In "STM32 ST-LINK Utility" I check "MagicKeywordValue" and "MagicKeywordAddress" and in code above values are there.

image image Mbed always add some code at the end of program. Now after programming nucleo, STM_OTA find what he need and accept my program.

image

But program don't work because I swithed RAM 0x20000004. In ble scanner I don't see GattServer device. The program has probably crashed and STM_OTA cannot be restarted. Again, this flow work doesn't work.

3. I do everything that i did in point 2 but dont edit "NVIC_RAM_VECTOR_ADDRESS 0x20000000" in file "cmsis_nvic.h"

After that I upload to nucleo by STM_OTA the program and bootloader does nott reject program. After reset I see my device BLE_GattServer in ble scanner. BUT STM_OTA don't work. I cannot again upload other program. Probably I override some data in RAM - Reboot request characteristics.

I have some question:

image and image Datasheet: image

image

This is my "main.cpp" file you must edit extension from txt to cpp. It is BLE_GattServer example with my edit for reboot request. main.txt

LMESTM commented 4 years ago

@pawelm87 Looks like good progress anyway. Your method 2) for defining the TAGS sections seems a good idea and seem to work well.

But as explained before, MBED requires RAM regions to be 8 bytes aligned. Can you please rather try to shift to 0x20000008 ?

#define NVIC_RAM_VECTOR_ADDRESS 0x20000008  // Vectors positioned at start of RAM from 0x20000000 to x20000004

And then reflect this in the linker script:

  ; Total: 79 vectors = 316 bytes (0x13C) to be reserved in RAM
  ; RW_IRAM1 (0x20000000+0x13C) (0x30000-0x13C-Stack_Size)  {  ; RW data
  RW_IRAM1 (0x20000000+0x13C+0x8) (0x30000-0x13C-Stack_Size-0x8)  {  ; RW data
  .ANY (+RW +ZI)
  }

?

pawelm87 commented 4 years ago

image

I shift to 0x20000008 at linker script and build program. I merge two file in one and checking bin file but i don't find specyfic "magic" value for STM_OTA. I tried upload to nucleo but when finish STM_OTA reject my program.

LMESTM commented 4 years ago

I don't understand.

I said your option 2) seems a good solution and you said previously that the Magic value was well present in ROM with option 2) and there is no need to merge binaries with opton 2).

=> so I think this is the best option. So I proposed you to use option 2) and try to align RAM boundaries to 8 bytes

pawelm87 commented 4 years ago

@LMESTM sorry, my mistake I have done so many variants ... I will tried your suggest ...

pawelm87 commented 4 years ago

image

When I shift RAM by 8 bytes with your suggestion, mbed crash and print message at Serial Monitor about error.

LMESTM commented 4 years ago

Do you mean that it crashes now after the binary was downloaded and installed through OTA ?

If so, that would mean that at least it's booting now, whereas it was not booting at all up to now in your step 2) ... Can you debug and see where it actually fails ?

LMESTM commented 4 years ago

About the OTA related questions, I don't have more information than publicly available information from here https://www.st.com/content/ccc/resource/technical/document/application_note/group1/47/71/00/8f/f8/ef/45/4b/DM00556294/files/DM00556294.pdf/jcr:content/translations/en.DM00556294.pdf

For further questions on OTA program itself, you'd rather ask around here: https://community.st.com/s/topic/0TO0X0000003fOMWAY/stm32wb

pawelm87 commented 4 years ago

Yes, after upload bin file through OTA, mbed prints error by serial monitor, that means my program run but crash. I added in first line main() printf command to see if print that - dont print.

I can debug program by add printf commands to the program.

My Question at ST community: https://community.st.com/s/question/0D50X0000BcTRBXSQ4/stm32wb55rg-stmota-ble-dont-update-firmware-how-change-mbed-linker

LMESTM commented 4 years ago

Can't you rather debug with a JTAG debugger ? that would help a lot to check where the error comes from ...

pawelm87 commented 4 years ago

@LMESTM I cannot debug with a JTAG debugger.

Also Mbed Studio not support debug nucleo_wb55rg yet.

LMESTM commented 4 years ago

@0xc0170 Any idea what would be missing to get NUCLEO_WB55RG supported in mbed Studio ?

0xc0170 commented 4 years ago

@0xc0170 Any idea what would be missing to get NUCLEO_WB55RG supported in mbed Studio ?

Does it have cmsis-pack and pyOCD support?

LMESTM commented 4 years ago

@jeromecoutant ?

pawelm87 commented 4 years ago
PS C:\Users> C:\Users\...\AppData\Local\Programs\Python\Python37\Scripts\pyocd-gdbserver.exe
0000557:WARNING:gdb_server:pyocd-gdbserver is deprecated; please use the new combined pyocd tool.
0001182:ERROR:gdb_server:uncaught exception: Target type 'stm32wb55rgvx' not recognized. Use 'pyocd list --targets' to see currently available target types. See <https://github.com/mbedmicro/pyOCD/blob/master/docs/target_support.md> for how to install additional target support.

PS C:\Users> C:\Users\...\AppData\Local\Programs\Python\Python37\Scripts\pyocd.exe list --targets
  Name                      Vendor                  Part Number                  Families   Source
-----------------------------------------------------------------------------------------------------
  cc3220sf                  Texas Instruments       CC3220SF                                builtin
  cortex_m                  Generic                 CoreSightTarget                         builtin
  cy8c64xa_cm0              Cypress                 cy8c64xA_cm0                            builtin
  cy8c64xa_cm4              Cypress                 cy8c64xA_cm4                            builtin
  cy8c64xa_cm4_full         Cypress                 cy8c64xA_cm4_full                       builtin
  cy8c64xa_cm4_full_flash   Cypress                 cy8c64xA_cm4_full_flash                 builtin
  cy8c64xx_cm0              Cypress                 cy8c64xx_cm0                            builtin
  cy8c64xx_cm4              Cypress                 cy8c64xx_cm4                            builtin
  cy8c64xx_cm4_full         Cypress                 cy8c64xx_cm4_full                       builtin
  cy8c64xx_cm4_full_flash   Cypress                 cy8c64xx_cm4_full_flash                 builtin
  cy8c6xx5                  Cypress                 CY8C6xx5                                builtin
  cy8c6xx7                  Cypress                 CY8C6xx7                                builtin
  cy8c6xxa                  Cypress                 CY8C6xxA                                builtin
  hc32f120x6                HDSC                    HC32F120x6TA                            builtin
  hc32f120x8                HDSC                    HC32F120x8TA                            builtin
  hc32f46x                  HDSC                    HC32F46x                                builtin
  hc32m120                  HDSC                    HC32M120                                builtin
  k20d50m                   NXP                     K20D50M                                 builtin
  k22f                      NXP                     K22F                                    builtin
  k22fa12                   NXP                     K22FA12                                 builtin
  k28f15                    NXP                     K28F15                                  builtin
  k32w042s                  NXP                     K32W042S                                builtin
  k64f                      NXP                     K64F                                    builtin
  k66f18                    NXP                     K66F18                                  builtin
  k82f25615                 NXP                     K82F25615                               builtin
  ke15z7                    NXP                     KE15Z7                                  builtin
  ke18f16                   NXP                     KE18F16                                 builtin
  kinetis                   NXP                     Kinetis                                 builtin
  kl02z                     NXP                     KL02Z                                   builtin
  kl05z                     NXP                     KL05Z                                   builtin
  kl25z                     NXP                     KL25Z                                   builtin
  kl26z                     NXP                     KL26Z                                   builtin
  kl27z4                    NXP                     KL27Z4                                  builtin
  kl28z                     NXP                     KL28x                                   builtin
  kl43z4                    NXP                     KL43Z4                                  builtin
  kl46z                     NXP                     KL46Z                                   builtin
  kl82z7                    NXP                     KL82Z7                                  builtin
  kv10z7                    NXP                     KV10Z7                                  builtin
  kv11z7                    NXP                     KV11Z7                                  builtin
  kw01z4                    NXP                     KW01Z4                                  builtin
  kw24d5                    NXP                     KW24D5                                  builtin
  kw36z4                    NXP                     KW36Z4                                  builtin
  kw40z4                    NXP                     KW40Z4                                  builtin
  kw41z4                    NXP                     KW41Z4                                  builtin
  lpc11u24                  NXP                     LPC11U24                                builtin
  lpc11xx_32                NXP                     LPC11XX_32                              builtin
  lpc1768                   NXP                     LPC1768                                 builtin
  lpc4088                   NXP                     LPC4088                                 builtin
  lpc4088dm                 NXP                     LPC4088dm                               builtin
  lpc4088qsb                NXP                     LPC4088qsb                              builtin
  lpc4330                   NXP                     LPC4330                                 builtin
  lpc54114                  NXP                     LPC54114                                builtin
  lpc54608                  NXP                     LPC54608                                builtin
  lpc55s69                  Generic                 LPC55S69JBD100                          builtin
  lpc800                    NXP                     LPC800                                  builtin
  lpc824                    NXP                     LPC824                                  builtin
  m252kg6ae                 Nuvoton                 M252KG6AE                               builtin
  max32600                  Maxim                   MAX32600                                builtin
  max32620                  Maxim                   MAX32620                                builtin
  max32625                  Maxim                   MAX32625                                builtin
  max32630                  Maxim                   MAX32630                                builtin
  mimxrt1020                NXP                     MIMXRT1021xxxxx                         builtin
  mimxrt1050                NXP                     MIMXRT1052xxxxB_hyperflash              builtin
  mimxrt1050_hyperflash     NXP                     MIMXRT1052xxxxB_hyperflash              builtin
  mimxrt1050_quadspi        NXP                     MIMXRT1052xxxxB_quadspi                 builtin
  musca_a1                  Arm                     MuscaA1                                 builtin
  musca_b1                  Arm                     MuscaB1                                 builtin
  ncs36510                  ONSemiconductor         NCS36510                                builtin
  nrf51                     Nordic Semiconductor    NRF51                                   builtin
  nrf52                     Nordic Semiconductor    NRF52                                   builtin
  nrf52840                  Nordic Semiconductor    NRF52840                                builtin
  rtl8195am                 Realtek Semiconductor   RTL8195AM                               builtin
  stm32f051                 STMicroelectronics      STM32F051                               builtin
  stm32f103rc               STMicroelectronics      STM32F103RC                             builtin
  stm32f412xe               STMicroelectronics      STM32F412xE                             builtin
  stm32f412xg               STMicroelectronics      STM32F412xG                             builtin
  stm32f429xg               STMicroelectronics      STM32F429xG                             builtin
  stm32f429xi               STMicroelectronics      STM32F429xI                             builtin
  stm32f439xg               STMicroelectronics      STM32F439xG                             builtin
  stm32f439xi               STMicroelectronics      STM32F439xI                             builtin
  stm32l031x6               STMicroelectronics      STM32L031x6                             builtin
  stm32l475xc               STMicroelectronics      STM32L475xC                             builtin
  stm32l475xe               STMicroelectronics      STM32L475xE                             builtin
  stm32l475xg               STMicroelectronics      STM32L475xG                             builtin
  w7500                     WIZnet                  W7500                                   builtin

did it help ?

LMESTM commented 4 years ago

For debugging the current issue you may use a generic cortex_m target - that would work just fine should be something like:

pyocd-gdbserver.exe -t cortex_m

jeromecoutant commented 4 years ago

Correct command is:

pyocd gdbserver --pack Keil.STM32WBxx_DFP.1.0.0.pack

pack file can be found on https://www.keil.com/dd2/pack/

pawelm87 commented 4 years ago

Ok I run pyOCD and debugging my program. I must switch to GCC_ARM compiler and run debug in Visual Studio Code

image

1: (8084) ->^done
1: (8084) ->(gdb)
<--   C (threads-7): {"command":"threads","type":"request","seq":7}
1: (8274) ->~"\nProgram"

Program
1: (8274) ->~" received signal SIGSEGV, Segmentation fault.\n"
 received signal SIGSEGV, Segmentation fault.
1: (8276) ->~"Reset_Handler () at .\\mbed-os\\targets\\TARGET_STM\\TARGET_STM32WB\\TARGET_STM32WB55xG\\device\\TOOLCHAIN_GCC_ARM/startup_stm32wb55xx.S:52\n"
Reset_Handler () at .\mbed-os\targets\TARGET_STM\TARGET_STM32WB\TARGET_STM32WB55xG\device\TOOLCHAIN_GCC_ARM/startup_stm32wb55xx.S:52
1: (8277) ->~"52\t  ldr   r0, =_estack\n"
52    ldr   r0, =_estack
1: (8277) ->*stopped,reason="signal-received",signal-name="SIGSEGV",signal-meaning="Segmentation fault",frame={addr="0x08016c70",func="Reset_Handler",args=[],file=".\\mbed-os\\targets\\TARGET_STM\\TARGET_STM32WB\\TARGET_STM32WB55xG\\device\\TOOLCHAIN_GCC_ARM/startup_stm32wb55xx.S",fullname="C:\\Users\\pawel\\Desktop\\workspace\\Mbed_studio\\mbed-BLE-GattServer\\mbed-os\\targets\\TARGET_STM\\TARGET_STM32WB\\TARGET_STM32WB55xG\\device\\TOOLCHAIN_GCC_ARM\\startup_stm32wb55xx.S",line="52"},thread-id="1",stopped-threads="all"
1: (8277) <-1022-stack-list-frames 0 1000
1: (8289) ->1022^done,stack=[frame={level="0",addr="0x08016c70",func="Reset_Handler",file=".\\mbed-os\\targets\\TARGET_STM\\TARGET_STM32WB\\TARGET_STM32WB55xG\\device\\TOOLCHAIN_GCC_ARM/startup_stm32wb55xx.S",fullname="C:\\Users\\pawel\\Desktop\\workspace\\Mbed_studio\\mbed-BLE-GattServer\\mbed-os\\targets\\TARGET_STM\\TARGET_STM32WB\\TARGET_STM32WB55xG\\device\\TOOLCHAIN_GCC_ARM\\startup_stm32wb55xx.S",line="52"}]
1: (8289) ->(gdb)
1: (8289) 1022: elapsed time 11
1: (8289) ->&"\n"
1: (8289) ->^done
1: (8289) ->(gdb)
1: (8290) Send Event AD7ExceptionEvent
Execute debugger commands using "-exec <command>", for example "-exec info registers" will list registers in use (when GDB is the debugger)
<--   C (threads-8): {"command":"threads","type":"request","seq":8}
<--   C (stackTrace-9): {"command":"stackTrace","arguments":{"threadId":1,"startFrame":0,"levels":20},"type":"request","seq":9}
1: (8333) <-1023-stack-list-arguments 0 0 0
1: (8343) ->1023^done,stack-args=[frame={level="0",args=[]}]
1: (8343) ->(gdb)
1: (8343) 1023: elapsed time 9
1: (8344) ->&"\n"
1: (8344) ->^done
1: (8344) ->(gdb)
<--   C (scopes-10): {"command":"scopes","arguments":{"frameId":1000},"type":"request","seq":10}
1: (8780) <-1024-stack-list-variables 0
1: (8782) ->1024^done,variables=[]
1: (8782) ->(gdb)
1: (8782) 1024: elapsed time 1
1: (8782) ->&"\n"
1: (8783) ->^done
1: (8783) ->(gdb)
<--   C (evaluate-11): {"command":"evaluate","arguments":{"expression":"CopyDataInit","frameId":1000,"context":"hover"},"type":"request","seq":11}
1: (158129) <-1025-var-create - * "CopyDataInit"
1: (158139) ->1025^done,name="var1",numchild="0",value="{<text variable, no debug info>} 0x8016c7e <Reset_Handler+14>",type="<text variable, no debug info>",has_more="0"
1: (158140) ->(gdb)
1: (158140) 1025: elapsed time 10
1: (158140) ->&"\n"
1: (158140) ->^done
1: (158140) ->(gdb)

Changed files:

I don't changed linker script for GCC_ARM, in default I would like to work in Mbed Studio - ARMC6. I will try change toolchains from GCC_ARM to ARMC6 (changing config for pyOCD).

When I compile program GCC_ARM with old RAM setting - 0x20000000 work, but when i change to 0x20000008 mbed crash.

LMESTM commented 4 years ago

if you do below change #define NVIC_RAM_VECTOR_ADDRESS 0x20000008

you also need to adapt RAM1 (rwx) : ORIGIN = 0x2000013C + 8, LENGTH = 192K - 0x13C - 8

@0xc0170 yes there is cmsis-pack and pyocd support, so how can support be added to mbedStudio ?

pawelm87 commented 4 years ago

@LMESTM you are right I must edit linker for GCC, I forget about it

I cannot debug again (programming nucleo), vsc display error message :/ image

when run debuger the led on nucleo is toggle (red-green). When I programming nucleo by STM32CubeProgrammer it's work fine

pawelm87 commented 4 years ago

when I program nucleo early by STM32CubeProgrammer and try debug, get this error code:

1: (108) LaunchOptions<LocalLaunchOptions xmlns='http://schemas.microsoft.com/vstudio/MDDDebuggerOptions/2014'
1: (119) LaunchOptions  ExePath='C:\Users\pawel\Desktop\workspace\Mbed_studio\mbed-BLE_GattServerV2\BUILD\NUCLEO_WB55RG\GCC_ARM\mbed-BLE_GattServerV2.elf'
1: (119) LaunchOptions  WorkingDirectory='C:\Users\pawel\Desktop\workspace\Mbed_studio\mbed-BLE_GattServerV2'
1: (119) LaunchOptions  ExeArguments='2&gt;CON 1&gt;CON &lt;CON'
1: (119) LaunchOptions  MIMode='gdb'
1: (119) LaunchOptions  MIDebuggerPath='C:\Program Files (x86)\GNU Tools ARM Embedded\6 2017-q2-update\bin\arm-none-eabi-gdb.exe'
1: (119) LaunchOptions  WaitDynamicLibLoad='false'
1: (119) LaunchOptions  DebugServer='C:\Users\pawel\AppData\Local\Programs\Python\Python37\Scripts\pyocd-gdbserver.exe'
1: (119) LaunchOptions  DebugServerArgs=''
1: (119) LaunchOptions  ServerStarted='GDB\ server\ started'
1: (119) LaunchOptions  FilterStderr='true'
1: (119) LaunchOptions  ServerLaunchTimeout='20000'
1: (119) LaunchOptions>
1: (119) LaunchOptions    <SetupCommands>
1: (119) LaunchOptions        <Command IgnoreFailures='false' Description=''>-environment-cd C:\Users\pawel\Desktop\workspace\Mbed_studio\mbed-BLE_GattServerV2\BUILD\NUCLEO_WB55RG\GCC_ARM\</Command>
1: (119) LaunchOptions        <Command IgnoreFailures='false' Description='connect to target'>-target-select remote localhost:3333</Command>
1: (119) LaunchOptions        <Command IgnoreFailures='false' Description='load file'>-file-exec-and-symbols mbed-BLE_GattServerV2.elf</Command>
1: (119) LaunchOptions        <Command IgnoreFailures='false' Description=''>-interpreter-exec console "monitor endian little"</Command>
1: (119) LaunchOptions        <Command IgnoreFailures='false' Description=''>-interpreter-exec console "monitor reset"</Command>
1: (119) LaunchOptions        <Command IgnoreFailures='false' Description=''>-interpreter-exec console "monitor halt"</Command>
1: (119) LaunchOptions        <Command IgnoreFailures='false' Description=''>-interpreter-exec console "monitor arm semihosting enable"</Command>
1: (119) LaunchOptions        <Command IgnoreFailures='false' Description='flash target'>-target-download</Command>
1: (119) LaunchOptions    </SetupCommands>
1: (119) LaunchOptions</LocalLaunchOptions>
1: (164) Starting: "C:\Users\pawel\AppData\Local\Programs\Python\Python37\Scripts\pyocd-gdbserver.exe" 
1: (1686) "C:\Users\pawel\AppData\Local\Programs\Python\Python37\Scripts\pyocd-gdbserver.exe" exited with code 1 (0x1).
1: (1691) <-logout
1: (20190) Send Event AD7MessageEvent)

task.json:

{
    // See https://go.microsoft.com/fwlink/?LinkId=733558
    // for the documentation about the tasks.json format
    "version": "0.1.0",
    "name": "mbed",
    "isShellCommand": true,
    "showOutput": "always",
    "problemMatcher": {
        "owner": "cpp",
        "fileLocation": ["relative", "${workspaceRoot}/mbed-os"],
        "pattern": {
            "regexp": "^(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$",
            "file": 1,
            "line": 2,
            "column": 3,
            "severity": 4,
            "message": 5
        }
    },
    "args": ["compile", "--profile=debug", "-t", "GCC_ARM", "-m", "NUCLEO_WB55RG"],
    "linux": {
        "command": "mbed"
    },
    "osx": {
        "command": "mbed"
    },
    "windows": {
        "command": "mbed.exe"
    }
}

launch.json

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "C++ Launch",
            "type": "cppdbg",
            "request": "launch",
            "program": "${workspaceRoot}/BUILD/NUCLEO_WB55RG/GCC_ARM/${workspaceRootFolderName}.elf",
            "args": [],
            "stopAtEntry": true,
            "cwd": "${workspaceRoot}",
            "environment": [],
            "externalConsole": false,
            "debugServerArgs": "",
            "serverLaunchTimeout": 20000,
            "filterStderr": true,
            "filterStdout": false,
            "serverStarted": "GDB\\ server\\ started",
            "preLaunchTask": "mbed",
            "setupCommands": [
                { "text": "-target-select remote localhost:3333", "description": "connect to target", "ignoreFailures": false },
                { "text": "-file-exec-and-symbols ${workspaceRootFolderName}.elf", "description": "load file", "ignoreFailures": false},
                { "text": "-interpreter-exec console \"monitor endian little\"", "ignoreFailures": false },
                { "text": "-interpreter-exec console \"monitor reset\"", "ignoreFailures": false },
                { "text": "-interpreter-exec console \"monitor halt\"", "ignoreFailures": false },
                { "text": "-interpreter-exec console \"monitor arm semihosting enable\"", "ignoreFailures": false },
                { "text": "-target-download", "description": "flash target", "ignoreFailures": false }
            ],
            "logging": {
                "moduleLoad": true,
                "trace": true,
                "engineLogging": true,
                "programOutput": true,
                "exceptions": true
            },
            "linux": {
                "MIMode": "gdb",
                "MIDebuggerPath": "arm-none-eabi-gdb",
                "debugServerPath": "pyocd-gdbserver"
            },
            "osx": {
                "MIMode": "gdb",
                "MIDebuggerPath": "arm-none-eabi-gdb",
                "debugServerPath": "pyocd-gdbserver"
            },
            "windows": {
                "preLaunchTask": "mbed.exe",
                "MIMode": "gdb",
                "MIDebuggerPath": "C:\\Program Files (x86)\\GNU Tools ARM Embedded\\6 2017-q2-update\\bin\\arm-none-eabi-gdb.exe",
                "debugServerPath": "C:\\Users\\pawel\\AppData\\Local\\Programs\\Python\\Python37\\Scripts\\pyocd-gdbserver.exe",
                "setupCommands": [
                    { "text": "-environment-cd ${workspaceRoot}\\BUILD\\NUCLEO_WB55RG\\GCC_ARM\\" },
                    { "text": "-target-select remote localhost:3333", "description": "connect to target", "ignoreFailures": false },
                    { "text": "-file-exec-and-symbols ${workspaceRootFolderName}.elf", "description": "load file", "ignoreFailures": false},
                    { "text": "-interpreter-exec console \"monitor endian little\"", "ignoreFailures": false },
                    { "text": "-interpreter-exec console \"monitor reset\"", "ignoreFailures": false },
                    { "text": "-interpreter-exec console \"monitor halt\"", "ignoreFailures": false },
                    { "text": "-interpreter-exec console \"monitor arm semihosting enable\"", "ignoreFailures": false },
                    { "text": "-target-download", "description": "flash target", "ignoreFailures": false }
                ]
            }
        }
    ]
}

any idea what go wrong ?

pawelm87 commented 4 years ago
PS C:\Users\pawel> C:\Users\pawel\AppData\Local\Programs\Python\Python37\Scripts\pyocd-gdbserver.exe
0000391:WARNING:gdb_server:pyocd-gdbserver is deprecated; please use the new combined pyocd tool.
Waiting for a debug probe to be connected...
0005399:INFO:board:Target type is stm32wb55rgvx
0005512:ERROR:gdb_server:uncaught exception: STLink error (9): Get IDCODE error

probably something wrong with my stlink?

LMESTM commented 4 years ago

I don't now :-( ... you may want to update your stlink firmware to the latest version (the Cube programmed can do that)

pawelm87 commented 4 years ago

image

When I connect P-NUCLEO-WB55 to PC and run STM32CubeProgrammer, the program show error message. I upgraded to the last version of firmware. This error may by a problem with pyOCD? With this error i can do everything with nucleo in the STM32Cube - I can program, erase and read memory :/

LMESTM commented 4 years ago

Sorry I don't know the reason (pyocd gdbserver should be down when you connect with STM32Cubeprogrammer)

As not related to mbed, I think it best to look for answers here: https://community.st.com/stm32

pawelm87 commented 4 years ago

I tried run debuger on diffrent computer and have this same error stlink :/ My config for debuger works, becouse i can debug other nucleo for example NUCLEO_L152RE.
@LMESTM I have a question. If i can't debug stm32wb55, can I shift ram in another nucleo (stm32l152) and debug. This will tell us where mbed-os crash at such a shift. Will this help?

LMESTM commented 4 years ago

@pawelm87 Could be helpful indeed.

Before that test, I have found another possible explanation, I wonder if the line below also needs to be updated https://github.com/ARMmbed/mbed-os/blob/master/targets/TARGET_STM/TARGET_STM32WB/TARGET_STM32WB55xG/device/cmsis_nvic.h#L24

to #define NVIC_RAM_VECTOR_ADDRESS 0x20000008 // Vectors positioned at start of RAM

pawelm87 commented 4 years ago

Before that test, I have found another possible explanation, I wonder if the line below also needs to be updated https://github.com/ARMmbed/mbed-os/blob/master/targets/TARGET_STM/TARGET_STM32WB/TARGET_STM32WB55xG/device/cmsis_nvic.h#L24

to #define NVIC_RAM_VECTOR_ADDRESS 0x20000008 // Vectors positioned at start of RAM

@LMESTM When I change only RAM address in the linker script, after uploading user app via OTA, bootloader run user app but I cannot again upload other app via OTA - only one I can upload user app (STM32CubeMonitor-RF does not see device).

I tried to find support for the reset request in the "BLE_HeartRate_ota" program in the examples "STM32Cube_FW_WB_V1.2.0" I did not come across a piece of code responsible for handling this request. You may know where it appears in the example above (anything useful will lead me to this piece of code).

LMESTM commented 4 years ago

@pawelm87 I'm a bit lost. Last thing I know your mbed app built with the proper TAG and 0x20000008 offset value in linker script, could be downloaded through the OTA process but it would not boot at all and display mbed-os error message. => so the idea was to solve this point with the above proposal - can you confirm whether you have tested this or not ?

I assume that the few bytes from 0x20000000 to 0x20000008 are used by the OTA so you need this offset to be well implemented before going to the next stage

pawelm87 commented 4 years ago

First test: I shift RAM in linker script and "cmsis_nvic.h" file #define NVIC_RAM_VECTOR_ADDRESS 0x20000008 // Vectors positioned at start of RAM and added magic value and address manually. It upload via OTA, OTA does not reject user app and run it but mbed crash

Second test: I shift RAM only in linker script not in "cmsis_nvic.h" file #define NVIC_RAM_VECTOR_ADDRESS 0x20000000 // Vectors positioned at start of RAM and add magic value and address manually. It upload via OTA, OTA does not reject user app and run app and work but I don't again upload other app (tested only at STM32CubeMonitor RF, not via smartphone)

Before that test, I have found another possible explanation, I wonder if the line below also needs to be updated https://github.com/ARMmbed/mbed-os/blob/master/targets/TARGET_STM/TARGET_STM32WB/TARGET_STM32WB55xG/device/cmsis_nvic.h#L24

to #define NVIC_RAM_VECTOR_ADDRESS 0x20000008 // Vectors positioned at start of RAM

but may You have right, about do not shifting RAM in cmsis_nvic.h file. #define NVIC_RAM_VECTOR_ADDRESS 0x20000008 // Vectors positioned at start of RAM linker will do it.

User app save data which comes from Reboot Request at this address and reset chip. OTA read data of this address and decide what need to do run user app or upload new firmware. In short, that's how I understand it.

I must implement Reboot Request characteristic and handler for test this. I finded above pieces of code in examples now I must re-write it to mbed, modificate it and test it. I will write soon.

LMESTM commented 4 years ago

Hi @pawelm87

One more input that could be useful to you - I made a few more tests to be able to shift RAM vector address and it turns out that this vector table needs to be aligned much more than I thought.

I found a working configuration (in GCC) with cmsis_device.h defined as below: #define NVIC_RAM_VECTOR_ADDRESS 0x20000200 // Vectors positioned at start of RAM

So the SRAM needs to be shifted accordingly as below: RAM1 (rwx) : ORIGIN = 0x2000023C, LENGTH = 192K - 0x13C - 0x200

This actually wastes some RAM as you shift by 0x200 and only need to use the 4 first bytes, but for unblocking your situation this might help.

in ARM sct that should be (not tested): RW_IRAM1 (0x20000000+0x13C+0x200) (0x30000-0x13C-0x200-Stack_Size) { ; RW data

Note about alignment: I found this note about cortex-M3 devices, but could not find the corresponding one for cortex-M4: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0552a/Ciheijba.html

EDIT - for any further reference, the correct offset calculation can be found here https://static.docs.arm.com/ddi0403/eb/DDI0403E_B_armv7m_arm.pdf The Vector table must be naturally aligned to a power of two whose alignment value is greater than or equal to (Number of Exceptions supported x 4), with a minimum alignment of 128 bytes.

in this case, this means 0x200 should be the minimum offset (0x100 above was replaced with 0x200)

pawelm87 commented 4 years ago

Hi @LMESTM I use MbedStudio ARMC6. I researched example for ota program and I have some info how it work and what it need:

when reset request will be send to device via the characteristics the device fallowing this piece of code:

#if(BLE_CFG_OTA_REBOOT_CHAR != 0)
            else if(attribute_modified->Attr_Handle == (aPeerToPeerContext.RebootReqCharHdle + 1))
            {
              BLE_DBG_P2P_STM_MSG("-- GATT : REBOOT REQUEST RECEIVED\n");
              Notification.P2P_Evt_Opcode = P2PS_STM_BOOT_REQUEST_EVT;
              Notification.DataTransfered.Length=attribute_modified->Attr_Data_Length;
              Notification.DataTransfered.pPayload=attribute_modified->Attr_Data;
              P2PS_STM_App_Notification(&Notification);
            }
#endif

and

#if(BLE_CFG_OTA_REBOOT_CHAR != 0)
    case P2PS_STM_BOOT_REQUEST_EVT:
      APP_DBG_MSG("-- P2P APPLICATION SERVER : BOOT REQUESTED\n");
      APP_DBG_MSG(" \n\r");

      *(uint32_t*)SRAM1_BASE = *(uint32_t*)pNotification->DataTransfered.pPayload;
      NVIC_SystemReset();
      break;
#endif

define:

#define SRAM_BASE              (0x20000000UL)            /*!< SRAM(up to 256 KB) base address */
#define SRAM1_BASE             SRAM_BASE                 /*!< SRAM1(up to 192 KB) base address */

uint8_t * pPayload;

after this I know why I need RAM (shift ram by 4), because there is saved the data from "reset request characteristics", and when the device will reset after that ota probably read it and decide what do: image

So if I don't shift RAM I overwrite mbed data. What mbed-os do after that may crash or not. I don't know. But after overwrite data in RAM device is reset.

So the datasheet say that I need ram shift. I did make a few test with shift RAM but only in the linker script (#define NVIC_RAM_VECTOR_ADDRESS 0x20000000 not change this) by 8 bytes, and for GattServer example on this moment it work. I didn't test with bigger program. I do this:

printf("before change SRAM1_BASE address: 0x%x, value: %u\n\r", (uint32_t)SRAM1_BASE, *(uint32_t*)SRAM1_BASE);
*(uint32_t*)SRAM1_BASE = *(uint32_t*)e->data & 0x000000FF;
printf("after change SRAM1_BASE address: 0x%x, value: %u\n\r", (uint32_t)SRAM1_BASE, *(uint32_t*)SRAM1_BASE);
printf("SRAM1_BASE 0|1|2|3: %d, %d, %d, %d\r\n", *(uint32_t*)SRAM1_BASE, *(uint32_t*)(SRAM1_BASE + 1), *(uint32_t*)(SRAM1_BASE + 2), *(uint32_t*)(SRAM1_BASE + 3));
NVIC_SystemReset();

but I see that when every time when the my app will be started the ram space will be overwritten by mbed :/

before change SRAM1_BASE address: 0x20000000, value: 537067520
after change SRAM1_BASE address: 0x20000000, value: 1
SRAM1_BASE 0|1|2|3: 1, 1224736768, 1950941184, 7620864
before change SRAM1_BASE address: 0x20000000, value: 537067520
after change SRAM1_BASE address: 0x20000000, value: 1
SRAM1_BASE 0|1|2|3: 1, 1224736768, 1950941184, 7620864

my logs, I send two reset request characteristics one by one. Mbed-os overwrite RAM. I change the linker :/ May I must edit #define NVIC_RAM_VECTOR_ADDRESS 0x20000000 ??

LMESTM commented 4 years ago

EDIT - for any further reference, the correct offset calculation can be found here https://static.docs.arm.com/ddi0403/eb/DDI0403E_B_armv7m_arm.pdf The Vector table must be naturally aligned to a power of two whose alignment value is greater than or equal to (Number of Exceptions supported x 4), with a minimum alignment of 128 bytes. in this case, this means 0x200 should be the minimum offset

mbed-os copies the VECTOR table to NVIC_RAM_VECTOR_ADDRESS, so to avoid your data to be overwritten, yes you need to change both the information below at the same time: #define NVIC_RAM_VECTOR_ADDRESS 0x20000200 // Vectors positioned at start of RAM and RW_IRAM1 (0x20000000+0x13C+0x200) (0x30000-0x13C-0x100-Stack_Size) { ; RW data

That will free-up the start of RAM so that you can use this area with some code like below.

#define SRAM_BASE              (0x20000000UL)            /*!< SRAM(up to 256 KB) base address */
#define SRAM1_BASE             SRAM_BASE                 /*!< SRAM1(up to 192 KB) base address */
uint8_t * pPayload;
pawelm87 commented 4 years ago

@LMESTM I made a few test and it's work. I must testing more and if I will have some problem I will reopen. I am currently closing the post

Thanks for help.