了解为蓝牙低能耗实现CRC的C代码

了解为蓝牙低能耗实现CRC的C代码,c,bluetooth-lowenergy,crc,C,Bluetooth Lowenergy,Crc,蓝牙低能量(BLE)使用24位CRC,生成多项式 x^24+x^10+x^9+x^6+x^4+x^3+x+1 我遇到了用“0x5555的初始值”在C中实现这个CRC的。我将代码粘贴如下: void btLeCrc(const uint8_t* data, uint8_t len, uint8_t* dst){ uint8_t v, t, d; while(len--){ d = *data++; for(v = 0; v < 8; v++,

蓝牙低能量(BLE)使用24位CRC,生成多项式

x^24+x^10+x^9+x^6+x^4+x^3+x+1

我遇到了用“0x5555的初始值”在C中实现这个CRC的。我将代码粘贴如下:

void btLeCrc(const uint8_t* data, uint8_t len, uint8_t* dst){
    uint8_t v, t, d;
    while(len--){
        d = *data++;
        for(v = 0; v < 8; v++, d >>= 1){    
            t = dst[0] >> 7;
            dst[0] <<= 1;
            if(dst[1] & 0x80) dst[0] |= 1;
            dst[1] <<= 1;
            if(dst[2] & 0x80) dst[1] |= 1;
            dst[2] <<= 1;

            if(t != (d & 1)){
                dst[2] ^= 0x5B;
                dst[1] ^= 0x06;
            }
        }   
    }
}
void btLeCrc(常量数据、常量长度、常量数据){
uint8_t v,t,d;
而(len--){
d=*数据++;
对于(v=0;v<8;v++,d>>=1){
t=dst[0]>>7;

dst[0]也许
uint8\u t
是唯一可用的整数类型,这就解释了作者为什么要一次移位和排他地对24位值进行oring,
dst[0..2]
8位

该代码实现了一个基本CRC移位寄存器,其中数据一次移位一位,当数据位与移出寄存器的位异或为1时,CRC与多项式异或。请注意,多项式的异或仅在三个寄存器字节中的两个字节上,因为多项式ial低于x24的最高功率为x10


使用
0x555555
而不是
0xffffff
初始化只是一个简单的尝试。使用零以外的任何值初始化都是一个好主意,因为这样数据中的初始零字符串不会使CRC保持不变。

在蓝牙低能量模式下,CRC移位寄存器被初始化为0x555555以进行广告ng和随机值(在连接过程中共享)对于连接的设备。

我认为这段代码可能会在数学上得到证明,然后进行调整。我不太清楚,但从能耗的角度来看,将乘法转换为按位运算肯定会降低功耗。这其中的哪一部分会给您带来麻烦?看起来内部循环一次只处理1位位置的内容时间,在
dst
@hustmphrr中维护24位移位寄存器这段代码用于8位微控制器。我想用位操作进行CRC更好。@shva我在大学时一直在研究嵌入式系统,读了一些关于CRC的书。我几乎忘记了一切,但我仍然觉得CRC可以将e映射到一个任意空间,并将其转换为按位运算。我认为M序列具有相同的想法。如果你发现了什么,请纠正我。
t!=(d&1)
相当于对这两位进行异或运算,然后在异或为
1
时采取行动。我意识到他可能是在用移位寄存器实现CRC,如中所示。如果我错了,请纠正我。但我仍然不明白,在这种情况下,他为什么用0x5555而不是0x000000初始化寄存器。我认为初始化值会影响最终计算的校验和。是的,图表就是这样。我说了为什么要用
0x555555
初始化它。当然它会影响结果。这就是重点。只要两端使用相同的过程,一切都好。