Release vs. Debug difference while writing to flash K64

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Release vs. Debug difference while writing to flash K64

Jump to solution
1,218 Views
roymessinger
Contributor V

This question is intended for BlackNight‌, or whoever else can help. I'm writing this question in continuous to my post here. I've used the nice document Erich has written regarding using _attribute_ to write to specific address in flash.

Maybe I'm missing something here but I've noticed there's a difference between Debug and Release when writing to the flash (in the freedom_bootloader source code).

In Release version, the appFlag I've written is (I think) optimized and vanished, while in Debug version it is well written to the address I've specified (0x20020000).

I've used the arm-none-eabi-nm.exe to look for my appFlash flag and I've seen differences between the Rls & Dbg versions:

In the Rls version:

20020000 d appFlag.4961
w atexit
In the Dbg version:

20020000 D appFlag
w atexit

I do not know what is the difference between the d and D (or the .4961 numbers mean).

Furthermore, in the map files I'm seeing these differences also:

In the Rls version:

.appFlag 0x20020000 0x1 C:\...\AppData\Local\Temp\ccRzaGIi.ltrans1.ltrans.o

In the Dbg version:

.appFlag 0x20020000 0x1 C:\...\AppData\Local\Temp\ccXjJvWa.ltrans0.ltrans.o
0x20020000 appFlag

Obviously, something is making this flag to disappear in the Release version, and that is why in my post here , the 'if' in line 367 is ignored.

This was not mentioned in Erich's doc. Have I done something wrong when using the _attribute_ method?

Any help will do.

Thanks!

Roy

1 Solution
779 Views
BlackNight
NXP Employee
NXP Employee

Hi Roy,

yes, I used

volatile unsigned char __attribute__((section (".appFlag"))) appFlag = 0x55;

What I did is to initialize the variable fully/properly from my code. I did this with

static void Init(void) {
  appFlag = 0x55;
}

and called it from the beginning of main().

Erich

View solution in original post

9 Replies
779 Views
roymessinger
Contributor V

Ok, Erich, finally, all is working well.

Thank you very much.

I will post a method which ties all loose ends for jumping from app to bootloader which concludes all my findings....

Roy

0 Kudos
779 Views
BlackNight
NXP Employee
NXP Employee

Hi Roy,

about the difference between 'd' and 'D', see nm - GNU Binary Utilities :

" If lowercase, the symbol is usually local; if uppercase, the symbol is global (external)."

Erich

0 Kudos
779 Views
BlackNight
NXP Employee
NXP Employee

Hi Roy,

>>I do not know what is the difference between the d and D (or the .4961 numbers mean).

I wrote about 'd' and 'D' above. Basically for 'd' it is like if the variable is static (not external), while with 'D' it globally visible.

The number .4961 is an internal symbol numbering of the linker to avoid naming conflicts.

Erich

0 Kudos
779 Views
BlackNight
NXP Employee
NXP Employee

Hi Roy,

About your problem: I did not had the time to reproduce your problem.

In that link you say you wrote it as:

unsigned char __attribute__((section (".appFlag"))) appFlag = 0x55; 

Depending on what the compiler and linker can see, it might optimize that variable (and using 0x55 instead).

I recommend that you mark it as volatile like this:

volatile unsigned char __attribute__((section (".appFlag"))) appFlag = 0x55; 

I hope this helps,

Erich

0 Kudos
779 Views
roymessinger
Contributor V

Thanks BlackNight‌,

I tried using volatile or/and static (as @Alice_Yang) suggested, but same problem.

I'm doing the simplest thing in bl_main.c (tried also in my app code):

volatile unsigned char __attribute__((section (".appFlag"))) appFlag = 0x55; //by Roy M.

int main(void)
{
BOARD_InitLEDs();

if (appFlag == 0x55)
{
redLedOn(); //function to light red led
}

...

In linker file:

/* Specify the memory areas */
MEMORY
{
m_interrupts (RX) : ORIGIN = 0x00000000, LENGTH = 0x00000400
m_flash_config (RX) : ORIGIN = 0x00000400, LENGTH = 0x00000010
m_text (RX) : ORIGIN = 0x00000410, LENGTH = 0x000FFBF0
m_data (RW) : ORIGIN = 0x1FFF0000, LENGTH = 0x00040000
m_data_20020000 (RW) : ORIGIN = 0x20020000, LENGTH = 0x00000400
}

/* Define output sections */
SECTIONS
{
/* placing appFlag section at given address: (Roy M.)*/
.appFlag 0x20020000 :
{
KEEP(*(.appFlag)) /* keep my variable even if not referenced */
} > m_data_20020000

The red LED is not on in Release mode. In debug it works fine. But, in debug I cannot flash my app (as I've stated here), that is why I must use Release version.

Roy

0 Kudos
776 Views
BlackNight
NXP Employee
NXP Employee

Hi Roy,

I appologize for my late reply.

I have tried to reproduce what you describe, but I think that your problem is not caused by either release or debug, but an oddity of the GNU linker with custom sections.

I have created an example similar like yours, and the code testing/reading the variable is working fine and as expected with -O3 (and both with and without -O3 the variable has the 'D' attribute).

However, there is a thing with how the variable is intialized.

If you are using an initialied variable in a custom section like

volatile unsigned char __attribute__((section (".appFlag"))) appFlag = 0x55;

then it won't get automatically initialized by the startup code.

If putting variables into sections like this, you have to make that initialization yourself.

I covered part of that thing in GNU Linker, can you NOT Initialize my Variable? | MCU on Eclipse  where the linker creates an initalization if the variable is *not* initialized.

I have never used *initialized* global variables, that's why I have not seen this.

I hope this helps,

Erich

0 Kudos
776 Views
roymessinger
Contributor V

Ok,  thanks, I'll look into the link you sent.

Just to make things clearer, you did not used this phrase?

volatile unsigned char __attribute__((section (".appFlag"))) appFlag = 0x55;

So, what did you write in order it to work properly?

I'm not following....

Roy

0 Kudos
780 Views
BlackNight
NXP Employee
NXP Employee

Hi Roy,

yes, I used

volatile unsigned char __attribute__((section (".appFlag"))) appFlag = 0x55;

What I did is to initialize the variable fully/properly from my code. I did this with

static void Init(void) {
  appFlag = 0x55;
}

and called it from the beginning of main().

Erich

776 Views
Alice_Yang
NXP TechSupport
NXP TechSupport

Hello Roy,

1.  Please pay attention when run the startup code the RAM memory will be initialized.

Except reserved without definition in the linker file .

For example use 0x20000000 to 0x2000FFF8 to save  the flag "appflag", we  can do not

includes this memory :

pastedImage_1.png

For I don't know your project flow ,so I'm not sure you have this question, if yes, you can refer

to this DOC :Kinetis Bootloader to Update Multiple Devices in a Network for Cortex-M4 

pastedImage_3.png

2.  Do you use the KBOOTv2.0 ? If yes, the difference between debug version and release version

is release version reduce some code , you can search "DEBGU" in the whole project, these code

only for debug version :

3. If the debug version can work well , while release can't ,  you can add volatile or static to the

appFlag to have a try .

BR

Alice

0 Kudos