MISRA Discussion Forums
Rule 13.5 - Printable Version

+- MISRA Discussion Forums (https://forum.misra.org.uk)
+-- Forum: MISRA C (https://forum.misra.org.uk/forumdisplay.php?fid=4)
+--- Forum: MISRA C:2012 and MISRA C:2023 guidelines (https://forum.misra.org.uk/forumdisplay.php?fid=21)
+---- Forum: 8.13 Side effects (https://forum.misra.org.uk/forumdisplay.php?fid=168)
+---- Thread: Rule 13.5 (/showthread.php?tid=1667)



Rule 13.5 - TomDK - 17-11-2023

In our first project with MISRA we have a question.
 
The couple of “issues” with MISRA 2012 rule 13.5:
 
Variables:
volatile uint8_t bMakeAlarm; (from interrupt)
uint8_t bRelay;
uint8_t bCountSW2High;
uint8_t bPlayerPlaying;
 
Info: SW2 = (PORTA.IN & (uint8_t)PIN5_bm) is a “register” (CPU)
 
Original if statement
 
if (SW2 == 0U || bMakeAlarm != 0U || bRelay != 0U || bCountSW2High != 0U || bPlayerPlaying != 0U)
{
  do_something;
}
 
This makes the message 13.5 because bMakeAlarm is volatile.
 
If I change it a little bit to (removing the volatile):
 
if (SW2 == 0U || bRelay != 0U || bCountSW2High != 0U || bPlayerPlaying != 0U)
{
  b100mSCount = 0U;
}
 
This complies with MISRA. However if change it to this which is normally basically the same:
 
if (bRelay != 0U || SW2 == 0U || bCountSW2High != 0U || bPlayerPlaying != 0U)
{
  b100mSCount = 0U;
}
 
This not comply with 13.5, why?
 
Like in recommendations for the rule 13.5 this will work:
 
SW2hold = SW2;
bMakeAlarmHold = bMakeAlarm;
   
if (bRelay != 0U || SW2hold == 0U || bMakeAlarmHold != 0U || bCountSW2High != 0U || bPlayerPlaying != 0U)
{
  b100mSCount = 0U;
}
 
What is the best solution?
But not super readable and could lead to faults if you do not remember that the xxxHold is just a temp. Any other good work-a-rounds?

Thanks  Smile




RE: Rule 13.5 - misra-c - 13-03-2024

Can you confirm the full declaration/definition of SW2?

The R.13.5 violation implies that SW2 is also volatile, or is a macro that contains a volatile (PORTA?)


RE: Rule 13.5 - misra-c - 02-07-2024

Updated answer

>> Info: SW2 = (PORTA.IN & (uint8_t)PIN5_bm) is a “register” (CPU)

PORTA.IN will be a volatile - hence if its position is anywhere other than the left-hand of the first logical operator, it is a violation of R.13.5

The "workaround" is, as you show, to read the volatiles into temporary variables (which the compiler will optimise away!) - if you make this a block-scope and have appropriate comments, this should be clear.