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.

CCS/TM4C1294NCPDT: Forcing an element from a structure to be volatile (or not optimized)

Part Number: TM4C1294NCPDT


Tool/software: Code Composer Studio

Gents,

I have the following small function:

/*
 * Holds program execution until the amount
 * of mili-seconds pass.
 */
void SystemUtilitiesDelayms(uint32_t delayms)
{
    uint32_t	timeLimit;
    timeLimit = systemUtilities.systemElapsedMS + delayms;
    while(timeLimit > systemUtilities.systemElapsedMS);
}

The element systemUtilities.systemElapsedMS is increased elsewhere, on a Timer interrupt.

Code gets stuck on the while() loop, despite timeLimit being lesser than .systemElapsedMS. I believe the problem is because of optimization on the function, which generates an assembly code that compares two registers:

Because of other indirect access elsewhere, I can't make the structure volatile.

Shall I "pragmatize" the function so that it does not get optimized? Any other way out of this one?

Thanks!

Bruno

  • Ok, found that this works:

        while(*(volatile uint32_t*)&systemUtilities.systemElapsedMS < timeLimit);

  • First don't bother with turning off optimization. Not only is that not guaranteed to work now, it can change in future compiler versions

    Second take a look at embeddedgurus.com/.../

    Adding a volatile to at least the incremented time is, I think, a necessity. Depending on the other elements in the structure you may want the entire structure to be volatile (indirect access shouldn't prevent that). Side note: unless you are copying this structure elsewhere I'm not sure you are gaining much by using a structure, maybe some syntactic sugar.

    Finally, in general you need to provide for atomic access as well as guarantee the number and order of accesses. By lucky happenstance the variable size is accessed atomically in this case.


    Robert

  • Bruno Saraiva said:
    while(*(volatile uint32_t*)&systemUtilities.systemElapsedMS < timeLimit);

    This is not a general solution. You need it to be volatile qualified for all accesses.

    Robert

  • Robert Adsett said:
    Adding a volatile to at least the incremented time is, I think, a necessity.

    Agreed and done, thanks.

    Robert Adsett said:
    indirect access shouldn't prevent that

    I was having some compilation warnings when I did such, but your warning was enough to make me look what else was wrong, for in fact it was not the volatile attribute to one element of the structure.

    Robert Adsett said:
    maybe some syntactic sugar

    That's one of the uses for structures! Keep everything under control in the same location... make it easier to copy to a separate place for debugging the whole set... anyway, because I can!

    All working now with no need for the pointer-to-address-to-pointer-to-address confusion that I used earlier.

    Bruno