This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Struct passed to function by value arrives corrupted



Gentlemen,

Using a TM4C123x, developing in CCS 6.1. I have a piece of code that passes a (big) struct to a function, by value. This is a debugging step right before the function is called.

This had been working for some time. Since a recent recompilation, the value arrives inside the function corrupted.

These are the first lines of the function, and there's also a global declaration of hwssi to be used later on...

static as5047_hardware_t	hwssi;

void AS5047PInitSPI(as5047_hardware_t hw)
{
//	as5047_hardware_t hwssi;
	hwssi = hw;		// Makes a copy of the application ssi struct into the static ssi struct
	if (hwssi.PowerPin)
	{
		AS5047PowerOn();
	}
	MAP_SysCtlPeripheralDisable(hwssi.SSIPeriph);

It's a new situation for me. I can solve it by passing the struct by reference, but I'd like to figure out what is going on here... Is there a size limit to pass a struct by value? Any suggestions as where to look?

Regards,

  • Hello Bruno,

    What is getting corrupted? Which element of the structure? As an example you could specify which element, what is the expected value and what is the actual value being shown. Also where is the structure being initialized?
  • Certainly Amit!

    Here's a print of hwssi right after it receives the values from hw at the beginning of the function.

    No need to compare to the previous image, suffices to say that probably only the first element is identical. Visually, lots of the lower ones are different.

    HOWEVER, having noted that it was a mess of 8-bit values in the middle of 32-bit ones, I added #pragma pack(push, 1) before the struct definition and pack(pop) after, and it is now working again. There's something on the compiler (or somewhere in the middle...) that was apparently optimizing the alignment of the struct in one part of the code and not on the other?

    Thanks for the quick reply, it was the push I needed for that extra thinking!

  • Bruno Saraiva said:
    . I have a piece of code that passes a (big) struct to a function, by value.

    That should raise a flag right away. You are using an embedded microcontroller not a desktop with virtual memory.

    In particular the stack is usually limited in size.

    Now in this particular case you should probably pass as a const pointer (or in C++ a const reference). Since no copy is required and the pointer arithmetic is similar you might actually see size and speed advantages to the code as well as the data.

    Bruno Saraiva said:
    void AS5047PInitSPI(as5047_hardware_t hw)

    becomes

    void AS5047PInitSPI(const as5047_hardware_t *hw)

    Robert

  • Hello Bruno,

    The values shown is in decimal format. Right click the structure and view it in HexaDecimal format to see which element is incorrect.
  • Robert,
    That's certainly true... the code was inherited from someone who was more used to a 32Gb desktop to run his errands...
    I tend to always use pointers to structs.
    Amit,
    I am aware these images are showing decimal formats... The dance of print screen/copy/crop/save and so on is too complex to inspire me to generate a whole new lot of images with hex numbers - but that being said, the thread is still valid as decimal elements #3, 5, 7 and others are easily seen to be different.
    Still - the pack push/pop mentioned earlier fixed things. So this matter can be put to rest. Wheather this was to be prevented by compiler/linker or not, it's up to different folks to say!
    Cheers!
  • Hello Bruno,

    Right now you are the only one who knows what the values are supposed to be (not me). That is why I asked for the values in the beginning.

    Did you increase the stack size and see the effect of the same on the structure?
  • Hello Amit!

    Sorry, I had no meaning to sound rude!!! So much on my mind these days that I believed the post sequence was clear...

    There was an image on the first post - a print of the elements at the calling of the function - and then, further on, there is supposed to be an image of the elements of the variable inside the function. One should have the same values as the other, but several elements were different.

    For the sake of clarification, are thes embedded JPEG images that I post viewable to all users?

    I had thought of increasing the stack size, but I have never treated the stack too professionally: most of my projects use 4096 as the stack size, which is already a lot, "just because I can"... So no, I did not try to increase it any further.

    This was the initialization of the struct when I the problem was still on:

    typedef struct
    {
    	uint32_t	SSIMISOBase;
    	uint8_t		SSIMISOPin;
    	uint32_t	SSIMOSIBase;
    	uint8_t		SSIMOSIPin;
    	uint32_t	SSICSLBase;
    	uint8_t		SSICSLPin;
    	uint32_t	SSICLKBase;
    	uint8_t		SSICLKPin;
    	uint32_t	SSIBase;
    	uint32_t	SSIPeriph;
    	uint32_t	SysClock;
    	uint32_t	PowerBase;
    	uint32_t	PowerPin;
    	bool		PowerOnHigh;
    }
    as5047_hardware_t;

    And this solved the matter:

    #pragma pack(push, 1)
    typedef struct
    {
    uint32_t SSIMISOBase;
    uint8_t SSIMISOPin;
    uint32_t SSIMOSIBase;
    uint8_t SSIMOSIPin;
    uint32_t SSICSLBase;
    uint8_t SSICSLPin;
    uint32_t SSICLKBase;
    uint8_t SSICLKPin;
    uint32_t SSIBase;
    uint32_t SSIPeriph;
    uint32_t SysClock;
    uint32_t PowerBase;
    uint32_t PowerPin;
    bool PowerOnHigh;
    }
    as5047_hardware_t;
    #pragma pack(pop)

    I apologize for the confusing messages...

    Regards,

    Bruno

  • Hello Bruno,

    You were not rude. It was just that the posts got confusing at some point, that it was not clear as to which one is the expected value.

    While the pragma is providing the solution, it is not addressing the root cause (which is yet to be determined). I would suggest (a) creating a CCS project that I can run with TivaWare and CCS to reproduce the issue and (b) checking where in the code does the corruption happen and (c) effect of the stack size increase.
  • Bruno Saraiva said:
    the code was inherited from someone who was more used to a 32Gb desktop to run his errand

    That explains it, although I wouldn't be enamored of it even it that context.

    Bruno Saraiva said:
    Still - the pack push/pop mentioned earlier fixed things.

    I'm with Amit, you probably want to find out why. There's almost no good scenario in which that fixes things.

    Robert