Issue with J-Link debugger while working with bootloader on STM32F765 - c

I'm using the J-Link EDU and STLink debugger present on the Nucleo boards from ST. For testing, the bootloader code is present at 0x8000000 and just jumps to 0x8020000 where the main app code is present. When I use the Jlink EDU, it can't program the flash at 0x8020000 every time successfully and if I modify the program and start debugging, the Jlink erases the flash but does not program it successfully and after the bootloader makes the jump, the MCU gets HardFault. Now this happens whether I use Jlink or the STLINK (converted to Jlink). Usually I see it stuck at 0xFFFFFFFE. At that point the JLINK has erased the app code but failed to program it.
The interesting thing is that the STlink debugger when converted back and used with openocd has no issues whatsoever with the bootloader jumping to main app code and debugging from there.
I also find that if I program the main app code at 0x8020000 by STLink and OpenOCD and then switch to JLINK EDU for debug, it works as long as the JLINK does't reprogram it. If in the log, I see that the JLINK flashes the code, then the ST crashes after jumping from bootloader. So I definitely think it has something to do with how the JLINK is erasing and programming the ST during debug.
I also tried programming with JLINK commander and that seems to fail as well. Unless I fully erase the chip.
I'm using System Workbench 2.0 with GNU ARM Eclipse plugin for Jlink debugging with the latest ARM toolchain as of this date and Jlink 616c. I'm using the STM32F765VI with the flash in dual bank configuration.
I'm also attaching the GDB logs from JLINK and STLINK for clarity. I would like to use JLINK for debugging since I can have SWO console in eclipse whereas its very cumbersome in OpenOCD so would like to resolve it.
Failed JLINK debug after it tried to program:
SEGGER J-Link GDB Server V6.16c Command Line Version
JLinkARM.dll V6.16c (DLL compiled Jun 16 2017 18:14:49)
WARNING: Unknown command line parameter -timeout found.
WARNING: Unknown command line parameter 0 found.
-----GDB Server start settings-----
GDBInit file: none
GDB Server Listening port: 2331
SWO raw output listening port: 2332
Terminal I/O port: 2333
Accept remote connection: localhost only
Generate logfile: off
Verify download: on
Init regs on start: on
Silent mode: off
Single run mode: on
Target connection timeout: 0 ms
------J-Link related settings------
J-Link Host interface: USB
J-Link script: none
J-Link settings file: none
------Target related settings------
Target device: STM32F765VI
Target interface: SWD
Target interface speed: 1000kHz
Target endian: little
Connecting to J-Link...
J-Link is connected.
Firmware: J-Link V10 compiled Jun 16 2017 16:15:19
Hardware: V10.10
S/N: 260101191
OEM: SEGGER-EDU
Feature(s): FlashBP, GDB
Checking target voltage...
Target voltage: 3.35 V
Listening on TCP/IP port 2331
Connecting to target...Connected to target
Waiting for GDB connection...Connected to 127.0.0.1
Reading all registers
Read 4 bytes # address 0x00000000 (Data = 0x51E9FF66)
Read 2 bytes # address 0x00000000 (Data = 0xFF66)
Target interface speed set to 1000 kHz
Resetting target
Halting target CPU...
...Target halted (PC = 0x080023CC)
R0 = 00000000, R1 = 00000000, R2 = 00000000, R3 = 00000000
R4 = 00000000, R5 = 00000000, R6 = 00000000, R7 = 00000000
R8 = 00000000, R9 = 00000000, R10= 00000000, R11= 00000000
R12= 00000000, R13= 20080000, MSP= 20080000, PSP= 00000000
R14(LR) = FFFFFFFF, R15(PC) = 080023CC
XPSR 01000000, APSR 00000000, EPSR 01000000, IPSR 00000000
CFBP 00000000, CONTROL 00, FAULTMASK 00, BASEPRI 00, PRIMASK 00
Reading all registers
Read 4 bytes # address 0x080023CC (Data = 0xD034F8DF)
Read 2 bytes # address 0x080023CC (Data = 0xF8DF)
Target interface speed set to 15000 kHz
Flash breakpoints enabled
SWO disabled succesfully.
SWO enabled succesfully.
Read 4 bytes # address 0x080023CC (Data = 0xD034F8DF)
Read 2 bytes # address 0x080023CC (Data = 0xF8DF)
Downloading 520 bytes # address 0x08020000 - Verified OK
Downloading 16064 bytes # address 0x08020210 - Verified OK
Downloading 16096 bytes # address 0x080240D0 - Verified OK
Downloading 16048 bytes # address 0x08027FB0 - Verified OK
Downloading 16112 bytes # address 0x0802BE60 - Verified OK
Downloading 16096 bytes # address 0x0802FD50 - Verified OK
Downloading 16112 bytes # address 0x08033C30 - Verified OK
Downloading 16144 bytes # address 0x08037B20 - Verified OK
Downloading 16000 bytes # address 0x0803BA30 - Verified OK
Downloading 15920 bytes # address 0x0803F8B0 - Verified OK
Downloading 16176 bytes # address 0x080436E0 - Verified OK
Downloading 16064 bytes # address 0x08047610 - Verified OK
Downloading 16032 bytes # address 0x0804B4D0 - Verified OK
Downloading 15696 bytes # address 0x0804F370 - Verified OK
Downloading 16032 bytes # address 0x080530C0 - Verified OK
Downloading 16176 bytes # address 0x08056F60 - Verified OK
Downloading 16064 bytes # address 0x0805AE90 - Verified OK
Downloading 16064 bytes # address 0x0805ED50 - Verified OK
Downloading 16128 bytes # address 0x08062C10 - Verified OK
Downloading 16176 bytes # address 0x08066B10 - Verified OK
Downloading 16112 bytes # address 0x0806AA40 - Verified OK
Downloading 16304 bytes # address 0x0806E930 - Verified OK
Downloading 16272 bytes # address 0x080728E0 - Verified OK
Downloading 16048 bytes # address 0x08076870 - Verified OK
Downloading 16080 bytes # address 0x0807A720 - Verified OK
Downloading 16048 bytes # address 0x0807E5F0 - Verified OK
Downloading 16048 bytes # address 0x080824A0 - Verified OK
Downloading 14616 bytes # address 0x08086350 - Verified OK
Downloading 16144 bytes # address 0x08089C80 - Verified OK
Downloading 16224 bytes # address 0x0808DB90 - Verified OK
Downloading 16128 bytes # address 0x08091AF0 - Verified OK
Downloading 16288 bytes # address 0x080959F0 - Verified OK
Downloading 16272 bytes # address 0x08099990 - Verified OK
Downloading 16256 bytes # address 0x0809D920 - Verified OK
Downloading 14880 bytes # address 0x080A18A0 - Verified OK
Downloading 8 bytes # address 0x080A52C0 - Verified OK
Downloading 4 bytes # address 0x080A52C8 - Verified OK
Downloading 4 bytes # address 0x080A52CC - Verified OK
Downloading 1068 bytes # address 0x080A52D0 - Verified OK
Comparing flash [....................] Done.
Erasing flash [....................] Done.
Programming flash [....................] Done.
Verifying flash [....................] Done.
Writing register (PC = 0x08083ED0)
Read 4 bytes # address 0x08083ED0 (Data = 0xE0032100)
Read 2 bytes # address 0x08083ED0 (Data = 0x2100)
Read 2 bytes # address 0x0807BAAE (Data = 0xF44F)
Read 2 bytes # address 0x0807BAAE (Data = 0xF44F)
Read 2 bytes # address 0x0807BAFA (Data = 0xF44F)
Read 2 bytes # address 0x0807BAFA (Data = 0xF44F)
Read 2 bytes # address 0x08080814 (Data = 0x4B14)
Read 4 bytes # address 0x08080868 (Data = 0x2002B994)
Read 2 bytes # address 0x08080814 (Data = 0x4B14)
Read 2 bytes # address 0x0807BB44 (Data = 0x687B)
Read 2 bytes # address 0x0807BBB2 (Data = 0xF897)
Resetting target
Halting target CPU...
...Target halted (PC = 0x080023CC)
Read 2 bytes # address 0x08080814 (Data = 0x4B14)
Read 4 bytes # address 0x08080868 (Data = 0x2002B994)
Read 2 bytes # address 0x08080814 (Data = 0x4B14)
Read 4 bytes # address 0x08080868 (Data = 0x2002B994)
Read 2 bytes # address 0x08080814 (Data = 0x4B14)
R0 = 00000000, R1 = 00000000, R2 = 00000000, R3 = 00000000
R4 = 00000000, R5 = 00000000, R6 = 00000000, R7 = 00000000
R8 = 00000000, R9 = 00000000, R10= 00000000, R11= 00000000
R12= 00000000, R13= 20080000, MSP= 20080000, PSP= 00000000
R14(LR) = FFFFFFFF, R15(PC) = 080023CC
XPSR 01000000, APSR 00000000, EPSR 01000000, IPSR 00000000
CFBP 00000000, CONTROL 00, FAULTMASK 00, BASEPRI 00, PRIMASK 00
Reading all registers
Read 4 bytes # address 0x080023CC (Data = 0xD034F8DF)
Read 2 bytes # address 0x080023CC (Data = 0xF8DF)
Setting breakpoint # address 0x0807BAAE, Size = 2, BPHandle = 0x0001
Setting breakpoint # address 0x0807BAFA, Size = 2, BPHandle = 0x0002
Setting breakpoint # address 0x0807BBB2, Size = 2, BPHandle = 0x0003
Setting breakpoint # address 0x08080814, Size = 2, BPHandle = 0x0004
Starting target CPU...
...Target halted (DBGRQ, PC = 0xFFFFFFFE)
Reading all registers
WARNING: Failed to read memory # address 0xFFFFFFFE
Removing breakpoint # address 0x0807BAAE, Size = 2
Removing breakpoint # address 0x0807BAFA, Size = 2
Removing breakpoint # address 0x0807BBB2, Size = 2
Removing breakpoint # address 0x08080814, Size = 2
WARNING: Failed to read memory # address 0xFFFFFFF4
Reading 64 bytes # address 0xFFFFFFC0
WARNING: Failed to read memory # address 0xFFFFFFC0
WARNING: Failed to read memory # address 0xFFFFFFF0
Reading 64 bytes # address 0xFFFFFFC0
WARNING: Failed to read memory # address 0xFFFFFFC0
WARNING: Failed to read memory # address 0xFFFFFFF0
Successful JLINK debug if it doesn't flash:
SEGGER J-Link GDB Server V6.16c Command Line Version
JLinkARM.dll V6.16c (DLL compiled Jun 16 2017 18:14:49)
WARNING: Unknown command line parameter -timeout found.
WARNING: Unknown command line parameter 0 found.
-----GDB Server start settings-----
GDBInit file: none
GDB Server Listening port: 2331
SWO raw output listening port: 2332
Terminal I/O port: 2333
Accept remote connection: localhost only
Generate logfile: off
Verify download: on
Init regs on start: on
Silent mode: off
Single run mode: on
Target connection timeout: 0 ms
------J-Link related settings------
J-Link Host interface: USB
J-Link script: none
J-Link settings file: none
------Target related settings------
Target device: STM32F765VI
Target interface: SWD
Target interface speed: 1000kHz
Target endian: little
Connecting to J-Link...
J-Link is connected.
Firmware: J-Link V10 compiled Jun 16 2017 16:15:19
Hardware: V10.10
S/N: 260101191
OEM: SEGGER-EDU
Feature(s): FlashBP, GDB
Checking target voltage...
Target voltage: 3.35 V
Listening on TCP/IP port 2331
Connecting to target...Connected to target
Waiting for GDB connection...Connected to 127.0.0.1
Reading all registers
Read 4 bytes # address 0x00000000 (Data = 0x51E9FF66)
Read 2 bytes # address 0x00000000 (Data = 0xFF66)
Target interface speed set to 1000 kHz
Resetting target
Halting target CPU...
...Target halted (PC = 0x080023CC)
R0 = 00000000, R1 = 00000000, R2 = 00000000, R3 = 00000000
R4 = 00000000, R5 = 00000000, R6 = 00000000, R7 = 00000000
R8 = 00000000, R9 = 00000000, R10= 00000000, R11= 00000000
R12= 00000000, R13= 20080000, MSP= 20080000, PSP= 00000000
R14(LR) = FFFFFFFF, R15(PC) = 080023CC
XPSR 01000000, APSR 00000000, EPSR 01000000, IPSR 00000000
CFBP 00000000, CONTROL 00, FAULTMASK 00, BASEPRI 00, PRIMASK 00
Reading all registers
Read 4 bytes # address 0x080023CC (Data = 0xD034F8DF)
Read 2 bytes # address 0x080023CC (Data = 0xF8DF)
Target interface speed set to 15000 kHz
Flash breakpoints enabled
SWO disabled succesfully.
SWO enabled succesfully.
Read 4 bytes # address 0x080023CC (Data = 0xD034F8DF)
Read 2 bytes # address 0x080023CC (Data = 0xF8DF)
Downloading 520 bytes # address 0x08020000 - Verified OK
Downloading 16064 bytes # address 0x08020210 - Verified OK
Downloading 16096 bytes # address 0x080240D0 - Verified OK
Downloading 16048 bytes # address 0x08027FB0 - Verified OK
Downloading 16112 bytes # address 0x0802BE60 - Verified OK
Downloading 16096 bytes # address 0x0802FD50 - Verified OK
Downloading 16112 bytes # address 0x08033C30 - Verified OK
Downloading 16144 bytes # address 0x08037B20 - Verified OK
Downloading 16000 bytes # address 0x0803BA30 - Verified OK
Downloading 15920 bytes # address 0x0803F8B0 - Verified OK
Downloading 16176 bytes # address 0x080436E0 - Verified OK
Downloading 16064 bytes # address 0x08047610 - Verified OK
Downloading 16032 bytes # address 0x0804B4D0 - Verified OK
Downloading 15696 bytes # address 0x0804F370 - Verified OK
Downloading 16032 bytes # address 0x080530C0 - Verified OK
Downloading 16176 bytes # address 0x08056F60 - Verified OK
Downloading 16064 bytes # address 0x0805AE90 - Verified OK
Downloading 16064 bytes # address 0x0805ED50 - Verified OK
Downloading 16128 bytes # address 0x08062C10 - Verified OK
Downloading 16176 bytes # address 0x08066B10 - Verified OK
Downloading 16112 bytes # address 0x0806AA40 - Verified OK
Downloading 16304 bytes # address 0x0806E930 - Verified OK
Downloading 16272 bytes # address 0x080728E0 - Verified OK
Downloading 16048 bytes # address 0x08076870 - Verified OK
Downloading 16080 bytes # address 0x0807A720 - Verified OK
Downloading 16048 bytes # address 0x0807E5F0 - Verified OK
Downloading 16048 bytes # address 0x080824A0 - Verified OK
Downloading 14616 bytes # address 0x08086350 - Verified OK
Downloading 16144 bytes # address 0x08089C80 - Verified OK
Downloading 16224 bytes # address 0x0808DB90 - Verified OK
Downloading 16128 bytes # address 0x08091AF0 - Verified OK
Downloading 16288 bytes # address 0x080959F0 - Verified OK
Downloading 16272 bytes # address 0x08099990 - Verified OK
Downloading 16256 bytes # address 0x0809D920 - Verified OK
Downloading 14880 bytes # address 0x080A18A0 - Verified OK
Downloading 8 bytes # address 0x080A52C0 - Verified OK
Downloading 4 bytes # address 0x080A52C8 - Verified OK
Downloading 4 bytes # address 0x080A52CC - Verified OK
Downloading 1068 bytes # address 0x080A52D0 - Verified OK
Comparing flash [....................] Done.
Verifying flash [....................] Done.
Writing register (PC = 0x08083ED0)
Read 4 bytes # address 0x08083ED0 (Data = 0xD034F8DF)
Read 2 bytes # address 0x08083ED0 (Data = 0xF8DF)
Read 2 bytes # address 0x08083ED2 (Data = 0xD034)
Read 2 bytes # address 0x0807BAAE (Data = 0xF44F)
Read 2 bytes # address 0x0807BAAE (Data = 0xF44F)
Read 2 bytes # address 0x0807BB44 (Data = 0x687B)
Read 2 bytes # address 0x0807BBB2 (Data = 0xF897)
Read 2 bytes # address 0x0807BAFA (Data = 0xF44F)
Read 2 bytes # address 0x0807BAFA (Data = 0xF44F)
Resetting target
Halting target CPU...
...Target halted (PC = 0x080023CC)
Read 2 bytes # address 0x08080814 (Data = 0x4B15)
Read 4 bytes # address 0x0808086C (Data = 0x2002B994)
Read 2 bytes # address 0x08080814 (Data = 0x4B15)
Read 4 bytes # address 0x0808086C (Data = 0x2002B994)
Read 2 bytes # address 0x08080814 (Data = 0x4B15)
R0 = 00000000, R1 = 00000000, R2 = 00000000, R3 = 00000000
R4 = 00000000, R5 = 00000000, R6 = 00000000, R7 = 00000000
R8 = 00000000, R9 = 00000000, R10= 00000000, R11= 00000000
R12= 00000000, R13= 20080000, MSP= 20080000, PSP= 00000000
R14(LR) = FFFFFFFF, R15(PC) = 080023CC
XPSR 01000000, APSR 00000000, EPSR 01000000, IPSR 00000000
CFBP 00000000, CONTROL 00, FAULTMASK 00, BASEPRI 00, PRIMASK 00
Reading all registers
Read 4 bytes # address 0x080023CC (Data = 0xD034F8DF)
Read 2 bytes # address 0x080023CC (Data = 0xF8DF)
Setting breakpoint # address 0x0807BAAE, Size = 2, BPHandle = 0x0001
Setting breakpoint # address 0x0807BAFA, Size = 2, BPHandle = 0x0002
Setting breakpoint # address 0x0807BBB2, Size = 2, BPHandle = 0x0003
Setting breakpoint # address 0x08080814, Size = 2, BPHandle = 0x0004
Starting target CPU...
...Breakpoint reached # address 0x08080814
Reading all registers
Read 4 bytes # address 0x08080814 (Data = 0x68184B15)
Removing breakpoint # address 0x0807BAAE, Size = 2
Removing breakpoint # address 0x0807BAFA, Size = 2
Removing breakpoint # address 0x0807BBB2, Size = 2
Removing breakpoint # address 0x08080814, Size = 2
Reading 64 bytes # address 0x20003A40
Read 4 bytes # address 0x0802ED40 (Data = 0xB083B480)
Reading 64 bytes # address 0x200039C0
Read 4 bytes # address 0x0802ED40 (Data = 0xB083B480)
STLINK success debug
Open On-Chip Debugger 0.10.0-dev-00278-ga53935e-dirty (2017-05-09-09:25)
Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
srst_only separate srst_nogate srst_open_drain connect_assert_srst
Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD
adapter speed: 4000 kHz
adapter_nsrst_delay: 100
Info : clock speed 4000 kHz
Info : STLINK v2 JTAG v27 API v2 M v15 VID 0x0483 PID 0x374B
Info : using stlink api v2
Info : Target voltage: 0.023669
Error: target voltage may be too low for reliable debugging
Info : STM32F765VITx.cpu: hardware has 8 breakpoints, 4 watchpoints
Info : accepting 'gdb' connection on tcp/3333
STM32F765VITx.cpu: target state: halted
target halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0x080023cc msp: 0x20080000
Info : flash size probed value 2048
Info : flash size probed value 2048
STM32F765VITx.cpu: target state: halted
target halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0x080023cc msp: 0x20080000
STM32F765VITx.cpu: target state: halted
target halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0x080023cc msp: 0x20080000
Info : Padding image section 0 with 8 bytes
Info : Padding image section 1 with 24 bytes
STM32F765VITx.cpu: target state: halted
target halted due to breakpoint, current mode: Thread
xPSR: 0x61000000 pc: 0x20000084 msp: 0x20080000
Warn : keep_alive() was not invoked in the 1000ms timelimit. GDB alive packet not sent! (4290). Workaround: increase "set remotetimeout" in GDB
STM32F765VITx.cpu: target state: halted
target halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0x080023cc msp: 0x20080000
JLINK commander failed log
SEGGER J-Link Commander V6.16c (Compiled Jun 16 2017 18:15:26)
DLL version V6.16c, compiled Jun 16 2017 18:14:49
Connecting to J-Link via USB...O.K.
Firmware: J-Link V10 compiled Jun 16 2017 16:15:19
Hardware version: V10.10
S/N: 260101191
License(s): FlashBP, GDB
OEM: SEGGER-EDU
VTref = 3.348V
Type "connect" to establish a target connection, '?' for help
J-Link>connect
Please specify device / core. <Default>: STM32F765VI
Type '?' for selection dialog
Device>
Please specify target interface:
J) JTAG (Default)
S) SWD
TIF>s
Specify target interface speed [kHz]. <Default>: 4000 kHz
Speed>
Device "STM32F765VI" selected.
Connecting to target via SWD
Found SW-DP with ID 0x5BA02477
Found SW-DP with ID 0x5BA02477
Scanning APs, stopping at first AHB-AP found.
AP[0] IDR: 0x74770001 (AHB-AP)
AHB-AP ROM: 0xE00FD000 (Base addr. of first ROM table)
CPUID reg: 0x411FC270. Implementer code: 0x41 (ARM)
Found Cortex-M7 r1p0, Little endian.
FPUnit: 8 code (BP) slots and 0 literal slots
CoreSight components:
ROMTbl[0] # E00FD000
ROMTbl[0][0]: E00FE000, CID: B105100D, PID: 000BB4C8 ROM Table
ROMTbl[1] # E00FE000
ROMTbl[1][0]: E00FF000, CID: B105100D, PID: 000BB4C7 ROM Table
ROMTbl[2] # E00FF000
ROMTbl[2][0]: E000E000, CID: B105E00D, PID: 000BB00C SCS
ROMTbl[2][1]: E0001000, CID: B105E00D, PID: 000BB002 DWT
ROMTbl[2][2]: E0002000, CID: B105E00D, PID: 000BB00E FPB
ROMTbl[2][3]: E0000000, CID: B105E00D, PID: 000BB001 ITM
ROMTbl[1][1]: E0041000, CID: B105900D, PID: 001BB975 ETM-M7
ROMTbl[0][1]: E0040000, CID: B105900D, PID: 000BB9A9 TPIU-M7
Cache: Separate I- and D-cache.
I-Cache L1: 16 KB, 256 Sets, 32 Bytes/Line, 2-Way
D-Cache L1: 16 KB, 128 Sets, 32 Bytes/Line, 4-Way
Cortex-M7 identified.
J-Link>r
Reset delay: 0 ms
Reset type NORMAL: Resets core & peripherals via SYSRESETREQ & VECTRESET bit.
Setting AIRCR.SYSRESETREQ
J-Link>loadbin C:\Users\User\workspace_10\DC_Booster_F756\Debug\DC_Booster_F756.bin,0x08020000
Downloading file [C:\Users\User\workspace_10\DC_Booster_F756\Debug\DC_Booster_F756.bin]...
J-Link: Flash download: Flash programming performed for 2 ranges (131072 bytes)
J-Link: Flash download: Total time needed: 6.157s (Prepare: 0.022s, Compare: 0.081s, Erase: 4.931s, Program: 1.116s, Verify: 0.000s, Restore: 0.005s)
J-Link: Flash download: Restarting flash programming due to program error (possibly skipped erasure of half-way erased sector).
J-Link: Flash download: Skip optimizations disabled for second try.
Error while programming flash: Programming failed.
J-Link>verifybin C:\Users\User\workspace_10\DC_Booster_F756\Debug\DC_Booster_F756.bin,0x08020000
Loading binary file C:\Users\User\workspace_10\DC_Booster_F756\Debug\DC_Booster_F756.bin
Reading 546556 bytes data from target memory # 0x08020000.
Verify failed # address 0x08065522.
Expected FE read 00J-Link>

I reached over to the guys at Segger and they created a wiki page detailing how to resolve the issue. To make the Jlink aware of the Dual Bank config on STM32F7 devices, Jlink Open Flash loader must be used with custom script containing info of the Dual Bank config. Once that's done, the Jlink debugger has no problem when the program jumps from bootloader to main app. Here are the steps for getting Jlink to work with STM32F765VI operating in Dual Bank mode.
First off, use the latest version from 616f onwards
download and place the precompiled binary (ST STM32F7xxxx_2MB_DualBank.elf)from Jlink wiki to folder containing Jlink.exe and JLinkDevices.xml
edit JLinkDevices.xml to contain info related to the MCU and direct it to use the precompiled binary instead of the default one in Jlink. Add the following beneath the database tag at the start:
<!-- This entry will overwrite the existing device entry in the J-Link software, so that a custom flash algorithm is used for the internal flash -->
<Device>
<ChipInfo Vendor="ST" Name="STM32F765VI" Core="JLINK_CORE_CORTEX_M7" />
<FlashBankInfo Name="Internes Flash" BaseAddr="0x08000000" MaxSize="0x00200000 " Loader="ST_STM32F7xxxx_2MB_DualBank.elf" LoaderType="FLASH_ALGO_TYPE_OPEN" />
</Device>
If you have multiple versions of Jlink installed, make sure you're using the one which has its JLinkDevices.xml edited to use the precompiled binary in your debugging session.

According to the first log it seems to me that J-Link erases the flash and then programs it from address 0x08020000 on -> no bootloader and nothing to execute at 0x08000000 -> jumps right to hardFault (although no handler is found in the vector table and the CPU locks up). I'm not an expert of J-Link, but we use it in a similar toolchain, with the following scenarios:
the BSL and the application binaries are combined using a simple tool and flashed together by J-Link. Either one can be debugged afterwards by connecting to the running target.
BSL is excluded and substituted by a 'stub' only doing the jump to the application
Both work flawlessly.

Related

ESP IDF: Task never leaves vTaskDelay()

I am building a system that creates a WLAN AP over which the end user can Connect/disconnect the ESP to another AP ( For example a router) by posting a JSON String to a URL. In APSTA mode. When this is done a bool "_STA_START" is set to true. And the login parameters are saved in _STA_WIFI_SSID and _STA_WIFI_PASS.
I encounter a problem when writing the Task that manages the esp as Station. When the vTaskDelay() is called the code in the vTask_Manage_STA_Connection() just stops running. If I delete the statement. The code runs very fast until it casues a stack overflow and resets the esp.
start_Manage_STA_Connection() is called in main.c after I initialise the esp as Access Point.
Right now I see on the monitor that the loop in the vTask_Manage_STA_Connection runs a single time.
Below you can find my Tasks.c and Task.h
Task.h
#ifndef INCLUDE
#define INCLUDE
#include "config.h"
#endif
#ifndef INCLUDE_WLAN_STA
#define INCLUDE_WLAN_STA
#include "WLAN_STA.h"
#endif
// Dimensions the buffer that the task being created will use as its stack.
// NOTE: This is the number of words the stack will hold, not the number of
// bytes. For example, if each stack item is 32-bits, and this is set to 100,
// then 400 bytes (100 * 32-bits) will be allocated.
#define STACK_SIZE 2048
/// #brief Starts a Task to Manage the STA Connection
/// #param pvParameters
void vTask_Manage_STA_Connection( void * pvParameters );
/// #brief Calls vTask_Manage_STA_Connection in main.c
/// #param
void start_Manage_STA_Connection( void );
Tasks.c
#include "Tasks.h"
static const char *TAG_Manage_STA = "Manage STA Connection";
// Task to be created.
void vTask_Manage_STA_Connection(void *pvParameters)
{
for (;;)
{
// Task code goes here.
if (_STA_START == true)
{
ESP_LOGI(TAG_Manage_STA, "Connecting to Station...");
wifi_init_sta(
_STA_WIFI_SSID,
_STA_WIFI_PASS);
_STA_START = false;
}
ESP_LOGI(TAG_Manage_STA, "Managing STA Connection...");
vTaskDelay(100/portTICK_PERIOD_MS);
}
}
// Function that creates a task.
void start_Manage_STA_Connection(void)
{
static uint8_t ucParameterToPass;
TaskHandle_t xHandle = NULL;
// Create the task pinned to core 0, storing the handle. Note that the passed parameter ucParameterToPass
// must exist for the lifetime of the task, so in this case is declared static. If it was just an
// an automatic stack variable it might no longer exist, or at least have been corrupted, by the time
// the new task attempts to access it.
xTaskCreatePinnedToCore(vTask_Manage_STA_Connection,
"Manage_STA_Connection",
STACK_SIZE,
&ucParameterToPass,
(configMAX_PRIORITIES-1),
&xHandle, 0);
configASSERT(xHandle);
// Use the handle to delete the task.
if (xHandle != NULL)
{
vTaskDelete(xHandle);
}
}
The Monitor Output:
I (0) cpu_start: App cpu up.
I (388) cpu_start: Pro cpu start user code
I (388) cpu_start: cpu freq: 160000000
I (388) cpu_start: Application information:
I (392) cpu_start: Project name: wifi_softAP
I (398) cpu_start: App version: 1
I (402) cpu_start: Compile time: Dec 5 2022 11:50:36
I (408) cpu_start: ELF file SHA256: 3597702b82953470...
I (414) cpu_start: ESP-IDF: v4.4.2
I (419) heap_init: Initializing. RAM available for dynamic allocation:
I (426) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM
I (432) heap_init: At 3FFB7508 len 00028AF8 (162 KiB): DRAM
I (438) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM
I (445) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
I (451) heap_init: At 400944E0 len 0000BB20 (46 KiB): IRAM
I (459) spi_flash: detected chip: gd
I (462) spi_flash: flash io: dio
I (467) cpu_start: Starting scheduler on PRO CPU.
I (0) cpu_start: Starting scheduler on APP CPU.
I (559) MAIN: ESP_WIFI_MODE_AP/STA
I (569) WLAN AP: Wifi Loop Started
I (579) wifi:wifi driver task: 3ffc0378, prio:23, stack:6656, core=0
I (579) system_api: Base MAC address is not set
I (579) system_api: read default base MAC address from EFUSE
I (609) wifi:wifi firmware version: eeaa27d
I (609) wifi:wifi certification version: v7.0
I (609) wifi:config NVS flash: enabled
I (609) wifi:config nano formating: disabled
I (609) wifi:Init data frame dynamic rx buffer num: 32
I (619) wifi:Init management frame dynamic rx buffer num: 32
I (619) wifi:Init management short buffer num: 32
I (629) wifi:Init dynamic tx buffer num: 32
I (629) wifi:Init static rx buffer size: 1600
I (629) wifi:Init static rx buffer num: 10
I (639) wifi:Init dynamic rx buffer num: 32
I (639) wifi_init: rx ba win: 6
I (649) wifi_init: tcpip mbox: 32
I (649) wifi_init: udp mbox: 6
I (649) wifi_init: tcp mbox: 6
I (659) wifi_init: tcp tx win: 5744
I (659) wifi_init: tcp rx win: 5744
I (669) wifi_init: tcp mss: 1440
I (669) wifi_init: WiFi IRAM OP enabled
I (669) wifi_init: WiFi RX IRAM OP enabled
I (689) phy_init: phy_version 4670,719f9f6,Feb 18 2021,17:07:07
I (789) wifi:mode : sta (30:ae:a4:80:4e:88) + softAP (30:ae:a4:80:4e:89)
I (789) wifi:enable tsf
I (789) wifi:Total power save buffer number: 16
I (789) wifi:Init max length of beacon: 752/752
I (789) wifi:Init max length of beacon: 752/752
I (799) WLAN AP: Error: Unknown AP Exception
I (799) WLAN AP: wifi_init_softap finished. SSID:myssid password:mypassword channel:4
I (799) WLAN AP: Access point started!
I (819) Manage STA Connection: Managing STA Connection...
I (91529) wifi:new:<1,1>, old:<1,1>, ap:<1,1>, sta:<0,0>, prof:1
I (91529) wifi:station: 1c:bf:ce:ca:79:de join, AID=1, bgn, 40U
I (91549) WLAN AP: station 1c:bf:ce:ca:79:de join, AID=1
I (91559) esp_netif_lwip: DHCP server assigned IP to a station, IP is: 192.168.5.2
I (91559) AP Webserver: Starting webserver
I (91559) AP Webserver: Starting server on port: '80'
I (91569) AP Webserver: Registering URI handlers
W (95189) wifi:<ba-add>idx:2 (ifx:1, 1c:bf:ce:ca:79:de), tid:0, ssn:190, winSize:64

In-Application Program jump from user bootloader to user application and viceversa on STM32F446RE board

I've got a question.
I'm developing an IAP (In-Application Programming) tool for my STM32F446RE board and I'm stuck.
I've developed all the necessary utilities in order to let to the microcontroller to receive a binary (.bin) compiled file from a GUI, write it on a specific flash memory sector and execute it.
My problem comes when, from the uploaded code, I want to jump again to the bootloader that is stored on the flash memory sector 0, I see that the code does not jump to the bootloader but, instead, it continues the execution of the user application code. I've debugged the code and I seen that all the addresses (the msp and the reset handler) of the bootloader code are correctly set and they are different compared to the ones of the uploaded code.
The flow that i want to achieve is the following:
1 --> Execute the bootloader code stored on sector 0 (starting at address 0x0800 0000, when an interrupt from the User button is received) and write the newly received code into the sector 2 (starting at address 0x0800 8000)
2 --> set the msp address (#0x0800 8000) and the reset handler address (0x0800 8004)
3 --> jump to the reset handler address of the new code (#0x0800 8004)
4 --> execute the new uploaded code.
5 --> during the user code execution, if an interrupt is received (from user push button) then set the bootloader msp address, the reset handler and jump to the bootloader
6 --> repeat again from step one.
This is the code used to jump from the bootloader to the user application:
IAP_loadProgram(&data);
//pointer to the user application reset handler address
void (*user_resetHandler)(void);
//set the user application MSP address (user application starts on the flash SECTOR2
uint32_t msp_addr = *(volatile uint32_t *)APPLICATION_ADDRESS;
__set_MSP(msp_addr);
//Set now the addres of the reset handler
uint32_t resetAddr = *(volatile uint32_t *)(APPLICATION_ADDRESS + 4);
user_resetHandler = (void *)resetAddr;
//When there, the bootloader sector will be leaved and the user code execution starts
user_resetHandler();
Finally, the code used to jump from the user application code to the bootloader is:
if(toBootloader){
toBootloader = 0;
//pointer to the user application reset handler address
void (*bootLoader_resetHandler)(void);
//set the user application MSP address (user application starts on the flash SECTOR2
uint32_t msp_addr = *(volatile uint32_t *)BOOTLOADER_ADDRESS;
__set_MSP(msp_addr);
//Set now the address of the reset handler
uint32_t bootLoaderResetAddr = *(volatile uint32_t *)(BOOTLOADER_ADDRESS + 4);
bootLoader_resetHandler = (void *)bootLoaderResetAddr;
//When there, the user code sector will be leaved and the bootloader code execution starts
bootLoader_resetHandler();
}
Where APPLICATION_ADDRESS is 0x0800 8000 and BOOTLOADER_ADDRESS is 0x0800 0000.
The content of the first two addresses of the bootloader code is:
0x08000000: 20020000
0x08000004: 080044DD
meanwhile the content of the first two addresses of the application code is:
0x08008000: 20020000
0x08008004: 0800A1F1
Last modify that i've done is on the user application linker (.ld) file, where i set the flash start to the address 0x0800 8000 (instead of the address 0x0800 0000).
All the interrupts are correctly working and, after that the code has been uploaded, if I do a hardware reset, the result is the same, the code execution starts from the user application code, not from the bootloader.
Any tips?
Your problem description is unclear but the procedure of invoking the app is far not sufficient. You need to make sure that the environment for the application is same as after the uC reset. You need to change the vector table address as well.
I wrote tens of bootloaders but I do not understrand your problem
Here you have an example how it should be done (app call from bootloader)
void startAPP(void)
{
static uint32_t *pAppPosition;
static voidFunc *appResetHandler;
static uint32_t newSP;
pAppPosition = (uint32_t *)(bankStartAddress[0] + (uint32_t)&_BOOTFlashSize);
appResetHandler = (voidFunc *)pAppPosition[1];
newSP = pAppPosition[0];
SPI_DeInit();
FLASH_DeInit();
I2C_DeInit();
IRQ_DeInit();
GPIO_DeInit();
__disable_irq();
__set_MSP(newSP);
__enable_irq();
SCB -> ICSR = 0x00000000; // reset value;
SCB -> SCR = 0;
SCB -> CCR = 0x00000200; // reset value
SCB -> SHP[0] = 0;
SCB -> SHCSR = 0;
SCB -> CFSR = (SCB_CFSR_DIVBYZERO_Msk | SCB_CFSR_UNALIGNED_Msk | SCB_CFSR_UNDEFINSTR_Msk | SCB_CFSR_NOCP_Msk | SCB_CFSR_INVPC_Msk | SCB_CFSR_INVSTATE_Msk);
SCB -> HFSR = (SCB_HFSR_DEBUGEVT_Msk | SCB_HFSR_FORCED_Msk | SCB_HFSR_VECTTBL_Msk);
SCB -> VTOR = bankStartAddress[0] + (uint32_t)&_BOOTFlashSize; // new vector table pos. I od not clear 8 LSB because APP start position is aligned to FLASH Sectors which are at least 2k aligned
// SysTick
SysTick -> CTRL = 0;
SysTick -> LOAD = 0;
SysTick -> VAL = 0;
appResetHandler();
__builtin_unreachable();
}
The simplest and safest method of running the bootloader from the application is simply to issue a soft reset using the CMSIS NVIC_SystemReset() function.
if( toBootloader )
{
NVIC_SystemReset() ;
}
Jumping to the bootloader by a direct call is unnecessary and ill-advised. While it can be done, just as you can jump from the bootloader to the application, you need to at least disable interrupts/exceptions and switch the vector table from that of the application to that of the bootloader. Neither your application code nor bootloader code appear to be doing that. See ARM: How to Write a Bootloader for example.
Issuing a reset has the advantage of setting the processor and all on-chip peripherals and I/O into their known reset state so you do not need to worry about de-initialising the NVIC, or any peripherals that might generate an interrupt while you are switching vector tables.
If you need to communicate information to the bootloader from the application the state of the on-chip SRAM will survive the reset process, so you can reserve space that the run-time start-up will not initialise to pass parameters to the bootloader if you need to.

How to debug TF-A on ARM Cortex-A7

I'm trying a custom image for ARM STM32MP151A on a custom board. On power up nothing happens on the tty port (while using a wrong sd-card leads to a PANIC PC error - hence the port is ok). As far as I understand in the early stages of power up sequence, the ROM code should load the FSBL from the dedicated partition. Because the boot type is "trusted" that partition is filled with the TF-A firmware:
#Opt Id Name Type IP Offset Binary
- 0x01 fsbl1-boot Binary none 0x0 tf-a-stm32mp151a-myproject-mx-trusted.stm32
- 0x03 ssbl-boot Binary none 0x0 u-boot-stm32mp151a-myproject-mx-trusted.stm32
P 0x04 fsbl1 Binary mmc0 0x00004400 tf-a-stm32mp151a-myproject-mx-trusted.stm32
P 0x05 fsbl2 Binary mmc0 0x00044400 tf-a-stm32mp151a-myproject-mx-trusted.stm32
P 0x06 ssbl Binary mmc0 0x00084400 u-boot-stm32mp151a-myproject-mx-trusted.stm32
P 0x21 bootfs System mmc0 0x00284400 st-image-bootfs-openstlinux-eglfs-stm32mp1-myproject.ext4
P 0x22 vendorfs FileSystem mmc0 0x04284400 st-image-vendorfs-openstlinux-eglfs-stm32mp1-myproject.ext4
P 0x23 rootfs FileSystem mmc0 0x05284400 myproject-image-openstlinux-eglfs-stm32mp1-myproject.ext4
P 0x24 userfs FileSystem mmc0 0x4E664400 st-image-userfs-openstlinux-eglfs-stm32mp1-myproject.ext4
The question is: how to debug the very first stages of the boot sequence of an ARM-A7 if there's no output on the tty console port?

Use U-boot to change a bit in NAND flash memory

I am trying to test the ECC (error correction code) in U-boot. To do so, I want to use U-boot to flip a bit in NAND flash without rewriting the CRC. Then, when I restart the processor, I hope to see U-boot correct the bit using ECC.
The question is how can I write a new bit or byte or page into memory using U-boot without writing a new CRC?
Never found a u-boot with the bitterr implementation, the source code usually looks like this:
if (strcmp(cmd, "biterr") == 0) {
/* todo */
return 1;
}
In this case, the way to go is little more complicate. As it took me some time to discover how to do it, I believe it may be helpful for other to have the manual process described here.
nand read ${ram_addr1} ${sector_addr} ${sector_size}
nand read.oob ${ram_addr2} ${sector_addr} ${oob_size}
nand erase ${sector_addr} ${sector_size}
nand write ${ram_addr1} ${sector_addr_plus_page_size} ${sector_size_minus_page_size}
cp ${ram_addr2} ${ram_addr1} ${oob_size}
mm ${ram_addr1_plus_biterr_offset}
#modify a single bit of the referred data
nand write.raw ${ram_addr1} ${sector_addr} 1
Check if you get a bitflip err message:
nand read ${ram_addr1} ${sector_addr} ${sector_size}
Note that you may set the environment to run this command as is, or replace the ${} directives for the raw values. ram_addr1 and ram_addr2 may be any available ram adrress as long as ram_addr2 - ram_addr1 > sector_size
Use nand biterr to simulate a bit flipping at an offset.
For example, bit 3 in byte 69 [0x45] in the 2nd block = 0x20000
U-Boot> nand biterr 0x20045 3
Erasing at 0x20000 -- 100% complete.
toggling bit 3 in byte 45 in block 20000 00 ->08
byte offset 0x00020045 toggled bit 3
Reference:
http://www.infopoort.nl/index.php/Software:U-Boot
You can use nand read.raw and nand write.raw which by passes the writing to the OOB.
To simplify #Jonatan-Goebel answer, you can avoid a lot of the steps as long as you only clear bits, as this won't require erasing the nand.
=> setenv ram_addr1 $loadaddr
=> setenv page_addr 0
=> setenv page_size 1000
# Make sure there is actually something in nand
=> nand erase.chip && mw.b $loadaddr ff 40000 && load mmc 0 $loadaddr MLO && nand write.i $loadaddr $page_addr $filesize
# Read one raw page
=> nand read.raw ${ram_addr1} ${page_addr} 1
# Clear x number of bits
=> mm $ram_addr1
83000000: 00000040 ?
...
83000018: 4e495454 ?
8300001c: 00005347 ?
83000020: ffffffff ? efffffff
83000024: ffffffff ? => <INTERRUPT>
# Write back page
=> nand write.raw ${ram_addr1} ${page_addr} 1
# Read the page
=> nand read ${ram_addr1} ${page_addr} ${page_size}
NAND read: device 0 offset 0x0, size 0x40000
elm_config: 2
nand: bit-flip corrected #data=35
262144 bytes read: OK
Make sure you try again with too many bitflips to make sure it fails
...
=> mm $ram_addr1
...
83000020: cccccccc ? 8ccccccc
83000024: ffffffff ? => <INTERRUPT>
=> nand write.raw ${ram_addr1} ${page_addr} 1
NAND write: 4320 bytes written: OK
=> nand read ${ram_addr1} ${page_addr} ${page_size}
NAND read: device 0 offset 0x0, size 0x40000
elm_config: 2
omap-elm: uncorrectable ECC errors
NAND read from offset 0 failed -74
0 bytes read: ERROR

LPC1768 load application to new memory offset

Question: - how to locate application to non 0x0000.0000 address?
Processor: NXP LPC1768
Dev system: Keil ARM 4.73
Steps used:
1) scatter file below used to set load region and execution region to 0x0000.2000
2) copied vector table to 0x2000
3) udpated vtor register to 0x2000
Problem: Application does not run.
Scatter file used:
LR_IROM1 0x00002000 0x00000D000
{ ; load region size_region
ER_IROM1 0x00002000 0x0000D000
{ ; load address = execution address
*.o (RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
}
RW_IRAM1 0x10000000 0x00008000 { ; RW data
.ANY (+RW +ZI)
}
}
This follows instructions specified in NXP app note AN10744, something else I’m missing?
Vector Table Offset Register (VTOR) points to 0x00000000 at reset.
Thus, stack pointer must be at 0x00000000, and program start address (program counter) at 0x00000004.
If you change the location of the vector table in linker settings, you need to update VTOR to point to this new location. This can only happen at runtime.
This means that you need to have a small bootloader program which does the remapping, which means that first sector must be reserved for that purpose.
Bootloader needs to:
Make sure that interrupts are disabled, so you don't accidentally use VTOR.
Update VTOR register to address 0x2000.
Get stack pointer address from 0x2000 and update stack pointer register.
Get program start address from 0x2004 and update the program counter.
You might want to check out CMSIS library, it has functions like NVIC_SetVTOR and __set_MSP which make setting these registers a little easier.
To set the program counter, you can cast the address to function pointer and then call the function:
uint32_t * vtor = (uint32_t *)0x2000;
uint32_t startAddr = vtor[1];
( (void(*)(void))startAddr )(); // Cast and call

Resources