Author Topic: Array initialization fails  (Read 8218 times)

0 Members and 2 Guests are viewing this topic.

Offline ricko_ukTopic starter

  • Super Contributor
  • ***
  • Posts: 1233
  • Country: fr
Array initialization fails
« on: October 31, 2021, 11:55:14 pm »
UPDATE: I made this post with list of solutions that solved this and other issues. I hope it helps others too. :)
https://www.eevblog.com/forum/projects/solved-mplab-1)-slowno-variables-updates-2)-icd4-not-connecting-3)-others/

Hi,
the code below does not initialise the array (all the values are just initialised to 0x00) in the globally defined structure. Any idea why?

Code: [Select]
    typedef struct {
    uint8_t arrImage_data[2][_IMAGE_ARRAY_SIZE__IN_BYTES];
    bool bIndxImageBeingPrinted;
    uint32_t ui32IndxOfFirstByteOfCurrentlyPrintingLine;
} _image_data_struct_t; //image_data_struct;   

 _image_data_struct_t imageTest =
                            {
                                .arrImage_data =
                                    {{
                                    #include"TestImage_1.txt"
                                        },{
                                    #include"TestImage_1.txt"
                                   }},
                                .bIndxImageBeingPrinted = 0,
                                .ui32IndxOfFirstByteOfCurrentlyPrintingLine = 0
                            };

and the file TestImage_1.txt in the #include"TestImage_1.txt" has just a long list of comma-separated byte values exactly like this and nothing more:

0x11, 0x22, 0x33, 0x00, 0x00, 0x00,
0xAA, 0x55, 0x13, 0xFF, 0xFF, 0xFF,
0x11, 0x22, 0x33, 0x00, 0x00, 0x00

Thank you :)
« Last Edit: November 06, 2021, 06:04:03 pm by ricko_uk »
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 12463
  • Country: us
    • Personal site
Re: Array initialization fails
« Reply #1 on: November 01, 2021, 12:22:13 am »
Why create multiple topics for essentially the same question?

What compiler? What platform? How it was tested?

Also are any warning messages when compiling? Enable the highest warning level possible.
Alex
 

Offline ricko_ukTopic starter

  • Super Contributor
  • ***
  • Posts: 1233
  • Country: fr
Re: Array initialization fails
« Reply #2 on: November 01, 2021, 12:43:43 am »
Thank you Alex

I use XC32 version 2.5 (I have not updated to the very recently released V3 because in the release notes it says it has some backwards compatibility issues and when I tried it the code does not compile).
The environment is MPLABX IDE (latest version).
I used the built-in simulator.
There are no compile errors.
I tried changing the warning level and even googled it but cannot find anywhere the option. I do get full error for things as simple as variables not used (instead of just a warning) so it might be already at the highest warning level, however it is set. (Just a speculation!)

Ref posting a new topic, I agree. I created a different topic only because in the past, for a similar situation, I was asked to make a new post because "although closely related it was essential a different issue/question" and the other issue I posted previously was more about not compiling. So I thought it might have been better to post a new one also because the other was solved. :)

Thank you
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 12463
  • Country: us
    • Personal site
Re: Array initialization fails
« Reply #3 on: November 01, 2021, 01:38:04 am »
I have no idea about XC32 and simulator, and have no interest in even trying to figure this out. May be someone else will.
Alex
 

Offline retiredfeline

  • Frequent Contributor
  • **
  • Posts: 572
  • Country: au
Re: Array initialization fails
« Reply #4 on: November 01, 2021, 02:50:26 am »
Just a couple of things that come to mind:

See if you can turn on the assembly language generation option to see if the initialisations made it there.

In many Harvard arch MCUs, initialised data is put into the RO data segment or the code segment, so you may have to prefix the initialised variable declaration with __code__ or something similar. I don't know about XC32.

Sorry, that's all I can suggest. Good luck.
 

Offline DavidAlfa

  • Super Contributor
  • ***
  • Posts: 6919
  • Country: es
Re: Array initialization fails
« Reply #5 on: November 01, 2021, 03:41:03 am »
#include inside a struct declaration? What the hell?
I'm not a master in C programming, but to me it looks wrong?
Why don't you do it in the correct way, declaring the arrays properly?

At least use a define:
Code: [Select]
#define IMAGE1_DATA \
0x35, 9x44, 0x11, 0x42, 0x76, \
111, 104, 84, 10, 84, 92, \
'l', 'i', 'n', 'e', '3', \
You need add "\" to make it multiline \
This is the last line (No "\")
With that, you could simply type "IMAGE1_DATA" in the initialization array.
But it's not a tidy or proper way to do that...
« Last Edit: November 01, 2021, 03:55:26 am by DavidAlfa »
Hantek DSO2x1x            Drive        FAQ          DON'T BUY HANTEK! (Aka HALF-MADE)
Stm32 Soldering FW      Forum      Github      Donate
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 12463
  • Country: us
    • Personal site
Re: Array initialization fails
« Reply #6 on: November 01, 2021, 03:42:58 am »
It is fine to include the data like this. Some thing else is wrong. I suspect just misinterpretation of the results or some simulator/XC32 issue.
Alex
 

Offline DavidAlfa

  • Super Contributor
  • ***
  • Posts: 6919
  • Country: es
Re: Array initialization fails
« Reply #7 on: November 01, 2021, 03:53:18 am »
Hantek DSO2x1x            Drive        FAQ          DON'T BUY HANTEK! (Aka HALF-MADE)
Stm32 Soldering FW      Forum      Github      Donate
 

Offline Nominal Animal

  • Super Contributor
  • ***
  • Posts: 8349
  • Country: fi
    • My home page and email address
Re: Array initialization fails
« Reply #8 on: November 01, 2021, 04:03:07 am »
the code below does not initialise the array (all the values are just initialised to 0x00) in the globally defined structure. Any idea why?
Since the code most certainly does initialize the array in a hosted environment (I checked), the reason is most likely due to the environment you are using.

It may be, that XC32 2.5 does not initialize data structures defined in RAM properly.  (In e.g. Arduino, these are initialized by storing a copy of the initialized object in Flash, and copying initialized objects to RAM during startup.)  Lessee, okay, an XC32 manual I found on the net has a section 12.3.4 about this.  It says the compiler should do this properly; it actually uses initialization records, for this.  So the underlying problem is unclear.

However, if the image data is not modified during run time, you really should put that part of the data in Flash/ROM.  According to that random XC32 manual, const suffices for this.

So, what I would recommend for you, is to use something like the following instead:
Code: [Select]
typedef  struct {
    const uint8_t *data[2];
    uint32_t ui32IndxOfFirstByteOfCurrentlyPrintingLine;
    bool bIndxImageBeingPrinted;
} image_spec;

const uint8_t imageTest_data[] = {
#include"TestImage_1.txt"
};

image_spec  imageTest = {
    .data = { imageTest_data, imageTest_data },
    .ui32IndxOfFirstByteOfCurrentlyPrintingLine = 0
    .bIndxImageBeingPrinted = 0,
};
This way, you only use RAM for the two pointers to the data, and the two other members, and the actual image data is in Flash.  (The XC32 manual said you have an unified address space, where both RAM and Flash are accessible using the same instructions, just at different addresses, so this should work without issues.)

In general, when writing code for resource-constrained embedded targets, you do need to consider what data you can keep in Flash/ROM, and what needs to be in RAM because you wish to be able to manipulate it.  Above, instead of incorporating the data into the image definition, we use a pointer to the data, so that the data can be anywhere else (RAM, Flash, wherever, since we have an unified address space).  This also means the data appears only once in Flash, so actually saves you resources there too.
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 12463
  • Country: us
    • Personal site
Re: Array initialization fails
« Reply #9 on: November 01, 2021, 04:11:40 am »
I thought it was only a C++ thing:
This is not what this code does, it simply includes another file. It is no different than including a header file.
Alex
 

Offline DavidAlfa

  • Super Contributor
  • ***
  • Posts: 6919
  • Country: es
Re: Array initialization fails
« Reply #10 on: November 01, 2021, 08:48:57 am »
I'm not telling you anything new, for sure you know far more more than me about C.
But this code hurts my eyes!

It's not about the fact he's including the txt file, it's about WHAT he's trying to achieve with it.
The txt file has just comma separated values, so how on earth would this work? (ignoring the fact it's being declared twice)
Code: [Select]
.arrImage_data =
                                   {{
                                   #include"TestImage_1.txt"
                                   },{
                                   #include"TestImage_1.txt"
                                   }},

#include simply tells the compiler to search for resources in that file following the line where it was declared.
But that initialization actually does this, #include does absolutely nothing inside it:
Code: [Select]
.arrImage_data =
                                    {{
                                    },{
                                    }},

It's like inserting any random preprocessor stuff:
Code: [Select]
.arrImage_data =
                                   {{
                                   #define This_does_nothing
                                   },{
                                   #define Neither_this
                                   }},

Actually, it's strange that the compiler isn't dropping any error, because a random text not following any syntax would definitely shoudl fail.
Perhabs the compiler is ignoring it due not being a standard C file extension (.c, or .h).
« Last Edit: November 01, 2021, 09:01:15 am by DavidAlfa »
Hantek DSO2x1x            Drive        FAQ          DON'T BUY HANTEK! (Aka HALF-MADE)
Stm32 Soldering FW      Forum      Github      Donate
 

Offline mikerj

  • Super Contributor
  • ***
  • Posts: 3671
  • Country: gb
Re: Array initialization fails
« Reply #11 on: November 01, 2021, 10:51:03 am »
#include simply tells the compiler to search for resources in that file following the line where it was declared.

#include inserts the entire contents of the target file, no searching is performed at that point.  I suggest the OP enables preprocessor file output and checks that.
 

Offline Renate

  • Super Contributor
  • ***
  • Posts: 1716
  • Country: de
    • Renate's Android Page
Re: Array initialization fails
« Reply #12 on: November 01, 2021, 11:49:33 am »
Haven't you ever forgotten a semicolon in a function declaration in a header file?
Code: [Select]
int my_fun(int x, int y)   <- missing semicolonThat sometimes shows up as an error in the .c where it's included.
That shows that #include just shovels in text from the file without paying attention to anything.
In your example you could include the next set of braces in the included file or even just the opening braces (as long as the net effect with the .c file was balanced).
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 12463
  • Country: us
    • Personal site
Re: Array initialization fails
« Reply #13 on: November 01, 2021, 04:09:38 pm »
#include simply tells the compiler to search for resources in that file following the line where it was declared.
As been said before, #include just scans the whole file as it was copy-pasted into that place. Nothing more.

This use of include is very common and useful. I use it all the time with stupider compilers, like SDCC, which does not deal well with optimizations across multiple object files. When I still want to have some structure to my code I simply include all the C files into one main source code. From the compiler point of view it starts to look like a single file.

There are other uses. And this one is valid too.
Alex
 
The following users thanked this post: DavidAlfa

Offline DrG

  • Super Contributor
  • ***
  • !
  • Posts: 1199
  • Country: us
Re: Array initialization fails
« Reply #14 on: November 01, 2021, 04:46:29 pm »
Hi,
the code below does not initialise the array (all the values are just initialised to 0x00) in the globally defined structure. Any idea why?

Code: [Select]
    typedef struct {
    uint8_t arrImage_data[2][_IMAGE_ARRAY_SIZE__IN_BYTES];
    bool bIndxImageBeingPrinted;
    uint32_t ui32IndxOfFirstByteOfCurrentlyPrintingLine;
} _image_data_struct_t; //image_data_struct;   

 _image_data_struct_t imageTest =
                            {
                                .arrImage_data =
                                    {{
                                    #include"TestImage_1.txt"
                                        },{
                                    #include"TestImage_1.txt"
                                   }},
                                .bIndxImageBeingPrinted = 0,
                                .ui32IndxOfFirstByteOfCurrentlyPrintingLine = 0
                            };

and the file TestImage_1.txt in the #include"TestImage_1.txt" has just a long list of comma-separated byte values exactly like this and nothing more:

0x11, 0x22, 0x33, 0x00, 0x00, 0x00,
0xAA, 0x55, 0x13, 0xFF, 0xFF, 0xFF,
0x11, 0x22, 0x33, 0x00, 0x00, 0x00

Thank you :)

I think you will get much better help if you will post a minimal example that demonstrates the problem that you *think* is happening and show all of the code for that minimal example.

So, in this case, the problem as you see it is that "the code below does not initialise the array (all the values are just initialised to 0x00) in the globally defined structure."

But, to my eyes, there are a whole lot of things that can be going on that are not at all revealed in that snippet. Not trying to give you a hard time, just giving my opinion. I have a little bit of experience with XC32 and I read through the thread and decided that there are just too many issues that *could* be going on and maybe I would only know about a few....but if you had posted a minimal example that demonstrates the problem, I would have looked further.
- Invest in science - it pays big dividends. -
 

Online Siwastaja

  • Super Contributor
  • ***
  • Posts: 11145
  • Country: fi
Re: Array initialization fails
« Reply #15 on: November 01, 2021, 06:36:14 pm »
David Alfa,

#include, by very definition, includes another file. Fancy copy-paste, ranging from very crude automated copypaste on old compilers, to a bit fancier which can track file names and line numbers to show errors/warnings properly; but still just a copy-paste).

The most typical use a beginner sees, it's used to include the headers of libraries (the actual binaries to be linked later). For this use, it's quite a crappy tool but neither C nor C++ has any better, so #include it has to be. Basically, the compiler copy pastes the declarations (but not definitions or contents, because they are not in the .h files) of all library functions every time to your code (compilation unit). If anything, this standard use would hurt the eye of someone who has seen something better in other languages.

Example shown here is different: this is the most proper use case for a file "copy paste" type of include. You have some externally autogenerated data. You don't want to manually copy-paste every time that data changes, which could be even for every compilation. You don't want to have the ugly thousand-line hex blob visible in the code because it tells you nothing. So you #include it; make the compiler copy-paste it automagically for you. This would be the most appropriate use case for #include, it should not hurt your eyes.

Preprocessor commands (starting with #) are all very simple, like automated text processing features. It's helpful to understand this.
« Last Edit: November 01, 2021, 06:38:31 pm by Siwastaja »
 
The following users thanked this post: DavidAlfa

Offline Nominal Animal

  • Super Contributor
  • ***
  • Posts: 8349
  • Country: fi
    • My home page and email address
Re: Array initialization fails
« Reply #16 on: November 01, 2021, 07:18:42 pm »
@ricko_uk:

Please check if a simpler/test version of this works in your environment.  I recommend you do this as a separate project.  For example,
Code: [Select]
#include <stdint.h>

typedef struct {
    uint32_t  a;
    int8_t    b;
    uint8_t   c[2][64];
} data_struct;

data_struct  test_data_struct = {
    .a = 0xdeadbeef,
    .b = -42,
    .c = { {
         1, 2, 3, 4, 5, 6, 7, 8,
        -1,-2,-3,-4,-5,-6,-7,-8,
        32,33,34,35,36,37,38,39,
        47,46,45,44,43,42,41,40,
        16,17,18,19,20,21,22,23,
        24,25,26,27,28,29,30,31,
        55,54,53,52,51,50,49,48,
        56,57,58,59,60,61,62,63,
         }, {
         1,63,62,61,60,59,58,57,
        56, 1,54,53,52,51,50,49,
        48,47, 1,45,44,43,42,41,
        40,39,38, 1,36,35,34,33,
        32,31,30,29, 1,27,26,25,
        24,23,22,21,20, 1,18,17,
        16,15,14,13,12,11, 1, 9,
         8, 7, 6, 5, 4, 3, 2, 1,
         } },
};
The sum of test_data_struct.c[0] is 3944 (104, if you sum as uint8_t), and the sum of test_data_struct.c[1] is 1828 (36, if you use uint8_t), if you want to use a test loop to verify all the data is still there.

If you see at runtime zeroes here, then you have a minimal, complete verifiable example or MCVE, as needed for proper bug reports.

If this works correctly, then I'd expand the size, duplicating the shown data or using random data, up to around the same size as in your proper project.  If it suddenly stops working, it means that your environment has a limit of how much it can initialize data.  Perhaps it is running out of Flash/ROM, or perhaps it is some configurable limit.

It this works correctly as a separate example, but fails in your own project, then your project has a serious bug where something clears the memory after it has been initialized; most likely, your own code does an equivalent of memset(pointer, 0, size) where pointer, size, or both are bogus.  A particular case I've seen is when supplied size is negative: since the parameter is of type size_t, the size is cast to an unsigned type, leading to a very large size.
 

Offline DavidAlfa

  • Super Contributor
  • ***
  • Posts: 6919
  • Country: es
Re: Array initialization fails
« Reply #17 on: November 01, 2021, 08:57:13 pm »
Damn, learned something in the wrong way, after opening my mouth and putting myself in evidence. :-DD
Hantek DSO2x1x            Drive        FAQ          DON'T BUY HANTEK! (Aka HALF-MADE)
Stm32 Soldering FW      Forum      Github      Donate
 

Offline ricko_ukTopic starter

  • Super Contributor
  • ***
  • Posts: 1233
  • Country: fr
Re: Array initialization fails
« Reply #18 on: November 01, 2021, 09:03:15 pm »
Thank you all! :)

I now have few things to try. Also reinstalling MPLAB to see if that changes anything.

 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 17774
  • Country: fr
Re: Array initialization fails
« Reply #19 on: November 01, 2021, 09:11:38 pm »
Just a point, XC32 is just GCC for MIPS. It shouldn't in itself do anything weird or special.

Now of course, initializers for global data are put in the .data section, and the copy in the actual objects in RAM is done in the startup code. The startup code for your particular project could be worth taking a look at - although, if it didn't copy initializers properly, absolutely no initializer in your code would work. Thus, something as simple as a global like: "int n = 5;" would not hold the value '5' either... which can be checked very easily.

Note that - even if you still should find out what is wrong here - you can try declaring your variable with a 'const' qualifier, if it's not going to be modified. Then it should be read directly from program memory and not copied in RAM. If that works, then you have an additional clue as to what could be wrong. (And BTW, if said variable is not going to be modified in your code, you definitely *should* declare it 'const' anyway.)
 

Offline ricko_ukTopic starter

  • Super Contributor
  • ***
  • Posts: 1233
  • Country: fr
Re: Array initialization fails
« Reply #20 on: November 01, 2021, 09:29:29 pm »
I forgot to mention that (for the moment) I am not putting the large array as const at the moment only because being very large, for some reason the ICD4 takes up to 3.5 minutes to read any other variable. Even if I don't include that struct/array in the watch or variable windows (to see their value) it still takes those 3 to 3.5 minutes.

As soon as I declare it as a non-const variable or remove it completely then the ICD4 is the usual fast speed (seconds to list all the variables I want to monitor).

It will go as const in the final code.

It would be interesting to know if anybody else experience similar issues. I also ordered the JLink debugger which hopefully will not have that issue (assuming it is ICD4 related)...?

Thank you
 

Offline AlfBaz

  • Super Contributor
  • ***
  • Posts: 2187
  • Country: au
Re: Array initialization fails
« Reply #21 on: November 01, 2021, 10:49:23 pm »
Apologies for this off topic question
I see the code using the dot operator without the base object. How long has this been around?
Is this something new in C or something old in C++ or ??
Is there some link I can read about the rules surrounding this built in "namespace" thing?

Sorry I don't get out much :-[
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 12463
  • Country: us
    • Personal site
Re: Array initialization fails
« Reply #22 on: November 01, 2021, 11:07:42 pm »
There are no dot operators here. There is only structure member initialization by name. This was in the standard since C99 or so.
Alex
 
The following users thanked this post: AlfBaz

Offline mikerj

  • Super Contributor
  • ***
  • Posts: 3671
  • Country: gb
Re: Array initialization fails
« Reply #23 on: November 01, 2021, 11:10:18 pm »
Apologies for this off topic question
I see the code using the dot operator without the base object. How long has this been around?

This is called designated initializers, and like ataradov says was introduced in C99.
 
The following users thanked this post: AlfBaz

Offline AlfBaz

  • Super Contributor
  • ***
  • Posts: 2187
  • Country: au
Re: Array initialization fails
« Reply #24 on: November 01, 2021, 11:28:53 pm »
Thank you both
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf