07-04-2010, 08:20 AM
Registers are typically not allocated by the program at all, as they sit in the hardware itself. Declaring a register as a value, rather than accessing it through a pointer seems to be the problem here.
For register definitions, you need to deviate from rule 8.10, it simply isn't practical to hide register maps inside private encapsulation, as the rule enforces. For upcoming releases of MISRA-C, I think register definitions should be named as the only allowed exception to the rule.
---
That being said, I guess the reason you wrote your own file is because MISRA-C 18.4 forbids union? The reasons why they are forbidden are named: padding problems, alignment, endianess, bit-order. Struct bit fields contain all of these problems as well. Omitting the union keyword solves nothing if one resorts to bit fields.
Although bit fields are allowed by MISRA-C, they are completely unportable and leads to random behavior of the program if it is ever ported. They might very well lead to random behavior on your current MCU as well. (Allowing bit fields is, in my opinion, one of the biggest flaws of the MISRA-C standard.)
You can however easily solve all of these problems, including your static linkage issue, while at the same time making the program portable to any processor and compiler in the world. Use the following syntax instead:
#define TRISA ( *((volatile uint16_t*)0x1234) ) /* where 0x1234 is the address of the register */
TRISA |= 0x01; /* set bit 0 ti value 1 */
TRISA &= (uint8_t)~0x01; /* set bit 0 to value 0*/
This code will work perfectly even if you have a linker-specific register map elsewhere in the project.
But if you aren't using this syntax, you must write a thick essay of all implementation-defined behavior asociated with bit fields: how your compiler treats struct padding, how your compiler treats the bit padding you are using, whether there is memory alignment on the MCU, how little endian works on PICs, what bit order your compiler uses, how your bit fields will or won't be affected by implicit type conversions, and so on. If you don't write such an essay, your code does not conform to MISRA-C.
Or alternatively, you can use the macro syntax above, then you don't need to document a thing.
For register definitions, you need to deviate from rule 8.10, it simply isn't practical to hide register maps inside private encapsulation, as the rule enforces. For upcoming releases of MISRA-C, I think register definitions should be named as the only allowed exception to the rule.
---
That being said, I guess the reason you wrote your own file is because MISRA-C 18.4 forbids union? The reasons why they are forbidden are named: padding problems, alignment, endianess, bit-order. Struct bit fields contain all of these problems as well. Omitting the union keyword solves nothing if one resorts to bit fields.
Although bit fields are allowed by MISRA-C, they are completely unportable and leads to random behavior of the program if it is ever ported. They might very well lead to random behavior on your current MCU as well. (Allowing bit fields is, in my opinion, one of the biggest flaws of the MISRA-C standard.)
You can however easily solve all of these problems, including your static linkage issue, while at the same time making the program portable to any processor and compiler in the world. Use the following syntax instead:
#define TRISA ( *((volatile uint16_t*)0x1234) ) /* where 0x1234 is the address of the register */
TRISA |= 0x01; /* set bit 0 ti value 1 */
TRISA &= (uint8_t)~0x01; /* set bit 0 to value 0*/
This code will work perfectly even if you have a linker-specific register map elsewhere in the project.
But if you aren't using this syntax, you must write a thick essay of all implementation-defined behavior asociated with bit fields: how your compiler treats struct padding, how your compiler treats the bit padding you are using, whether there is memory alignment on the MCU, how little endian works on PICs, what bit order your compiler uses, how your bit fields will or won't be affected by implicit type conversions, and so on. If you don't write such an essay, your code does not conform to MISRA-C.
Or alternatively, you can use the macro syntax above, then you don't need to document a thing.
<t></t>