• AVR Freaks

Hot!Question about uint32_t values not working correctly sometimes

Author
user2x
Super Member
  • Total Posts : 445
  • Reward points : 0
  • Joined: 2011/02/10 20:43:36
  • Location: 0
  • Status: offline
2020/10/26 15:14:41 (permalink)
0

Question about uint32_t values not working correctly sometimes

I have a problem:  XC16 1.41
 
I have a function and the a call to it:

 
void Watchdog_StartTimout_ms(uint32_t timeout_ticks)
 
{
 
   uint32_t something_else = timeout ticks;
 
}
 
 
 
 
 
void main(void)
{
     Watchdog_StartTimout_ms(1);
}

 
But when I debug it, the timeout_ticks contains rubbish in the MSW.
such as 0x 00320001
 
 
However, when I call it with a value of say 0x12345678, 
The value is correct.
It appears that the calling value of 1 is not being promoted to a uint32_t but rather a uint16_t
Why is this happening?
 
#1

19 Replies Related Threads

    ric
    Super Member
    • Total Posts : 28943
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: online
    Re: Question about uint32_t values not working correctly sometimes 2020/10/26 15:24:26 (permalink)
    +1 (1)
    Using a debugger to look at variables that are never used, often leads to misleading results, due to the operation of the C optimiser.
    You have to add a "volatile" qualifier to any variable you want to inspect like this, to force it to always update the copy in RAM.
     
    Of course, if the real code you are testing is not what you show here, all bets are off.
     
     

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #2
    user2x
    Super Member
    • Total Posts : 445
    • Reward points : 0
    • Joined: 2011/02/10 20:43:36
    • Location: 0
    • Status: offline
    Re: Question about uint32_t values not working correctly sometimes 2020/10/26 16:04:28 (permalink)
    0
    My variables are used. That is not the problem.
    Also, optimization is off at this stage.
     
    #3
    user2x
    Super Member
    • Total Posts : 445
    • Reward points : 0
    • Joined: 2011/02/10 20:43:36
    • Location: 0
    • Status: offline
    Re: Question about uint32_t values not working correctly sometimes 2020/10/26 16:21:41 (permalink)
    0
    I can actually show the real code...
     
    Here:

    volatile watchdog_t watchdog;
     
    void Watchdog_StartTimout_ms(uint32_t timeout_ticks)
    {
        watchdog.flags.bits.use_timeout = 0;
        watchdog.timeout_ticks = timeout_ticks;
        watchdog.flags.bits.use_timeout = 1;
    }
     
    void main (void)
    {
           Watchdog_StartTimout_ms(1);
           while(1)
               ;
    }

    #4
    ric
    Super Member
    • Total Posts : 28943
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: online
    Re: Question about uint32_t values not working correctly sometimes 2020/10/26 16:56:53 (permalink)
    0
    Please post the definition for your watchdog_t structure.
     

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #5
    user2x
    Super Member
    • Total Posts : 445
    • Reward points : 0
    • Joined: 2011/02/10 20:43:36
    • Location: 0
    • Status: offline
    Re: Question about uint32_t values not working correctly sometimes 2020/10/26 16:59:53 (permalink)
    0
    Here:
     

    typedef union
    {
        struct
        {
            uint8_t startbit_ok         :1;  
            uint8_t taprate_ok          :1; 
            uint8_t timer_handler_ok    :1;
           
            uint8_t not_in_run_mode     :1;
            uint8_t waiting_uart_input  :1;  
            uint8_t use_timeout         :1;   //timeout after counter in ms has expired
            uint8_t ok_to_refresh       :1;   
        } bits;
        struct
        {
            uint8_t comms       :3;
            uint8_t ctrl        :3;
        } fields;

        uint8_t val;
    } watchdog_flag_t;

    typedef struct
    {
      watchdog_flag_t flags;
      uint32_t   timeout_ticks;   //in ms
    } watchdog_t;

    #6
    ric
    Super Member
    • Total Posts : 28943
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: online
    Re: Question about uint32_t values not working correctly sometimes 2020/10/26 17:03:22 (permalink)
    0
    Hmm, always a bit suss having a structure with an 8 bit field followed by a 32 bit field on a 16 bit processor.
    That forces it to either pad the structure, or acces the 32 bit field using byte instructions.
    What happens if you swap the two fields to put the 32 bit one first?
     

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #7
    user2x
    Super Member
    • Total Posts : 445
    • Reward points : 0
    • Joined: 2011/02/10 20:43:36
    • Location: 0
    • Status: offline
    Re: Question about uint32_t values not working correctly sometimes 2020/10/26 18:08:37 (permalink)
    0
    Not sure. But the problem goes when I cast the 1 to a uint32_t in the function call.
    Such as:

    Watchdog_StartTimout_ms((uint32_t)1);

    #8
    1and0
    Access is Denied
    • Total Posts : 11501
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: Question about uint32_t values not working correctly sometimes 2020/10/26 18:08:40 (permalink)
    +1 (1)
    The 8-bit "flags" should be padded to a 16-bit word, and the 32-bit "timeout_ticks" should occupy the next two 16-bit words.
     
    #9
    1and0
    Access is Denied
    • Total Posts : 11501
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: Question about uint32_t values not working correctly sometimes 2020/10/26 18:10:46 (permalink)
    0
    user2x
    Not sure. But the problem goes when I cast the 1 to a uint32_t in the function call.
    Such as:

     
    Watchdog_StartTimout_ms((uint32_t)1);
     


    "goes" or "gone"?  Try 1uL too, but the unqualified 1 should work as is.
    post edited by 1and0 - 2020/10/26 18:12:17
    #10
    1and0
    Access is Denied
    • Total Posts : 11501
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: Question about uint32_t values not working correctly sometimes 2020/10/26 18:15:26 (permalink)
    0
    user2x
    I have a problem:  XC16 1.41

    The latest version is 1.60. ;)
     
    #11
    ric
    Super Member
    • Total Posts : 28943
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: online
    Re: Question about uint32_t values not working correctly sometimes 2020/10/26 18:24:49 (permalink)
    0
    1and0
    The 8-bit "flags" should be padded to a 16-bit word, and the 32-bit "timeout_ticks" should occupy the next two 16-bit words.

    It's less wasteful just to put the larger item first.
     

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #12
    user2x
    Super Member
    • Total Posts : 445
    • Reward points : 0
    • Joined: 2011/02/10 20:43:36
    • Location: 0
    • Status: offline
    Re: Question about uint32_t values not working correctly sometimes 2020/10/26 18:36:02 (permalink)
    0
    Ohh man,
     
    This is a riddle.
    I ran into the problem because the watchdog did not operate as expected this morning.
    From that function particular call.
     
    I then tried stuff and eventually typecast to (uint32_t) and also tried 1L.
    Both times it fixed it.
     
    I have since posted here and also tried playing with the structure arrangement (as per Ric) in making it aligned to 16bit instead of the 8bit.
     
    I have undone the casts to (uint32_t) and also the 1L to test the above
     
    It still worked. 
    so I thought, yay, it is the alignment after all.
    Now I have reverted that, just to see and .....
     
    Same code with the original problem is now working ok.
     
    Is it possible that due to other code changes elsewhere, the memory has aligned differently and it now just works, until it aligns differently again?
     
    I do not understand it.
     
     
     
    #13
    1and0
    Access is Denied
    • Total Posts : 11501
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: Question about uint32_t values not working correctly sometimes 2020/10/26 18:40:53 (permalink)
    0
    I just now tested your code with XC16 v1.60 and it works as it should. ;)
     
    #14
    1and0
    Access is Denied
    • Total Posts : 11501
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: Question about uint32_t values not working correctly sometimes 2020/10/26 18:50:14 (permalink)
    0
    ric
    1and0
    The 8-bit "flags" should be padded to a 16-bit word, and the 32-bit "timeout_ticks" should occupy the next two 16-bit words.

    It's less wasteful just to put the larger item first.

    I just tried this and the two do not overlap share a word; i.e. each 8-bit "flags" occupies its own 16-bit word.
    typedef struct {
      uint32_t   timeout_ticks;   //in ms
      watchdog_flag_t flags;
    } watchdog_t;

    typedef struct {
      watchdog_flag_t flags;
      uint32_t   timeout_ticks;   //in ms
    } watchdog_t2;

    volatile watchdog_t watchdog;
    volatile watchdog_t2 watchdog2;

    post edited by 1and0 - 2020/10/26 18:51:45
    #15
    user2x
    Super Member
    • Total Posts : 445
    • Reward points : 0
    • Joined: 2011/02/10 20:43:36
    • Location: 0
    • Status: offline
    Re: Question about uint32_t values not working correctly sometimes 2020/10/26 19:42:29 (permalink)
    0
    I thought as much. I have not had any issue in the past with this arrangement and I did observe that the alignment is always on 16bit boundaries. So 8 bits are basically wasted by a unit8_t in these cases.
    #16
    user2x
    Super Member
    • Total Posts : 445
    • Reward points : 0
    • Joined: 2011/02/10 20:43:36
    • Location: 0
    • Status: offline
    Re: Question about uint32_t values not working correctly sometimes 2020/10/26 19:45:36 (permalink)
    0
    But that leaves me scratching my head as the problem seems to have disappeared suddenly.
    Which means it will re-appear suddenly at as well =Not good as it can go undetected for quite some time.
     
    #17
    JPortici
    Super Member
    • Total Posts : 1202
    • Reward points : 0
    • Joined: 2012/11/17 06:27:45
    • Location: Grappaland
    • Status: offline
    Re: Question about uint32_t values not working correctly sometimes 2020/10/27 02:30:40 (permalink)
    +1 (1)
    1and0
    user2x
    I have a problem:  XC16 1.41

    The latest version is 1.60. ;)
     




    OP didn't mention the processor.
    If it's a dsPIC33CK/CH it's possible that this is the problem, as there were compiler bugs regarding structures with bitfields, corrected in 1.50
    #18
    user2x
    Super Member
    • Total Posts : 445
    • Reward points : 0
    • Joined: 2011/02/10 20:43:36
    • Location: 0
    • Status: offline
    Re: Question about uint32_t values not working correctly sometimes 2020/10/27 16:22:22 (permalink)
    0
    PIC24FJ64GA702.
    I am not using 'packed' on anything.
     
    I am rather VERY reluctant to change compiler version whilst on a critical path with a project. it has once caused me major problems.
     
    post edited by user2x - 2020/10/27 16:23:45
    #19
    Jump to:
    © 2020 APG vNext Commercial Version 4.5