Menu

Is there a hint to indicate that volatile pointers correspond to MMIO registers?

Tim Gover
2020-07-30
2020-07-31
  • Tim Gover

    Tim Gover - 2020-07-30

    Is there a method or hint to indicate that "volatile uint32_t pointer" variables correspond to MMIO hardware registers so that certain checks can be skipped?

    This causes a knownConditionTrueFalse error in the if statement after the loop

    volatile uint32_t *reg = (volatile uint32_t *) 0xffff1234;
    int retries = 1000;
    while ((*reg & 0x1) && retries-- > 0)
        ;
    if (retries <= 0)
       return -1;
    

    Also, if when there are multiple writes to the same hardware register in sequence cause redundantAssignment errors but it's quite common to require separate writes for an 'enable bit' and the 'config bits'

    I'm using cppcheck v2.1 with "--enable=all --inconclusive" .

    I'm be happy to wrap bits of the code above in a macro as a HINT because cppcheck is generally very useful with a great signal to noise ratio!

     
  • Andreas Grob

    Andreas Grob - 2020-07-30

    The part with knownConditionTrueFalse could be related to or identical to https://trac.cppcheck.net/ticket/9808 .

     

    Last edit: Andreas Grob 2020-07-30
  • Tim Gover

    Tim Gover - 2020-07-30

    Thanks, moving the decrement outside of the loop condition resolved the knownConditionTrueFalse warnings

     
  • Daniel Marjamäki

    hmm.. I guess redundantAssignment should not warn about volatile variables.

    Also cppcheck could assume that pointers with a fixed address are hardware related.

    Which checks do you have problems with?

     
  • Daniel Marjamäki

     
  • Daniel Marjamäki

    which checks do you see problems with for volatile variables?

     
  • Tim Gover

    Tim Gover - 2020-07-31

    Here's a simplified example of the issue. Whist creating this I noticed that using read-modify-write (&= |=) avoids the error or inserting a nop between the assignments also avoids the error.

    That's probably a hint that I should tidy up the old code although skipping a read where it's unecessary for a hardware register is fairly common

    #include <stdint.h>
    
    #define DISP_CTL_RESET_LSB 0
    
    void display_reset(void)
    {
        volatile uint32_t *disp_ctl = (volatile uint32_t*) 0xffff1234;
    
        // Assert reset
        *disp_ctl = (1 << DISP_CTL_RESET_LSB);
    
        // De-assert reset
        *disp_ctl = 0;
    
    }
    
    im@timvm::~$ cppcheck --inconclusive --enable=all ./cpp-redundantAssigment.c 
    Checking cpp-redundantAssigment.c ...
    cpp-redundantAssigment.c:13:15: style: Variable '*disp_ctl' is reassigned a value before the old one has been used. [redundantAssignment]
        *disp_ctl = 0;
                  ^
    cpp-redundantAssigment.c:10:15: note: *disp_ctl is assigned
        *disp_ctl = (1 << DISP_CTL_RESET_LSB);
                  ^
    cpp-redundantAssigment.c:13:15: note: *disp_ctl is overwritten
        *disp_ctl = 0;
                  ^
    cpp-redundantAssigment.c:5:0: style: The function 'display_reset' is never used. [unusedFunction]
    
     

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.