3

I'm working on a safety system that requires me to implement 2oo3 voting. I roughly have an idea of implementing this using state machines using function pointers. Assume there are 3 systems, A B C. With respect to A, C is left system and B is right system With respect to B, A is left system and C is right system With respect to C, B is left system and C is right system

For every decision that a system takes,it shall cause the function pointer to point to the "exchange data with left system" function. After data is sent to the Left system it shall point to a dummy function and wait for the Left system to reply.

When the Left system replies and its decision(left system) also agrees with decision made by the system(my system),it shall proceed to the next state. If it disagrees it shall repeat the same with "exchange data with right system" and proceed.

My doubt here is since i dont want to implement using Flags for state transition control,is implementation using function pointers ok cause nowhere does MISRA 2004 onwards say not to use function pointers??

Is the approach to a 2oo3 implementation as above ok or is there something else to be taken care of?

Are there any other approaches to implementing a 2oo3 architecture(No external comparator for decisions made by each system. That is, each uC shall form a decision itself and consult its decision with the other 2.It will not place its decision in an external comparator(ex:shared memory, fpga based comparator etc) for access and comparison by the other 2 systems)??

Please forgive me if i have approached it wrongly. Im a newbie to this.

(Note:The 3 systems have only microcontrollers)

UPDATE: Some Useful points were added by @Lundin here - State Machine design with no function pointers

Community
  • 1
  • 1
AlphaGoku
  • 968
  • 1
  • 9
  • 24
  • is triple voting a software thing? normally isnt that in hardware/logic? How/where do you draw the line as to when to take the vote? For every decision? What about the decision to ask the left system, you need to take a vote about taking a vote? I have heard of three processors being in lock step, logic taking care of that, if two agree okay nobody agrees then I guess you reset or cause the watchdogs to fire...just curious had not heard of software doing this, but me not hearing of it doesn tmean much, could be quite common... – old_timer Jan 12 '16 at 05:42
  • Yes its entirely software doing the 2oo3 voting. Its like there are 3 master processors.For me to proceed to my next state atleast one among the other 2 masters should agree with me.If no one agrees i just stay at that state. Each system takes a voting only for every vital decision. Not for every single minute thing. – AlphaGoku Jan 12 '16 at 05:56
  • "nowhere does MISRA 2004 onwards say not to use function pointers" - MISRA C:1998 Rule 104 – AlphaGoku Feb 12 '16 at 04:21

1 Answers1

2

My doubt here is since i dont want to implement using Flags for state transition control,is implementation using function pointers ok cause nowhere does MISRA 2004 onwards say not to use function pointers??

Where did you get that idea from? There is nothing in any MISRA-C standard that forbids the use of function pointers. MISRA-C barely mentions function pointers at all. The only thing MISRA-C does not allow is wild casts between function pointers and regular pointers, since that invokes undefined behavior.

The de facto standard way of implementing state machines is usually with a state variable, such as an enum, which points out the index in an array of function pointers. Here is a typical example, which at a brief glance seems to be 100% MISRA compliant.

Is the approach to a 2oo3 implementation as above ok or is there something else to be taken care of?

Nobody can tell without knowing your requirements. Usually when designing such safety-critical systems (majority voter), you want the actual "vote" to be located in hardware outside the CPUs though, since the whole purpose of it is to protect against malfunctioning sub systems/CPUs. (The "voter" hardware itself may be supervised in turn.) Therefore, there are some issues with your approach:

  • Main issue: if A polls B, but A itself has gone haywire, it will then "lie" about the vote cast by B. Essentially the corrupt node A would then gain 2 votes and the whole safety of the system will fail. The whole purpose of redundancy systems is to protect against processors/programs going haywire. If none of the involved CPUs/sub systems will never go haywire, why would you need the majority voter to begin with? What is the failure you are trying to protect yourself from?

  • If A polls B for some vote and B never responds, or responds with nonsense, then what? This scenario needs to be stated in your specification. Timeouts, error detection, behavior upon error etc etc.

Also consider: "majority voter" is some old 80s buzzword technique. It may or may not make sense: it may improve safety or it may be complete nonsense. Be aware of designing in false safety and be aware of dangerous "safety" standards blinding preaching to use majority voter without knowing the specifics of your system.

The "SIL" 61508/26262 standards might be particularly dangerous to blindly trust here, as they lack rationale/modern sources for recommending "majority voter". See for example IEC 61508-7 A.1.4, it's complete nonsense: sources are technical papers only available in German, from the 80s. Laugh or cry?

Applying common sense is much more important than the contents of those standards!

Why would you ever want to use 2 out of 3 in a safety-critical system? That's 33% of the system failing, why would you wish the system to continue running in such a scenario? In many systems 33% of the system failing would be rather catastrophic... Similarly, a "diagnostic coverage" of 66% would be considered extremely poor in many systems.

The whole safety system design really depends on what is considered as the safe state and what to do upon critical failure. Is the safe state "stop everything" (typical industrial application) or is it "keep running/limping as well as you are able" (typical automotive/medical application).

Again, it all points back at the specification, which is extremely important to get right for these kind of systems.

Community
  • 1
  • 1
Lundin
  • 195,001
  • 40
  • 254
  • 396
  • I generally prefer function pointers to keep changing state transitions based on events so i went for that approach. Main issue- even if A goes haywire and proceeds with its decision,the external hardware driven will in turn operate if 2oo3 systems are consistent in their decision(ur right,only difference is an external software can in turn do 2oo3 based on the decisions from the 3 systems and control an output).[link](https://law.resource.org/pub/in/bis/S05/is.iec.61508.7.2000.pdf)-its completely in English :). System may go on 2 oo 3 (if not for safety primarily) for greater availability. – AlphaGoku Jan 12 '16 at 10:30
  • Functions pointers are simpler than using struct(i feel). If A happens point to fA. Else keep pointing to fB. Simple :) – AlphaGoku Jan 12 '16 at 10:31
  • @akshimmu I was not talking about the standard itself... I do of course have a (legal) copy in English of that. I was talking to the very questionable sources the standard lists. – Lundin Jan 12 '16 at 10:39
  • Ya but thats what the V&V team holds on to. So i wont have any base trying to prove the authenticity of the standards. Ya my main doubt was about the function pointer approach. Thanks for clearing that wrt MISRA. But why do safety applications not insist on using function pointers? – AlphaGoku Jan 12 '16 at 11:02
  • @akshimmu Again, there are no restrictions against using function pointers. The only reason you would avoid them is if you are designing on some 80s technology platform with non-standard compilers, in which case the use of function pointers is the least of your problems. – Lundin Jan 12 '16 at 11:47
  • @Lundin- looking at your profile,you seem exactly like the guy that should be advising me. Thanks :) appreciate it. Any references stating justification for use of function pointers in safety systems would be useful. Else this is sufficient. – AlphaGoku Jan 12 '16 at 12:12
  • @akshimmu They are just language components like anything else. All arguments against function pointers are either historical, or they are related to performance. – Lundin Jan 12 '16 at 12:22
  • Though there is an incredibly misguided "limited pointers" rule in the "SIL" standards saying that pointers in general should be avoided, but they are not anywhere close to even hinting at a sound rationale for it. Whoever came up with that rule could not have been a professional/competent programmer, so just ignore it as the nonsense it is. Things like this is what causes the "SIL" standards to be such dangerous safety hazards: they are a mix of very sound, proven design advise mixed with complete nonsense taken out of the blue. – Lundin Jan 12 '16 at 12:24
  • Exactly...its like i give you 10 dollars(C language) but ask you to use only 5 dollars(restrictions on C) to solve a 7 dollar problem.. :) – AlphaGoku Jan 12 '16 at 12:51
  • [Function Pointer Cant be used in Safety System](http://spinroot.com/gerard/pdf/P10.pdf)... this doc is by NASA and says function pointers cant be used. Why does MISRA not claim that? – AlphaGoku Jan 22 '16 at 09:53
  • Rule 9: The use of pointers should be restricted. Specifically, no more than one level of dereferencing is allowed. Pointer dereference operations may not be hidden in macro definitions or inside typedef declarations. Function pointers are not permitted. – AlphaGoku Jan 22 '16 at 09:54
  • @AkshayImmanuelD It's the very same, brain-damaged rule as in IEC61508, with the very same (lack of) rationale: "easily misused" which is rubbish. The same can be said about plain integers. In fact plain integers is involved in the vast majority of all bugs so by using the same rationale, we should therefore ban the use of integers. That being said, you _can't_ avoid using pointers and you _can't_ avoid using function pointers. How do you for example write an interrupt vector table in C without using function pointers? Hard code the addresses manually each time you link the project? – Lundin Jan 22 '16 at 10:22
  • As for static analysers being unable to detect recursion because of function pointers, that's true, but that's because the vast majority of static analysers on the market are _crap_, even in 2016. I just confirmed that mine (LDRA) couldn't detect the simplest kind of recursion through a function pointer. You shouldn't let that affect the way you write programs though. As long as common sense is activated, you will of course not be using recursion, so it is a non-issue. – Lundin Jan 22 '16 at 10:23
  • As for why MISRA doesn't have the rule, they did inherit some of the nonsense from 61508 in the form of MISRA-C:2004 17.4 "array indexing should be the only form of pointer arithmetic". This was some sort of failed attempt to make the requirements in 61508 make sense. Since it was a rubbish rule which did noting to increase safety, it was removed in MISRA-C:2012. (In general, MISRA is far more responsive than most other such safety organizations and will actually remove flawed rules if you just point out why they should be removed. One advantage of not being an ISO/IEC standard I would guess.) – Lundin Jan 22 '16 at 10:30
  • Conclusion: Just because a static analyser tool cant validate function pointers I cant use function pointer? Safety related no violations as per EN 50128 – AlphaGoku Jan 22 '16 at 12:22
  • I had a chance to speak to [Dr.Michael Hennell](https://en.wikipedia.org/wiki/Michael_Hennell) at a LDRA conference. He said its completely OK to use function pointers even in safety critical code. I have the audio recording of the chat with him. If anyone needs it,plz do ask. He went up even to the point that even recursion can be used(not infinite recursion,controlled recursion) – AlphaGoku Feb 08 '16 at 04:18
  • `void f1(int *ptr); void f2(int *ptr); void (*const fpTest[2])(int *ptr1)={f1,f2}; int b[2][2]={{0,1},{2,3}}; void f1(int *ptr) { int a=0; int b=0; a=ptr[0]; b=ptr[1]; printf("%d\n",a); printf("%d\n",b); } void f2(int *ptr) { int a=0; int b=0; a=ptr[0]; b=ptr[1]; printf("%d\n",a); printf("%d\n",b); } int main() { (*fpTest[0])(b[0]); (*fpTest[1])(b[1]); return 0; }` Based on inputs from @Lundin and Dr.Michael Hennell, im planning on implementing my code this way – AlphaGoku Feb 10 '16 at 04:38
  • @AkshayImmanuelD Remember to use a typedef for the function pointer type. – Lundin Feb 10 '16 at 07:50
  • Ya thanks. Will keep that in mind. Just wanted to give a brief idea how I plan on implementing it. Il also check the array value passed when i use a global variable to call the functions. – AlphaGoku Feb 10 '16 at 09:01
  • @Lundin - I'm a German native speaker, and I to looked up IEC16508-7:2010, sec. A.1.4 "Majority voter". The section references a [book edited by the American Institute of Chemical Engineers](https://www.aiche.org/ccps/publications/books/guidelines-safe-automation-chemical-processes) in 1993 (in English, of course). This period between the editions of the scientific sources and the international industry standards is hardly evitable, taking into account several years to finish an IEC standard. Foreign languages are a matter of course in scientific communication (this applies for any language). – HelpingHand Apr 16 '20 at 08:12
  • The argument about 33% doesn't hold. Errors are estimated on the basis of independent error events (aside from common-cause errors). The probability of multiple errors coinciding within a limited period of time is substantially lower than that of each single error. A 2oo3 system (if well-done...) is able (a) to detect single (non-common-cause) error events and trigger repairs, and (b) to remain available for safe operation in a degraded mode. If repairs are carried out in time, this is a huge advantage without reducing safety, especially in process industry where reaction times are "slow". – HelpingHand Apr 16 '20 at 08:23
  • 1
    @HelpingHand It's hard to speak of such techniques from a general point of view. In industrial control, the safe state is typically to stop everything upon detecting any error. In automotive or med-tech, it is the opposite - you are never allowed to stop but must keep going despite errors ("limp home"), in the safest manner achievable. So as mentioned in this old answer, majority voter might make perfect sense or it might be utter nonsense, depending on the nature of the safety application. – Lundin Apr 16 '20 at 09:45