EmbeddedRelated.com
Forums
Memfault Beyond the Launch

MISRA Rule 45

Started by Mikael Lundqvist March 14, 2005
Hi!

I would like to define a pointer to a hardware register. I have done as follows:


typedef unsigned int Hw_Register;

volatile Hw_Register* const gp_dor_address = (Hw_Register* const)0x84501500;


When checking against MISRA I get the following error:

line 74: error #1703-D: MISRA Rule 45:
cast
          from type "unsigned int" to type "Hw_Register *" not allowed
  volatile Hw_Register* const gp_dor_address = (Hw_Register*
const)0x84501500;


How do I define a constant pointer to a register according to MISRA?

Regards,
Mikael Lundqvist
Well,
I guess because you are hiding the unsigned int by a typedef.
MISRA rule 45 does not allow that.

> How do I define a constant pointer to a register according to MISRA?
I guess you are in a dilemma here. Hardware related implementations (no matter which compiler/toolchain) usually employ coding mechanisms that MISRA rules see as "dangerous". Which in a larger context of a huge application may make sense. The low level stuff however is very hard - if not impossible - to implement following MISRA. Perfectly legal expressions (according to ANSI) like: unsigned int *ptr; ptr = (unsigned int *)0x67a9; *ptr = 0xaa55; *(int * const)(0x67a9) = 0xaa55; Trigger a massive wave of MISRA error messages: MISRA C rule 53 violation: [R] all non-null statements shall have a side-effect 17: *(int * const)(0x67a9) = (unsigned int* const)0xaa55; MISRA C rule 13 violation: [A] specific-length typedefs should be used instead of the basic types MISRA C rule 44 violation: [A] redundant explicit casts should not be used MISRA C rule 45 violation: [R] type casting from any type to/from pointers shall not be used MISRA C rule 13 violation: [A] specific-length typedefs should be used instead of the basic types MISRA C rule 44 violation: [A] redundant explicit casts should not be used MISRA C rule 45 violation: [R] type casting from any type to/from pointers shall not be used MISRA C rule 53 violation: [R] all non-null statements shall have a side-effect Anyone proficient in embedded C programming will use these expressions (together with volatile) to describe Special Funtion Registers or device I/O adresses. At best you disable MISRA for hardware dependend modules, document why you have done so and use lint to check for any suspicious code constructs. regards /jan Mikael Lundqvist <programmer_71@hotmail.com> schrieb in im Newsbeitrag: 4cd9ba3a.0503140615.35565489@posting.google.com...
> Hi! > > I would like to define a pointer to a hardware register. I have done as
follows:
> > > typedef unsigned int Hw_Register; > > volatile Hw_Register* const gp_dor_address = (Hw_Register*
const)0x84501500;
> > > When checking against MISRA I get the following error: > > line 74: error #1703-D: MISRA Rule 45: > cast > from type "unsigned int" to type "Hw_Register *" not allowed > volatile Hw_Register* const gp_dor_address = (Hw_Register* > const)0x84501500; > > > > > Regards, > Mikael Lundqvist
Jan Homuth wrote:

> Well, > I guess because you are hiding the unsigned int by a typedef. > MISRA rule 45 does not allow that. > > >>How do I define a constant pointer to a register according to MISRA? > > > I guess you are in a dilemma here. > > Hardware related implementations (no matter which compiler/toolchain) > usually employ coding mechanisms that MISRA rules see as "dangerous". > Which in a larger context of a huge application may make sense. > The low level stuff however is very hard - if not impossible - to implement > following MISRA. > > Perfectly legal expressions (according to ANSI) like: > > unsigned int *ptr; > ptr = (unsigned int *)0x67a9; > > *ptr = 0xaa55; > > *(int * const)(0x67a9) = 0xaa55; > > Trigger a massive wave of MISRA error messages: > > MISRA C rule 53 violation: [R] all non-null statements shall have a > side-effect > 17: *(int * const)(0x67a9) = (unsigned int* const)0xaa55; > MISRA C rule 13 violation: [A] specific-length typedefs should be used > instead of the basic types > MISRA C rule 44 violation: [A] redundant explicit casts should not be used > MISRA C rule 45 violation: [R] type casting from any type to/from pointers > shall not be used > MISRA C rule 13 violation: [A] specific-length typedefs should be used > instead of the basic types > MISRA C rule 44 violation: [A] redundant explicit casts should not be used > MISRA C rule 45 violation: [R] type casting from any type to/from pointers > shall not be used > MISRA C rule 53 violation: [R] all non-null statements shall have a > side-effect > > Anyone proficient in embedded C programming will use these expressions > (together with volatile) to describe Special Funtion Registers or device I/O > adresses. > > At best you disable MISRA for hardware dependend modules, document why you > have done so and use lint to check for any suspicious code constructs. > > > regards > /jan > > Mikael Lundqvist <programmer_71@hotmail.com> schrieb in im Newsbeitrag: > 4cd9ba3a.0503140615.35565489@posting.google.com... > >>Hi! >> >>I would like to define a pointer to a hardware register. I have done as > > follows: > >> >>typedef unsigned int Hw_Register; >> >>volatile Hw_Register* const gp_dor_address = (Hw_Register* > > const)0x84501500; > >> >>When checking against MISRA I get the following error: >> >>line 74: error #1703-D: MISRA Rule 45: >>cast >> from type "unsigned int" to type "Hw_Register *" not allowed >> volatile Hw_Register* const gp_dor_address = (Hw_Register* >>const)0x84501500; >> >
You could also define all the relevant symbols in an assembly file, then define the symbols as "extern" in your code. If MISRA has some way of temporarily turn off a rule (i.e. with a "#pragma" command or the like) then it may be a good thing to do, with a slew of comments as to why you're doing it. -- Tim Wescott Wescott Design Services http://www.wescottdesign.com
Jan Homuth wrote:
> > I guess because you are hiding the unsigned int by a typedef. > MISRA rule 45 does not allow that. > >> How do I define a constant pointer to a register according to MISRA? > > I guess you are in a dilemma here. > > Hardware related implementations (no matter which compiler/toolchain) > usually employ coding mechanisms that MISRA rules see as "dangerous". > Which in a larger context of a huge application may make sense. > The low level stuff however is very hard - if not impossible - to > implement following MISRA.
Registers don't have addresses whose value can be taken. This is illegal in any form of C.
> > Perfectly legal expressions (according to ANSI) like: > > unsigned int *ptr; > ptr = (unsigned int *)0x67a9;
legal, but not portable.
> > *ptr = 0xaa55;
perfectly legal anywhere, provided ptr has been initialized to point somewhere legal.
> > *(int * const)(0x67a9) = 0xaa55;
You can't cast the lvalue. You can only cast the value to be put into it. Illegal everywhere.
> > Anyone proficient in embedded C programming will use these > expressions (together with volatile) to describe Special Funtion > Registers or device I/O adresses.
You shouldn't need the assistance of MISRA to avoid those particular foul-ups. BTW, please don't top-post, and please do snip. The practice of top-posting a complete snipped bottom posted message only clutters the world with further useless verbiage. -- "If you want to post a followup via groups.google.com, don't use the broken "Reply" link at the bottom of the article. Click on "show options" at the top of the article, then click on the "Reply" at the bottom of the article headers." - Keith Thompson
In article <4cd9ba3a.0503140615.35565489@posting.google.com>, 
programmer_71@hotmail.com says...
> Hi! > > I would like to define a pointer to a hardware register. I have done as follows: > > > typedef unsigned int Hw_Register; > > volatile Hw_Register* const gp_dor_address = (Hw_Register* const)0x84501500; > > > When checking against MISRA I get the following error: > > line 74: error #1703-D: MISRA Rule 45: > cast > from type "unsigned int" to type "Hw_Register *" not allowed > volatile Hw_Register* const gp_dor_address = (Hw_Register* > const)0x84501500; > > > How do I define a constant pointer to a register according to MISRA?
Two options AFAIK 1- if your linker supports it you can define it there. GNU ld can be used in that fashion. 2- Use MISRAs exception capability and use the form you are using but document it as an exception. At least the last revision of MISRA I read had a provision for exceptions. Robert
CBFalconer <cbfalconer@yahoo.com> wrote:

> >Registers don't have addresses whose value can be taken. This is >illegal in any form of C. >
You've never worked on a processor, whose initial register set starts at address 0? Very handy to run a programm just out of the registers, especially when testing core memory! Andreas -- It's not the things you don't know what gets you into trouble. It's the things you do know that just ain't so. - Will Rogers
In article <4235B55D.44F1CDAB@yahoo.com>, cbfalconer@yahoo.com says...
> Registers don't have addresses whose value can be taken. This is > illegal in any form of C.
Come now, "memory mapped register" is surely a fairly common usage. And referring to memory as a "register file" may be old-fashioned but I do seem to recall seeing the term in documentation recently (just don't ask me for a reference).
>Jan Homuth wrote: > > Perfectly legal expressions (according to ANSI) like: > > > > unsigned int *ptr; > > ptr = (unsigned int *)0x67a9; > > legal, but not portable.
On the other hand, peripheral reigster definition is pretty much inheritly non-portable. Robert
Mikael Lundqvist <programmer_71@hotmail.com> wrote:

> I would like to define a pointer to a hardware register.
[...]
> When checking against MISRA I get the following error:
The main problem is that you even tried to apply a portability / safety oriented C coding ruleset such as MISRA to this strictly hardware-specific task. That makes no sense.
> How do I define a constant pointer to a register according to MISRA?
You don't. You might as well try to make an omelett according to a "no breaking of eggs" standard. -- Hans-Bernhard Broeker (broeker@physik.rwth-aachen.de) Even if all the snow were burnt, ashes would remain.
>> >> *(int * const)(0x67a9) = 0xaa55; > > You can't cast the lvalue. You can only cast the value to be put > into it. Illegal everywhere.
Well, it's a GCC extention. So, while it's not (std.) conformant, it's not 'illegal everywhere' either. Regards, Andras Tantos
CBFalconer wrote:
> Jan Homuth wrote: > >>I guess because you are hiding the unsigned int by a typedef. >>MISRA rule 45 does not allow that. >> >> >>>How do I define a constant pointer to a register according to MISRA? >> >>I guess you are in a dilemma here. >> >>Hardware related implementations (no matter which compiler/toolchain) >>usually employ coding mechanisms that MISRA rules see as "dangerous". >>Which in a larger context of a huge application may make sense. >>The low level stuff however is very hard - if not impossible - to >>implement following MISRA. > > > Registers don't have addresses whose value can be taken. This is > illegal in any form of C. >
registers can be memory mapped, and I think here we are talking about memory mapped hardware registers not cpu registers. who else would you access memory mapped registers in peripherals?
> >>Perfectly legal expressions (according to ANSI) like: >> >>unsigned int *ptr; >>ptr = (unsigned int *)0x67a9; > > > legal, but not portable.
doesn't have to be, what ever is at 0x67a9 in this micro will probably be some where else in another. but it would be nicer to use a define or somthing.
> > >>*ptr = 0xaa55; > > > perfectly legal anywhere, provided ptr has been initialized to > point somewhere legal. > > >>*(int * const)(0x67a9) = 0xaa55; > > > You can't cast the lvalue. You can only cast the value to be put > into it. Illegal everywhere. >
hmm... compiles with gcc and does what I'd expect; write the value 0xaa55 to adress 0x67a9 using STR
> >>Anyone proficient in embedded C programming will use these >>expressions (together with volatile) to describe Special Funtion >>Registers or device I/O adresses. > > > You shouldn't need the assistance of MISRA to avoid those > particular foul-ups. > > BTW, please don't top-post, and please do snip. The practice of > top-posting a complete snipped bottom posted message only clutters > the world with further useless verbiage. >
-Lasse

Memfault Beyond the Launch