Hello!
We experience a strange problem with XDATA initialization - part of global variables are not initialized. After digging deeper in the problem we found that C_INITSEG segment is corrupted in the .hex output.
The segment is defined in the .map file as follows: 003899H 003D79H 0004E1H BYTE UNIT CODE ?C_INITSEG
As described in the INIT.A51, the table should end with 00 - means in our case at the address 003D79 we should see value 00. Here is our .hex file (excuse for the huge content). First byte of the table (first line) and last bytes (last line) are bold.
:10389000F208740393F27404734103C8004103C730 :1038A00000E0020200001435E002020002120EE005 :1038B0000102000954E00102000AA5E00502120B12 :1038C000120E02043D4107DF060114004107DE012C :1038D0004107DC01C115011900011700433DD0006B :1038E0000000423DCE000041416300E002021210A0 :1038F00001B0E00102121200E00102129300E005A3 :103900000213BB01B006043DC109413246004132F9 :10391000C0FF4132B800C108C1074132C100413285 :10392000C2004132B901C10B41324500C1184147C3 .... (truncated, too long for the forum - can post more on demand) :103AE000FC0310FE0406050607FC0610FE0708FC92 :103AF0000710FE080A060809040A07070A09020A4D :103B00000D080A0C090A0F0D0C10FC0C10FE090719 :103B100003090B020D0EFC0E110B0D10FE0B10FC19 :103B20000B10FE0F120A10120A11120A5436C504A5 :103B30000400C8080400C80E0B000A100A00000F99 :103B40000A00004D36DA013652210136C505000063 :103B50000112104536C0020908070DE0020213C029 :103B60000013E00C0213C201150100000400020062 :103B700000043DE0050213CE0013FF0000E0020246 :103B800013D300004141F10000C122C119C11BC182 <--- wrong ending here :103B90000F015800C10CC10D4229B098404129B213 :103BA000006020296F0000000000000000000000FD .... (truncated, too long for the forum - can post more on demand) :103D40003301412E9F00432E9C012E5A432E900199 :103D50002E5A4109690060200845EDFFFFFFFFFF73 :103D6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63 :103D7000FFFFFFFFFFFFFFFFFF7F2B282B3C2C6384
As one can see, the last byte is not 00. We have decoded this table and found another strange thing. Here is the decoded data: (format is <address in hex> <memory type> at <address in memory> (<size> bytes): <data>)
3899 XDATA at 0x03c8 (1 bytes): 00 389d XDATA at 0x03c7 (1 bytes): 00 38a1 HDATA at 0x020000 (2 bytes): 14 35 38a8 HDATA at 0x020002 (2 bytes): 12 0e 38af HDATA at 0x020009 (1 bytes): 54 38b5 HDATA at 0x02000a (1 bytes): a5 38bb HDATA at 0x02120b (5 bytes): 12 0e 02 04 3d 38c5 XDATA at 0x07df (1 bytes): 06 38c9 IDATA at 0x14 (1 bytes): 00 38cc XDATA at 0x07de (1 bytes): 01 38d0 XDATA at 0x07dc (1 bytes): 01 38d4 BIT at 0x15: 0 38d6 IDATA at 0x19 (1 bytes): 00 38d9 IDATA at 0x17 (1 bytes): 00 38dc XDATA at 0x3dd0 (3 bytes): 00 00 00 38e2 XDATA at 0x3dce (2 bytes): 00 00 38e7 XDATA at 0x4163 (1 bytes): 00 38eb HDATA at 0x021210 (2 bytes): 01 b0 38f2 HDATA at 0x021212 (1 bytes): 00 38f8 HDATA at 0x021293 (1 bytes): 00 38fe HDATA at 0x0213bb (5 bytes): 01 b0 06 04 3d 3908 BIT at 0x09: 0 390a XDATA at 0x3246 (1 bytes): 00 390e XDATA at 0x32c0 (1 bytes): ff 3912 XDATA at 0x32b8 (1 bytes): 00 3916 BIT at 0x08: 1 3918 BIT at 0x07: 0 391a XDATA at 0x32c1 (1 bytes): 00 391e XDATA at 0x32c2 (1 bytes): 00 ... (truncated) 3b43 XDATA at 0x36da (13 bytes): 01 36 52 21 01 36 c5 05 00 00 01 12 10 3b53 XDATA at 0x36c0 (5 bytes): 02 09 08 07 0d 3b5b HDATA at 0x0213c0 (2 bytes): 00 13 3b62 HDATA at 0x0213c2 (12 bytes): 01 15 01 00 00 04 00 02 00 00 04 3d 3b73 HDATA at 0x0213ce (5 bytes): 00 13 ff 00 00 3b7d HDATA at 0x0213d3 (2 bytes): 00 00 3b84 XDATA at 0x41f1 (1 bytes): 00 End of the table at 0x3b88 3b89 BIT at 0x22: 1 3b8b BIT at 0x19: 1 3b8d BIT at 0x1b: 1 3b8f BIT at 0x0f: 0 3b91 IDATA at 0x58 (1 bytes): 00 3b94 BIT at 0x0c: 1 3b96 BIT at 0x0d: 0 3b98 XDATA at 0x29b0 (2 bytes): 98 40 3b9d XDATA at 0x29b2 (1 bytes): 00 3ba1 XDATA at 0x296f (32 bytes): .... (truncated) 3bc5 XDATA at 0x2624 (3 bytes): 9f 01 00 3bcb XDATA at 0x2627 (16 bytes): .... (truncated) 3bde XDATA at 0x2c2a (290 bytes): .... (truncated) 3d04 XDATA at 0x2e35 (36 bytes): .... (truncated) 3d2c XDATA at 0x2d8c (6 bytes): 01 00 02 01 04 02 3d35 XDATA at 0x2e12 (2 bytes): 2c 4a 3d3a XDATA at 0x2e99 (1 bytes): 00 3d3e XDATA at 0x3033 (1 bytes): 01 3d42 XDATA at 0x2e9f (1 bytes): 00 3d46 XDATA at 0x2e9c (3 bytes): 01 2e 5a 3d4c XDATA at 0x2e90 (3 bytes): 01 2e 5a 3d52 XDATA at 0x0969 (1 bytes): 00 3d56 XDATA at 0x0845 (32 bytes): .... (truncated) ... ff ff ff ff 7f No ending 00 found
So, here we see that the ending 00 byte was inserted by Keil in the middle of the table (see bold) at the address 3B88. The total size of the table is correct but the ending byte is too early and the rest of the table is shifted by one byte.
This happens only in one project and does not for others - we experience this only on one single project.
Any idea why this might happen? Any help wil be appreciated!
But there is XDATALEN, and it is zero! That seems odd - doesn't it ?
This startup.a51 is the default one, so it uses project settings (this is why I've pasted them too).
That worked for all other projects we did before.
Please note that the C_INITSEG segment contains correct data even after the end mark. The only problem is that this mark is not at the end, but somewhere in the middle. And not overriding the byte where 00 is, but shifting data. So it looks like a bug in the algo. Why Keil is doing that?
So it looks like a bug in the algo. Why Keil is doing that?
Appears that you've made a massive jump at a conclusion there.
I'll be polite and say that the evidence is a tad sparse.
Whenever I've had anything like this crop up in the past, I've spent time searching for the cause. Near every time it's been a bad assumption on my part. Yes, i have found and reported bugs to Keil before (including a compiler bug) but only once I was 100% certain that 1) I knew what I was doing and 2) I knew exactly how to explain the situation fully. I'd suggest you do the same and analyse all information first.
Agree. To be more precise I see no obvious reason for the problem and if Keil is doing that intentionally, it should at least notify us. Otherwise it looks like a crazy bug (may be not in the algo, but at least in the notification of the user about something going bad).
So, any ideas? Where to dig?
If you have a licensed product, contact Keil support - that's what you pay the licence fee for!
Even if you don't have a licensed product, it might be worth contacting Keil support - they should be interested if it is a bug ...
As any bug hunt. Break the situation down. Try to minimise to the smallest possible code while keeping the issue present.
I personally wouldn't consult keil support until i was totally sure of the situation; regardless of whether i had access to it. Been on the other side of such issues too many times before.
set XDATALEN to what you have!!! the zero you are looking for is set in startup.a51
Problem found. And it is definitelly a bug.
We have few .lib and .c files forced to different banks. We also have files with default settings. And custom init_vars.obj that comes from Sigma Desgins.
We had a mixed order of those files. After changing the order in the project to have forced first, then default and only then the group with init_vars.obj and C51_startup, everything started to work as expected.
Before fixing this order everything after the group with init_vars.obj and C51_startup were after the 0 in the C_INITSEG.
Hope this helps someone.
Errr. It was obvious there was a bug from day one. You've not given any real detail of what you've found so it would be difficult to determine where exactly that bug might be. Although it's fairly obvious where you think the offence is, only true evidence would prove what is at fault.
As I've see above, not everyone had the perception that it is a bug ;)
I gave a pretty detailed description that order of groups in the project file relative to the one hosting all the starup file matters. Hope this will help others and may be Keil team will fix that. If someone needs more info, we can provide. Just be clear in what to provide.
have you set the correct XDATALEN?
No. As I suggested, this default value does not matter as the correct one will be substituted by Keil from the project settings. We have not touched anything but the order of groups in our project file to solve the issue.
For Keil to fix it, you will need to report it direct to Keil.
And I'm sure they'd appreciate something more than "it is definitelly a bug."
Sent it. If they will need more details, they will ask for. Hope they will be more detailed than just ask for "something more" ;)
I saw this forum thread because PS created a support case. However, this is not a bug in the linker. Whenever you add the module init.a51 to your project, it must be the last module in the linker command file. This is mentioned in the header of this file:
; INIT.A51: This code is executed, if the application program contains ; initialized variables at file level. ; ; If you are using uVision2, just add the file as last file to your project. ; *** IMPORTANT NOTE ***: this file needs to be the last file of the linker ; input list. If you are using uVision2 this file should be therefore the ; last file in your project tree.
This is also mentioned in these knowedgebase articles: http://www.keil.com/support/docs/752.htm "If you use the command line linker, STARTUP.OBJ and INIT.OBJ must be the last two files in the object file list."
http://www.keil.com/support/docs/787.htm "Include the module INIT.A51 in your project only if you have modified it. If you need it, drag it to the very bottom of the µVision project window. If you use a linker command file, specify the INIT.OBJ file as the last module."