3

I'm working on an industrial code for Cortex-M0 controller, using uVision Keil 4.71.0.0 IDE. Our code is supposed to respect MISRA rules and is routinely checked with QA-C.

My problem is that some controller-specific functions like __wfi(), __current_sp() etc. don't seem to be defined anywhere, and QA-C is complaining about them:

340:                __wfi();
                       ^
Msg(5:3335) No function declaration.
Implicit declaration inserted: 'extern int __wfi();'.
CC Coding Rule 6 <next>

Right-clicking on the function name in Keil and selecting "Go to definition" confirms that the function is not defined:

Source Browser: '__wfi' - undefined Definition/Reference!

Does Keil provide an official header file with prototypes of such functions? Hardcoding such prototypes in our project's code or creating QA-C exceptions will require a formal review process which I would like to avoid.

Dmitry Grigoryev
  • 3,156
  • 1
  • 25
  • 53

3 Answers3

2

These are called compiler intrinsics and I'm not sure they need to be declared. They are basically extensions to the language provided by the compiler.

unwind
  • 391,730
  • 64
  • 469
  • 606
  • Obviously they don't need to be declared, since our code compiles and works fine. What I'm looking for is a way to present them in a way conforming to MISRA rules. For example, using `sqrt()` function instead of `__sqrt()` intrinsic would solve my problem. Do similar wrapper functions exist for other intrinsics? – Dmitry Grigoryev May 22 '15 at 09:34
  • I don't think so, no. The case for math functions is special, since e.g. `sqrt()` is part of the standard library, the standard library implementor (=Keil, in your case) can of course choose to use their compiler's intrinsics in the implementation. There is no parallel case for "turn off the interrupts", the standard library doesn't support doing that. – unwind May 22 '15 at 09:42
  • Ok, thanks for clearing up the technical side of the question. I accepted @Lundin's answer since the issue has more to do with MISRA conformance. – Dmitry Grigoryev May 22 '15 at 10:02
2

I don't believe those are regular functions, but rather non-standard built-in functions that get in the generated binary get replaced with assembler code. See this.

There are 3 MISRA rules to consider here and they are not necessarily harmonized with each other:

  • All code must follow ISO C.
  • All functions must have prototypes.
  • All use of assembly language must be encapsulated and documented.

What I would do is to move all these "function calls" to a separate file and document that this file contains all invokations of inline assembly in your program. You probably need such a file to sate other MISRA rules regarding inline assembly. State that these functions are used to encapsulate assembler. Then exclude it from your static code analysis, unless the static analyser has support for the given assembler and/or "ARM intrinsics".

If you do like this, I think you will conform 100% to MISRA without the need of raising a deviation. Simply state that the ARM intrinsics are your way of encapsulating inline assembly.

Lundin
  • 195,001
  • 40
  • 254
  • 396
  • Moving these functions to a separate file is not an option, since that would require modification of many files, followed by code review of modified files. It would be helpful to have a link to a credible source saying that such functions can deviate from MISRA-C. Perhaps I will look in Keil documentation. – Dmitry Grigoryev May 22 '15 at 09:44
  • 3
    @DmitryGrigoryev Creditable source: MISRA-C:2004 rule 2.1 or MISRA-C:2012 directive 4.3. Needless to say you probably can't run static analysis on that file, as it would not be written in C. Perhaps it will suffice to say that those "intrinsics" are the encapsulation. At any rate, you will need to document what they do. The advantage of having a separate file is that the source code comments can then be your documentation. – Lundin May 22 '15 at 09:49
  • @DmitryGrigoryev More problematic is that the compiler uses double underscore for those names, which is explicitly forbidden in C. 7.1.3: `All identifiers that begin with an underscore and either an uppercase letter or another underscore are always reserved for any use.`. Your compiler does not conform to the C standard if it uses double underscore naming. – Lundin May 22 '15 at 09:53
  • Well, I think every compiler uses those (GCC `__builtin_xxx()` for example), so I don't see the problem. C standard reserves them exactly for this reason - so that compilers can freely define them without the fear of breaking someone's C code. – Dmitry Grigoryev May 22 '15 at 10:07
  • @DmitryGrigoryev Nope. "Reserved for any use" means nobody but the C standard itself may use such identifiers. This is different from "reserved for the implementation", which means that the compiler may use it but the programmer may not. That GCC doesn't follow the standard either is no excuse for another compiler to be non-compliant. – Lundin May 22 '15 at 11:06
0

As written bevor it is from the Compiler. I don`t think you have them in source. Maybee you find something written in the Keil or ARM Compiler Guideline, that helps you(I have already no KEIl installed, to have a look on my own).

It may be possible to get a define for this function with a special Compiler command (IAR Compiler have something like this).

If this all not works you can make an exception in QA-C (Don`t know it) to ignore this function because it is from the Compiler or to specify a dummy-function for QA-C.

Founbd this

http://www.keil.com/support/man/docs/armccref/armccref_CJADIFCI.htm