cancel
Showing results for 
Search instead for 
Did you mean: 

Code compiled as Release behaves different than Debug code

martin.k
Associate II
Posted on December 16, 2016 at 20:15

Hello experts.

Currently I experience a very strange problem with my firmware for a STM32F334.

I just switched from the debug configuration to release, uploaded the code to the device and it behaves totally different.

First of all being programmed with St-Link it does not start at all. If I program the device by the debug environment it starts, but does not work correct. To name it exactly, there is a timer for frequency measurement counting on an external clock. The data is collected by a DMA channel with a samling rate of 5 kHz. This fails at some point (not sure where) and a security mechanism is triggered.

I use a modified linker script and a modified startup file since I have initialized data in CCMRAM. Please find the files attached. Thus, I also use a different objcopy command to create the binary image for the flash memory:

arm-none-eabi-objcopy -R .data -R .ccmram -R .ccmidata -R .bss -O binary '${BuildArtifactFileBaseName}.elf' '${BuildArtifactFileBaseName}.bin'

The pehripheral initialization is the same for release or debug firmwares. I have the same optimization level for both as well. But, there are no debugging symbols in the release firmware. Because of this and because I do not expect different hardware timinigs with a connected debugger, there is probably something wrong with the linker script, the startup code or the objcopy command.

I'm not sure what information I can proivde in addition... Please ask if there is any.

My platform is Eclipse with SW4 and I do use the StdPeriph library and the arm-math library (but not in precompiled form).

Best regards,

Martin.

9 REPLIES 9
Posted on December 17, 2016 at 03:02

Is this your own board? Make sure BOOT0 is pulled low.

Check that your code initializes all clocks and pins, the debugger may enable things within the chip to serve it's own needs.

Use a USART to output diagnostic and progress information in the absence of the debugger. If necessary output register content in the two cases to understand what is different.

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
Posted on December 17, 2016 at 17:38

If code stopped to behave expectedly when you switched from debug to release, what exactly were the changes, what are the differences between debug and release?

Did those linker script and startup change? If yes, can you post both versions, working and non-working?

Anything else?

JW

martin.k
Associate II
Posted on December 18, 2016 at 12:38

The original post was too long to process during our migration. Please click on the provided URL to read the original post. https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006I6n5&d=%2Fa%2F0X0000000bvW%2FM_giNd36YLlU70tRlK.on_7gk6ajalMZybBKP8x38p0&asPdf=false
Posted on December 19, 2016 at 17:23

The .BIN and .ELF might shed some more light on the alternate behaviours. You'd really need to go over the CCM initialization, and make sure the .BIN only describes data in FLASH

Be aware the Period is specified as an N-1 number, ie the last value prior to reset. So here 36000-1 assuming a 36 MHz clock, although I'd expect the clock to be 72 MHz as in the DIV2 case for APB1, the TIMCLK is DIV1, so is twice the APB clock. As 72000-1 doesn't fit in 16-bit, you'd set Prescaler = 2-1; Period = 36000-1;

TIM_TimeBaseInitStruct.TIM_Period = 36000; // 1 kHz

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
martin.k
Associate II
Posted on December 29, 2016 at 12:00

Hi.

I made some changes on the code and now I have (at least) a consistent behaviour. I made the DMA buffer where the timer stores it's data 'double buffered'. So I can work on one part of the buffer, while the other part is already filled with new data. Thus, I have correct operation with debug and release firmware if the debugger is connected.

If I detach the debugger, the values in the buffer are smaller. Which means the TIM3 is either clocked with a slower external clock, which would be really weird, or the TIM1 runs faster and leads to a faster sampling rate of the TIM3 counter.

It seems there is indeed something missing in my initialization, because it still works if I simply disconnect the debugger. But, it does not count correct if I boot the device without the debugger.

Any idea?

Best regards,

Martin.

Posted on December 29, 2016 at 15:01

Hi.

Now I found the cause of the problem. It is not the timer operating incorrectly, but a GPIO output which enables the DC power supply in the device. The voltage level on that pin is around 0,8V while it should be at a high level.

The pin is configured as output in push-pull mode an has an external pull down. The questionable GPIO is PB9.

I'm not yet sure why this happens, but it must be another peripheral taking over the control of the pin. But still, I think it is very weird it only happens if I electrically disconnect the debugger.

Active peripherals which are related to PB9 are I2C1, DAC1,2 and HRTIM1, but none of them are configured to use the IO. What about the EVENTOUT function? Could it be the reason?

Best regards,

Martin.

Posted on December 29, 2016 at 16:32

The debugger configures pins/peripherals/clocks to suit it's needs. Most functionality is achieved through normal bus activity, not some magic backdoor access methods. The DBGMCU peripheral can stop clocks etc, so they don't keep firing while it dead-stops in the debugger waiting for your keystrokes.

Dump out related RCC and GPIO registers via a serial port to see what comes up differently. Most likely the GPIOB clock in your case.

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
Posted on December 29, 2016 at 19:07

Good hint. I actually found out that the output type configuration for PORTB is different with a connected debugger. This includes that pin (PB9), which is not configured as Push-Pull, but as a open-drain output without the debugger.

I do check the whole PORTB configuration currently.

Posted on December 29, 2016 at 19:26

I just found it. There was some old code left which changed the configuration of some IO pins on PORTB into AF mode and assigned it to the HRTIM. But, I had the same input pins connected to the EXTI controller. I'm not sure how this affected the output mode of PB9. However, I have removed that code and it works now.

Best regards,

Martin.