1

I am writing embedded code in GHS environment and I am facing such a strange issue that I have never encountered before. All global variables except for constant ones which are initialized before run-time are set the highest value of a data type. For example:

I define a global variable:

static uint8 Dcm_Cbk_Gu8_FirstReqAfterReset = 1;

However, the value of the variable is always set to 255 no matter what the initial value is. I am sure that the variable is not used yet anywhere in the code. If the data type is uint16, the value shall always be 65535 until It is changed in run-time. Well, It happens to all global variables no what the data type is.

Note that the situation doesn't occur if the variable is declared globally and initialized in run-time, but this way violates the coding convention.

Actually, Everything works well in another environment (built by make) but when I Merged the code (*.c,*h) and move the whole linker file to a different environment (built by Scon struct), I got the issue. The MCU that is used is chorus 10M (SPC58NH92).

Anybody knows about the reason, could you please broaden my knowledge? Thank you!

  • Looks like you don't have a loader initializing your data segment (I've run in such environments) or your linker sections are not set up properly. However, I would expect to see random data, not all 0xFFs -- that is more consistent with uninitialized flash memory than RAM. – Basya Aug 15 '21 at 16:00
  • Could you have your linker file accidentally pointing your .data segment to an address in flash? Then the loader could not successfully set the values, and unwritten flash is (almost always) all 0xFF. – Basya Aug 15 '21 at 16:04
  • Perhaps give some more info -- your linker definition file perhaps? What processor? (BTW, it was when working with GreenHills, iirc, that I had an environment with a loader which did not initialize the .data segment) – Basya Aug 15 '21 at 16:05
  • Thank you! But I can not show my linker definition file because It is owned by the enterprise, I got the file from my customer. Actually, Everything works well in another environment (built by make) but when I Merge the code (*.c,*h) and move the whole linker file to a different environment (built by Scon struct), I got the issue. The MCU that is used is chorus 10M (SPC58NH92). – Thanh Trinh Linh Aug 15 '21 at 16:17
  • You will have to check your linker file against your memory map, neither of which are you likely to be able to share. Is your different environment on the same hardware or different hardware? – Basya Aug 15 '21 at 16:17
  • Well, the same hardware and We do have startup code and the startup code works well in the previous environment (not the one that I encounter the issue) – Thanh Trinh Linh Aug 15 '21 at 16:26
  • Could something have gotten corrupted in the linker file when you made the transition to the new environment? I can not promise that this is the right direction to look, but it looks possible to me. – Basya Aug 15 '21 at 16:29
  • If you have a debugger, you could step through the startup code and see if it is succeeding to set the values.... – Basya Aug 15 '21 at 16:30
  • Almost certainly a linker or flashing issue. All ones is typically unprogrammed flash, so maybe you didn't flash correctly, or maybe you picked some weird "RAM build" etc. – Lundin Aug 16 '21 at 06:27
  • 1
    I already resolved the issue, It is because of the incorrect assembly startup code. I compared my startup code to other ones and then added asm(".globl _start"), asm(".global __start") and asm(".align 4") to mine. It works well now. But to be honest, I do not understand these asm commands, why they should be there. Anyway, many thanks for your help! – Thanh Trinh Linh Aug 17 '21 at 16:31
  • for .global __start see: https://stackoverflow.com/questions/17898989/what-is-global-start-in-assembly-language. Without it the linker does not know where the __start symbol is. The .align directive will locate the next instruction at an address which is a multiple of 4. – Basya Aug 17 '21 at 16:42
  • And...thank you for returning and letting us know what the problem was. – Basya Aug 17 '21 at 16:42

1 Answers1

1

With the limited information in the question, it is hard to give a definitive answer. I can tell you what it looks like to me though.

The initialized global or static variables make up the .data section. These values should be stored within the read-only memory (typically within .text) and should be copied into the .data segment during the start-up routine of the program.

If there is no proper code in the start-up routine to copy these values, they will be uninitialized. So, check whether you have such code. (I did work in a GreenHills environment where we did not have such code provided by the compiler. We had the choice of writing it ourselves or not using the .data segment and initializing everything towards the beginning of main).

However, this is unlikely to be your whole problem. You may or may not have the correct startup code. If you had your memory segments set up correctly but were missing startup code, I would expect to see random values in RAM. Consistent 0xFF looks to me like one of two things:

  1. Startup code which preinitializes all of RAM to 0xFF, and the values either loaded before that (and overwritten) or not loaded at all
  2. Your linker file is not set up correctly, and is located the .data segment in flash memory rather than RAM (uninitialized flash memory is generally all 0xFF, which is what you are seeing.

I think the second one is more likely, but I know neither the memory map of your hardware nor the setup in your linker definition file. You will have to check that yourself.

Basya
  • 1,477
  • 1
  • 12
  • 22