3

I am unable to solve misra rule 11.6 warning in this line:

uint32_t * delay = (uint32_t *)0x40086D0C ;

[FYI: typedef long unsigned int uint32_t;]

PC-Lint : Note 923: cast from int to pointer [MISRA 2012 Rule 11.6, required]

What I did:

  • Explicitly type-casted, But it doesn't work
  • Use memset(), It is working, but that is not the proper way to solve Misra warning. because that was unnecessary increased function call on the system and it may degrade system performance.

Could you share a helpful thought regarding my issue? It will be really appreciated.

Rishikesh Raje
  • 8,556
  • 2
  • 16
  • 31
Kanji Viroja
  • 493
  • 1
  • 7
  • 17
  • 2
    This code can't be made to comply. –  Dec 08 '16 at 06:12
  • Yes, you were right. But how to solve misra warning in that line? I am looking for solution. Do you have any idea to fix this warning? – Kanji Viroja Dec 08 '16 at 06:15
  • What exactly are you trying to do? Do you want to point `delay` to a set memory address, or to create a pointer with that integer value? –  Dec 08 '16 at 06:16
  • Yes. Actually, I want to access low level memory portion for that I assign address to pointer and these address already memory mapped. – Kanji Viroja Dec 08 '16 at 06:18
  • 1
    http://stackoverflow.com/questions/25720358/reading-a-value-from-raw-memory-misra-compliant – n. m. could be an AI Dec 08 '16 at 06:45
  • Try using linker scripts, which allow you to [assign values to symbols](https://sourceware.org/binutils/docs/ld/Simple-Assignments.html#Simple-Assignments). You'll then just use some global `extern uint32_t *delay;`. No need to break MISRA C. –  Dec 08 '16 at 07:23
  • 1
    I think that the real problem is not with the assignment but with the origins of "0x40086D0C". Where did you get this number from? MISRA-C is actually trying to prevent you making such casts. Don't try to work around. – eyalm Dec 08 '16 at 07:54
  • 1
    I recommend to uninstall Lint since it is an actively harmful tool. Using it leads to safety hazards caused by people trusting the tool, then altering working, MISRA compliant code. – Lundin Dec 08 '16 at 08:59

2 Answers2

5

Lint is broken as always. File a bug report or just uninstall Lint.

MISRA-C:2012 rule 11.6 is regarding cast from pointer to void to pointer of arithmetic type! Thus "cast from int to pointer [MISRA 2012 Rule 11.6, required]" is incorrect nonsense with no relation to the cited rule, which they cite incorrectly.

There is an advisory rule 11.4 regarding integer to pointer conversions. The aim of that rule is to catch cases where such casts would result in incorrectly aligned pointers. You can however ignore rule 11.4 without raising a deviation, since it is advisory.

Thus your code is MISRA-compliant apart from the advisory rule, although you need to append an U suffix to the integer constant to sate other rules:

uint32_t* delay = (uint32_t*)0x40086D0Cu ;

And the pointer should most likely be volatile uint32_t* in order for this code to make any sense.

Lundin
  • 195,001
  • 40
  • 254
  • 396
  • Lint is broken, yes - but only insofar that it is reporting R11.6 and not R11.4. But as you say, R11.4 is (a) Advisory only, but (b) acknowledges that there are times when memory-mapped access is required. – Andrew Sep 24 '19 at 15:52
  • 1
    @Andrew In all fairness, if you want to buy a broken tool, Lint is the way to go. 10 times cheaper than equally broken tools on the market, most bugs for the buck. – Lundin Sep 24 '19 at 20:38
  • :-) :-) :-) :-) – Andrew Sep 25 '19 at 08:16
-1

That is a totally reasonable cast to perform (assuming your pointers are 32 bits). In this case, it's probably better to tell your lint checker to ignore that line. The MISRA rules are there to prevent common cases of bugs, but some operations, like accessing memory-mapped peripherals, can't be done within the spec (as far as I know).

Using memset is a very bad idea - it sets individual bytes, so you'd need 4 memset() calls to set the 4 bytes of the pointer. You could get a similar effect with a single memcpy() call, though I don't think it's in the spirit of the specification.

For both memcpy() and memset(), you shouldn't see any decrease in performance. Any optimizing compiler worth its salt will detect the fixed-size memcpy and replace it with a single 32-bit MOV instruction (or the analog for your platform). Here is an example where clang

  1. replaced the fixed-length memset with a 32-bit move
  2. realized that the value of delay is the same as the value of addr
  3. removed delay entirely
alexkonradi
  • 750
  • 5
  • 5
  • You were right, But if we have added everywhere API call then it is increased push pop operation on stack. – Kanji Viroja Dec 08 '16 at 06:50
  • "That is a totally reasonable cast to perform" Evidently, for certain values of 'reasonable'. This can be fixed in a MISRA C compliant way by the linker. –  Dec 08 '16 at 07:11