Although the engineer had valid reasons for designing the register that way, he or she had not anticipated the impact on firmware of mixing different types of bits in the same register. To avoid complexity and risk of firmware defects, different types of bits should be located in different registers. To see why, let’s examine how firmware manages two types of bits – read/write bits and interrupt bits.
With read/write bits, firmware sets and clears bits when needed. It typically first reads the register, modifies the desired bit, then writes the modified value back out. Here is a sample code fragment:
tmp = ReadReg (regA); /* Get the register contents */
tmp |= 0x01; /* Set bit 0 */
RegWrite (regA, tmp); /* Write it back out */
In the case of interrupt bits, firmware often writes a value with one bit set to acknowledge the desired interrupt while leaving any other pending interrupts untouched.
RegWrite (regB, 0x10); /* Ack bit 4 */
Mixing the two types of bits in the same register could cause problems. Using the read/write code on interrupt bits causes pending interrupts to inadvertently be acknowledged. Using the interrupt code on read/write bits clears all read/write bits that used to be set. Firmware must take special care to ensure that it does not inadvertently change the wrong bits.
Here is a code fragment that acknowledges bit 4 while taking care not to acknowledge other pending interrupts or modify any read/write bits. In this example, read/write bits are located in positions
0x0f
and interrupt bits are located in positions 0x70
.tmp = RegRead (regC); /* Get the register contents */
tmp &= 0x0f; /* Keep R/W bits but zero any intr bits */
tmp |= 0x10; /* Set bit 4 to ack */
RegWrite (regC, tmp); /* Write it back out */
Acknowledging an interrupt changed from a one-step to a four-step operation. A similar code fragment is needed to modify desired read/write bits while leaving alone any pending interrupts.
While there is a way for firmware to safely handle this, it is out of the ordinary and prone to firmware defects. Combining different types of bits into the same register may save registers but it adds unnecessary burden and complexity to firmware. Looking ahead and anticipating the firmware impact can lead to a more reliable and robust solution of placing different types of bits in separate registers.
Best Practice: Segregate different types of bits (read/write, read-only, interrupt, etc.) into different registers.
If necessary, read-only bits could be combined with any one of the other types of bits. This is acceptable because no matter how the other bits are handled, firmware writes to the register will not affect the read-only bits.
Until the next bit..."
Nessun commento:
Posta un commento
Nota. Solo i membri di questo blog possono postare un commento.