C 位掩码寄存器

C Bit masking registers

我已经有一段时间没有用 C 编程并完成任何位掩码了。

我的问题是,在我的设备启动过程中,我的设备驱动程序正在初始化寄存器中的位,但只有其中一些被认为是可变的。我知道哪些位是可变的,并且我知道它们根据内存位置应该是什么。

例如: $0x00AA 应始终采用 0b101XXX01 格式,其中 X 是可变的,其他所有内容都应保持不变。 该函数当前接受一个地址和一个值,并将该值简单地设置为该地址。我需要修改它,这样即使函数在寄存器 $0x00AA 的 0b11111111 中传递,它也应该设置为 0b10111101。 同样,对于 0b00000000 到 0b10100001。

您可以先用按位与屏蔽可变位以外的任何内容,然后用按位或添加常量位。

void set_register(uint8_t value) {
    const uint8_t MUTABLE_BITS = 0x1C;  // 0b00011100 <- only mutable bits
    const uint8_t CONSTANT_BITS = 0xA1; // 0b10100001 <- constant 1-bits

    value &= MUTABLE_BITS; // remove any non-mutable bits
    value |= CONSTANT_BITS; // add the constant bits
    my_register = value;
}

这种方法有一个可疑的特征,即对常量位的值进行硬编码(根据名称“常量”)。另一种方法是仅设置可变位并从寄存器本身获取其余值(按位与可变位掩码的补码),例如:

void set_register(uint8_t value) {
    const uint8_t MUTABLE_BITS = 0x1C;  // 0b00011100 <- only mutable bits

    value &= MUTABLE_BITS; // remove any non-mutable bits
    value |= my_register & ~MUTABLE_BITS; // take other bits from register
    my_register = value;
}

(至于对具有不同掩码的多个寄存器执行此操作的要求,我希望它们的数量足够有限,您可以一个一个地设置它们。如果您真的需要一个接受一个函数的函数指针和一个值,然后您必须根据已知的受保护地址检查该指针并以某种方式获得适当的掩码。该范围的选择范围从 if/elseswitch 到二进制搜索到某些一种哈希映射。)