5

I'm currently working on a project, which has to be MISRA 2012 compliant. But in the embedded world, you can't fulfill every MISRA rule. So I have to suppress some messages generated by QA-C. What's he best solution to do this?

I was thinking about making a table in every module header file with references (\ref and \anchor) to the relevant code lines, a description, etc. The first problem is: I can't use the Doxygen markdown table feature, because then the description has to be in one line, because Doxygen tables don't support line breaking. So I thought about using a simple verbatim table, what do you think?

Or is there a way to generate such a table automatically?

Greetings m0nKeY

m0nKeY
  • 171
  • 1
  • 5
  • 1
    In its current form, your questions are too broad to be answerable here. In addition, questions such as "what's the best solution," or "what do you think" suffer (by the very nature of the question) from the additional problem of being primarily opinion-based. It is hard to find a programming-related question in your question - see the help section about "How to ask," as well as visiting the tour page and FAQs. – frasnian Jan 08 '15 at 07:48
  • 1
    "In the embedded world, you can't fulfill every MISRA rule" That sentence is funny to me because MISRA is for the embedded world and nothing else. I'd agree more if the statement were: "There are compiler/proprietary things that make being MISRA complient difficult sometimes, and sometimes multiple coding standards in an organization can contradict and in those instances rules in one or the other need to be carefully loosened." – Nick Jan 08 '15 at 16:50
  • Sorry for "In the embedded world, you can't fulfill every MISRA rule". Poorly fomulated. – m0nKeY Sep 23 '15 at 12:53

2 Answers2

2

According to MISRA, all such undesired rules must be handled by your deviation procedure, given that they are either "required" or "advisory". You are not allowed to deviate from "mandatory" rules. (Strictly speaking, you don't need to invoke the deviation procedure for advisory rules.)

In my experience, the safest and smoothest way by far to do this, is to not allow individual deviations on case-by-case basis. All deviations from MISRA should be stated in your company coding standard, and in order to deviate you have to update that document. Which in turn enforces approval from the document owner, who is preferably the most hardened C veteran you have in the team.

That way, you prevent less experienced team members from misinterpreting the rules and ignoring important rules, simply because they don't understand them and mistake them for false positives. There should be a rationale in the document stating why the rule you deviate from is not feasible for your company.

This means that everyone in the dev team is allowed to deviate from the listed rules at any point, without the need to invoke any form of bureaucracy.

Once you have a setup like this, simply customize your static analyser and remove/ignore the undesired warnings. That way, you get rid of a lot of noise and false warnings from the tool.

Lundin
  • 195,001
  • 40
  • 254
  • 396
  • I need to break MISRA rules sometimes on a case by case basis because I have another coding standard in the mix. Specifically the company coding standard says do not prototype ISRs. But MISRA says all functions shall have a prototype. In general we want to leave the MISRA rule turned on though because we want to comply with the MISRA rule everywhere else. We've considered doing is adding our own \xrefitem to extract all exceptions into a doxygen list as well, but for this limited case it simply becomes a list of all of our ISRs which isn't terribly necessary. – Nick Jan 08 '15 at 16:47
  • @Nick Any particular reason why ISRs wouldn't have a prototype? On most systems they need one, particularly on microcontroller systems with interrupt vector tables written in C. Anyway, what you can do for a case like that is to leave the rule on, but write an exception to the rule in some "global" document. You'll no doubt have to use non-standard syntax when writing the interrupt too, so you have to deviate from the "all code should be standard C" rule in exactly the same way. – Lundin Jan 09 '15 at 07:16
  • 1
    You're exactly right, you will need to use a `#pragma vector=foo` anyway for the interrupt or some intrinsic `__interrupt`. If the static analyzer gives you the ability to run a script prior to parsing the source directory you can automatically replace such strings so to avoid having to actually relax the MISRA rule. Otherwise you may be able to annotate around the violation so as to filter the violation. But you are right, I am be documenting something like: "ISRs are an exception to rule X" globally. But I want to leave the rule 'ON' in the static analyzer for everything else. – Nick Jan 09 '15 at 15:19
  • The ISR rules are as follows: 1) All ISR names need to end with _isr to make it clear to the reader it is an ISR (in case it wasn't already by the `#pragma` or whatever. 2) All ISRs shall be static to ensure they cannot be called from elsewhere in the application and shall be located in the file for the driver the belong to. 3) ISRs shall lack a prototype and be located at the end of the file to ensure they can't be accidentally called from within the module. In summary: ISRs should not be 'callable' functions. A static analyzer may look at an ISR and assume it is dead code and complain. – Nick Jan 09 '15 at 15:26
  • @Nick I think your coding rules will create problems for you, it seems they were created with a specific system in mind, and not to be generic. In case of the vector table, you want a function pointer to the ISR, which in turn creates a need for a function prototype. Of course you could write such a table as a collection of "magic numbers" (ISR addresses) but then you only created a less readable program. Apart from that, you can make an ISR `static` and have a static function prototype. This will make it impossible to call the function externally while remaining MISRA compatible. – Lundin Jan 11 '15 at 14:30
  • @Nick In fact I'm pretty sure than MISRA enforces you to make it static since the function only has local scope and you don't seem to reference it from elsewhere. – Lundin Jan 11 '15 at 14:31
1

To answer your question generally: To create an aggregate occurrence list of anything in doxygen, use \xrefitem

We use this as a tool in our code review process. I tag code with a custom tag \reviewme which adds the function to a list of all code in need of peer review. The next guy can come along and clear that tag. We have another custom tag \reviewedby which does not use \xrefitem but simply puts the reivewers name and the date in the code block saying who reviewed it and when. This had gotten a bit clunky as things have scaled with larget code bases and more developers. Now we're looking into tools that integrate with our version control process to handle this better. But when we started this it worked well and fit a shoestring budget. But that example should give you an idea of is capable.

Here is a screen shot of what the output looks like - proprietary stuff and auto names redacted:

Here is how we added this custom tag as an alias to xrefitem in our doxy file as follows

ALIASES = "reviewme = \xrefitem reviewme \"This section needs peer review\" \"Documentation block or code sections that need peer review\""

To add it from the GUI, you would go to Expert->Project->Aliases and add a line like this

reviewme = \xrefitem reviewme "This section needs peer review" "Documentation block or code sections that need peer review"

Same thing, just no need to put quotes around the whole thing and escape out the inner quotes.

\xrefitem is the underpinning of how things like \todo or \bug work in doxygen. You can make a list of just about anything your heart desires.

Speaking specifically to MISRA exceptions: Lundin's post has lot's of merit. I would consider it. I think a better place to document exceptions to coding standards is in the static analysis tool its self. Many tools have their own annotations where you can categorize the rule violation as 'excused' or whatever. But generally this does not remove them from the list, it allows you just to filter or sort them. Perhaps you can use REGEX in a script that runs prior to doxygen that will replace the tool specific annotation with a custom \xrefitem if you are really concerned. Or vice vera, replace the doxy annotation with your tool's annotation.

albert
  • 8,285
  • 3
  • 19
  • 32
Nick
  • 1,361
  • 1
  • 14
  • 42