Problem started with CW10.4 (Kinetis)

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

Problem started with CW10.4 (Kinetis)

Jump to solution
985 Views
mjbcswitzerland
Specialist V

Hi All

 

The following code started failing with CW10.4 and CW10.5 but was Ok with CW10.2:

 

static CHAR cTest[] = "abcdefghijklmnop";

..

while (i < 16) {

    if (cTest[i] == 'z') {

        cTest[i] = 'a';

    }

    else {

        cTest[i]++;

    }

    i++;

}

 

The code just shifts the string in the buffer each time it is called but the code itself is not the issue.

The problem is that cTEST[] is located in FLASH from CW10.4 (irrespective of optimisation settings) and so any attempt to modify the string content causes an exception.

 

No other compliers tested with (GCC, Keil, IAR) put the string in FLASH and CW10.2 put it in SRAM.

 

The code has been modified to allocate cTest[] on heap to avoid the problem but it would be interesting to know whether there is something specific controlling the behaviour and whether ANSI C defines specifically where the array should be located?

For example, if the code is changed to declare the array specifically as a const
static const CHAR cTest[] = "abcdefghijklmnop";

the compiler then throws an error on the lines where writes are made to it. This tells me that the compiler is treating the array (when not declared as const) as being modifiable but the linker is then locating it as a const.

I wonder whether there is some rule such as "make all strings consts" that is being followed??

 

Regards

 

Mark

Labels (1)
Tags (3)
0 Kudos
1 Solution
606 Views
mjbcswitzerland
Specialist V

Hi

It seems as though the problem is solved when strings that should not be located in flash are declared as if they are arrays:

static CHAR cTest[] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 0};


New tests have shown that there was an error made during the original trials and this method does work around the difficulty.


Regards


Mark


View solution in original post

0 Kudos
4 Replies
606 Views
BlackNight
NXP Employee
NXP Employee

Mark,

what is the type behind CHAR?

And is cTest a global variable or a static local?

Can you confirm that you are not using the ARM gcc in CodeWarrior, but instead the legacy Freescale ARM compiler (Freescale moved to GCC as the default compiler)?

Erich

0 Kudos
606 Views
BlackNight
NXP Employee
NXP Employee

Hi Mark,

I would say: if the linker allocates that non-const array in FLASH, I would consider this as definitely not expected (a bug?).

I quickly tried your example (with 10.5), and it does allocate it in RAM for me, according to the linker map file?

# .app_data

  1FFF8000 00000011 .data   cTest    (main_c.obj)

Erich

0 Kudos
606 Views
mjbcswitzerland
Specialist V

Hi Eric

CHAR is typedefed as "signed char" and the array in question is a local static (not global).

In the meantime the following has been found. By unclicking "Place Read-Only strings in .rodata Section" it places the array in SRAM again - see

Placing strings

I can't say whether GCC or the legacy compiler is being used since I am relaying the finding from a uTasker project user - I still use CW10.2 for my testing. However it was also found that declaring the array to make it not to specifically be a string: static CHAR cTest[] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 0}; didn't change behaviour (still in Flash).


I have always worked with this option set since it avoids having lots of string consts being copied to SRAM (which can use up a lot of SRAM when there is a text based command line interface with menus based on string entries but it looks like from CW10.4 arrays that are not consts (and also not used as consts by the code) may be getting included.


Regards


Mark

0 Kudos
607 Views
mjbcswitzerland
Specialist V

Hi

It seems as though the problem is solved when strings that should not be located in flash are declared as if they are arrays:

static CHAR cTest[] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 0};


New tests have shown that there was an error made during the original trials and this method does work around the difficulty.


Regards


Mark


0 Kudos