cancel
Showing results for 
Search instead for 
Did you mean: 

How to download firmware/bootloader to custom boards with STM32F479NIH6 and debug?

Kosta1
Associate II

TL:DR; New to firmware development. Inherited codebase for new revision of product. Sole firmware developer. Cannot step through code. Seeking advice.

---------------------

So I am fairly new to firmware development in a new company where I inherited this codebase that is to be used for a new product. Previously, TrueStudio 9.x.y was used for the previous generation product last year.

I am the sole firmware developer in a small company. I had 2 weeks with the previous firmware engineer before they left. They did their best to transfer as much knowledge as possible, but not everything could be covered in that time-frame. My background is Cypress FX3 firmware development and kernel device drivers.

The codebase seems to have bootloader and application code mixed together. First, is this a common practice, as I see these as separate functions. The bootloader, per my understanding, is to configure the STM32 to load and run the application.

I build the application and bootloader, and when I attempt to download/debug the bootloader with a breakpoint set immediately in main,

TrueStudio 9.3.0 with an ST-Link v2 is used to connect to the custom board. I am building a debug/non-optimized code, which I download via the ST-LinkV2. The Console window output I receive starts with the below, with the crash (?) shown afterwards.

So the question I have is, of which settings do I need to be most careful? Is there something obvious I am missing due to my lack of expertise? Given that the environment is for a shipped product that did work, should I still stick with TrueStudio, or make the change to STM32CubeIDE (I did play around to it, but saw that the conversion of the project to that new IDE is nontrivial).

And is there a way to pay for support from ST, now that TrueStudio Pro is no longer available?

Thank you for reading.

Kosta

And now the initial output:

STMicroelectronics ST-LINK GDB server. Version 5.1.0

Copyright (c) 2018, STMicroelectronics. All rights reserved.

Starting server with the following options:

    Persistent Mode      : Disabled

    Logging Level       : 1

    Listen Port Number     : 61234

    Status Refresh Delay    : 15s

    Verbose Mode        : Disabled

    SWD Debug         : Enabled

Waiting for debugger connection...

Debugger connected

   -------------------------------------------------------------------

            STM32CubeProgrammer v1.3.0          

   -------------------------------------------------------------------

Log output file:  C:\Users\Kosta\AppData\Local\Temp\STM32CubeProgrammer_a04312.log

ST-LINK SN : 48FF6E064967535721350887

ST-LINK FW : V2J35S7

Voltage   : 3.19V

SWD freq  : 4000 KHz

Connect mode: Under Reset

Reset mode : Hardware reset

Device ID  : 0x434

Device name : STM32F469xx/F467xx

Device type : MCU

Device CPU : Cortex-M4

Memory Programming ...

Opening and parsing file: C:\Users\Kosta\AppData\Local\Temp\ST-LINK_GDB_server_a04312.srec

 File     : C:\Users\Kosta\AppData\Local\Temp\ST-LINK_GDB_server_a04312.srec

 Size     : 162084 Bytes

 Address    : 0x08040000 

Erasing memory corresponding to segment 0:

Erasing internal memory sectors [6 7]

Download in Progress:

File download complete

Time elapsed during download operation: 00:00:03.894

Verifying ...

Download verified successfully 

Then after a moment I get the following output in the Console window:

Program received signal 

SIGINT, Interrupt.

0x08007506 in ?? ()

Stopping the session, I see the following appended to the Console window in the first section:

Debugger connection lost.

Shutting down...

7 REPLIES 7

If you have an idle loop with a __WFI (Wait For Interrupt) it will power down the debug interface.

Get a serial port working so you can understand behaviour beyond the debugger.

Check the .MAP and .LST files with respect to the failure address being reported.

>>The codebase seems to have bootloader and application code mixed together. First, is this a common practice,..

I usually keep things separate. A "workspace" might have multiple sub-projects or build options, and these might share a common/similar code base.

The main() function can be quite deep, turn off "Run to main()" options, and step from Reset_Handler on in.

SystemInit() can initialize a lot of clocks and external memory subsystems, this is usually done before the startup.s code unpacks and clears the static allocations.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

>>And is there a way to pay for support from ST, now that TrueStudio Pro is no longer available?

Not aware they have a model for that. They keep a list of contractors/consultants.

I don't particularly care for the Atollic / TrueStudio / Eclipse / CubeIDE environments.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

What is your preferred IDE? Given my lack of expertise, I'm a bit concerned as to switching environments, given that this environment was used successfully in the past. I'm just missing something basic. But as my knowledge grows, I'm open to change.

I have a preference for Keil, and when using GNU/GCC I use MAKE.

IDE's are mostly about personal preference, or business mandate, what works for me doesn't necessarily translate well to others.

Here you just sound like you're crashing early, so something in the startup code might be dumping the debug interface, either explicitly attempting to disable it, or interfering with the pins it uses, or turning off power to the interface.

Breakpointing main() is evidently too later, so you need to move earlier. I'd usually do this via code inspection and code walking, but absent that level of insight into the code, I'd step in from here the CPU starts executing.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

Is there a way to set a breakpoint at an address? I'm able to set breakpoints at source code lines. I know how to do this in windbg, but this is a new world for me.

Setting a breakpoint in the .s file for Reset_Handler and the call to SystemInit results in basically a hang where there is what was provided in my first post up until "Download verified successfully"

Looking at the .list file I see the following around the address 8007506:

 tmpccer |= sConfig->IC1Polarity | (sConfig->IC2Polarity << 4U);

 8007500: 683b    ldr r3, [r7, #0]

 8007502: 685a    ldr r2, [r3, #4]

 8007504: 683b    ldr r3, [r7, #0]

 8007506: 695b    ldr r3, [r3, #20]

 8007508: 011b    lsls r3, r3, #4

 800750a: 4313    orrs r3, r2

 800750c: 68fa    ldr r2, [r7, #12]

 800750e: 4313    orrs r3, r2

 8007510: 60fb    str r3, [r7, #12]

From the .map file:

 .text.Reset_Handler

        0x0800907c    0x50 HALUtils\startup_stm32f479xx.o

        0x0800907c        Reset_Handler

Code starts at 0x0800'0000, so if you load code from 0x0800'4000 there's already something at that lower portion of memory, probably the bootloader, which may not pass control to the upper code's startup code and then main() as you expect. Or, your problem may be, that the bootloader is *not* there (just FFs). That might perhaps be the reason it won't get to the bootloader's main, or even its startup code or that it behaves there unexpectedly.

I loathe the eclipsoids so have no idea how is it in atollic's version of it, but in normal IDEs you set breakpoint and step through binary code in the disassembly window.

I'd also start with getting familiar with the environment, whatever it is, by writing a basic blinky; without the bootloader first, and then adding the boodloader. Small steps at a time. Trow out any ranting bean-counting superior through door or window, of your choice; firm grip on the tools is an absolute necessity.

Then, can't you start with reproducing the known working binary? You've surely shown how to achieve that by your predecessor?

And an unwanted advice, forget soon about using a different compiler setting for debugging, unless you're debugging an algorithmic problem,

JW

Thanks. Yes, I did note that in the .ld file for the bootloader, I have the following:

/* Specify the memory areas */

MEMORY

{

RAM (xrw)   : ORIGIN = 0x20000000, LENGTH = 320K

CCMRAM (rw)   : ORIGIN = 0x10000000, LENGTH = 64K

FLASH (rx)   : ORIGIN = 0x8000000, LENGTH = 256K

}

and for the application code:

MEMORY

{

RAM (xrw)   : ORIGIN = 0x20000000, LENGTH = 320K

CCMRAM (rw)   : ORIGIN = 0x10000000, LENGTH = 64K

FLASH (rx)   : ORIGIN = 0x8040000, LENGTH = 512K

}

Good advice on the getting familiar. In different tools/environments, my knowledge/expertise in tools makes things quick. While the concepts translate, the rest does not. I'll ping ST about which eval or development board they'd recommend as I'm using an STM32F479NIH6.