ZHCAAO5A June 2020 – August 2021 ADS112C04 , ADS112U04 , ADS114S06 , ADS114S08 , ADS122C04 , ADS122U04 , ADS1235 , ADS1235-Q1 , ADS124S06 , ADS124S08 , ADS1259 , ADS1259-Q1 , ADS125H01 , ADS125H02 , ADS1260 , ADS1260-Q1 , ADS1261 , ADS1262 , ADS1263 , ADS127L01 , ADS131A02 , ADS131A04 , ADS131M04 , ADS131M06 , ADS131M08
使用汉明和校验和验证后,可以纠正单个位错误。首先进行数据验证和纠错,如果可能,则纠正位。如果恢复了数据,则重新评估校验和。如果出现多位错误或校验和错误,则传输无效。
uint32_t fixResults[] = {
0, // 数据块正常
1 << 3, // 数据中没有错误 (H0)
1 << 4, // 数据中没有错误 (H1)
1u << 31, // 数据[23] 错误
1 << 5, // 数据中没有错误 (H2)
1 << 30, // 数据[22] 错误
1 << 29, // 数据[21] 错误
1 << 28, // 数据[20] 错误
1 << 6, // 数据中没有错误 (H3)
1 << 27, // 数据[19] 错误
1 << 26, // 数据[18] 错误
1 << 25, // 数据[17] 错误
1 << 24, // 数据[16] 错误
1 << 23, // 数据[15] 错误
1 << 22, // 数据[14] 错误
1 << 21, // 数据[13] 错误
1 << 7, // 数据中没有错误 (H4)
1 << 20, // 数据[12] 错误
1 << 19, // 数据[11] 错误
1 << 18, // 数据[10] 错误
1 << 17, // 数据[9] 错误
1 << 16, // 数据[8] 错误
1 << 15, // 数据[7] 错误
1 << 14, // 数据[6] 错误
1 << 13, // 数据[5] 错误
1 << 12, // 数据[4] 错误
1 << 11, // 数据[3] 错误
1 << 10, // 数据[2] 错误
1 << 9, // 数据[1] 错误
1 << 8, // 数据[0] 错误
// 不可纠正的 30
// 不可纠正的 31
// H0 覆盖 14 个位,H1-H4 覆盖 13 个位,
// 因此如果汉明码为 30 或 31,
// 则会出现多位错误且无法纠正
};
/**
* 数据验证和单个位错误修复。
*
* \详细信息:使用汉明位信息验证和
* 恢复数据以纠正单个位错误。 首先检查“in”值,
* 如果异或运算返回 0,则相对于汉明位验证数据内容,
* 然后使用校验和检查数据内容是否存在多位错误。
* 如果汉明位与数据不匹配,则在可能的情况下
* 使用汉明位来纠正数据,方法是使用计算出的
* 汉明位与传输的汉明位进行异或。 使用基于校正系数和异或值的查找表
* 来恢复数据,然后计算校验和以确保没有
* 多位错误。
*
* \参数 uint32_t in 是要计算和比较的值。
*
* \返回 uint32_t res,如果数据可纠正或有效,则返回 0。
* 非零值是无效数据。
*/
uint32_t fixHamming(uint32_t in)
{
uint32_t res;
uint32_t fix;
// checkHamming 将从数据“in”返回 5 个汉明位
// 在条件语句中使用赋值时,条件会对赋值进行
// 评估。
// 如果 checkHamming 返回“0”以外的值,则尝试修复结果
if(res = checkHamming(in))
{
// 根据非“0”的汉明码结果,通过调整来自包含
// 2^5(或 32)种可能组合的表中“in”的 32 位值,
// 使用查找表来纠正结果。总之,32 个值中有 24 个值用于 1 位纠错,
// 5 个值表示数据无错误(汉明码中的 1 位错误),1 个值表示
// 数据和汉明码均无错误,2 个值表示数据、汉明码
// 或两者中存在多位错误。对于多位错误的情况只分配了
// 两个值,因此算法很可能错误地
// 将多位错误视为 1 位错误。为了降低这种
// 可能性,除了汉明检测之外,还添加了 2 位校验和
// 以进行检错。
// 快速检查汉明值中是否存在多位错误
fix = res >> 3;
// 然后将计算出的汉明位与“in”值汉明位进行异或运算
fix = fix ^ ((in & 0xFF) >> 3);
// 如果存在已知的多位错误,则指示修复失败
if (fix > 29) return HC_FIX_FAIL;
else
{
// 发生了位错误,尝试进行修复
fix = (fixResults[fix]);
// 识别的错误可能是汉明错误或数据错误,在此处将“in”值
// 与 fix 值进行异或
res = in ^ fix;
}
}
else
{
res = in;
}
// res 现在包含数据的原始值或修复值,即经过
// 汉明校验和数据纠正后的数据 + 汉明值,
// 使用校验和位检查多位错误,checkSum 将
// 在计数中排除汉明位。如果 checkSum 返回 0 以外的值,则
// checkSum 失败,否则返回 0
if(checkSum(res))
{
return HC_FIX_FAIL;
}
return res;
}