从一个变量的位到另一个变量位的有效映射
Efficient mapping from bits of one variable to another
我有4个名为lowLevelErrors1、lowLevelError s2的Uint32变量…最多4个。其中的每一位都表示一个低级别错误。我需要将它们映射到一个名为userErrors的Uint64变量。userError的每个位表示向用户显示的错误,该错误可以由于一个或多个低级别错误而设置。换句话说,每个低级别错误都映射到1个用户错误。2个或更多个低级别错误可以被映射到相同的用户错误。
让我们将其缩小到2个Uint8低级别错误和1个Uint 8用户错误,这样我们就可以看到一个示例。
示例:如果设置了以下任何低级别错误{ERR_VOLT_low|ERR_NO_BATTERY|ERR_NOT_CHARGING}(对应于lowLevelErrors1的位0、位2和位3),则设置用户错误US_ERR_POWER_FAIL(即userErrors的位5)。
因此,我能想到的唯一方法是为每个lowLevelErrors变量创建一个映射数组,用于映射到userErrors的相应位。
/* Let's say the lowLevelErrors have to be mapped like this:
lowLevelErrors1 bit maps to userError bit
0 5
1 1
2 5
3 5
4 0
5 2
6 7
7 0
lowLevelErrors2 bits maps to userError bit
0 1
1 1
2 0
3 3
4 6
5 6
6 4
7 7
*/
Uint8 lowLevelErrors1 = 0;
Uint8 lowLevelErrors2 = 0;
Uint8 userErrors = 0;
Uint8 mapLLE1[8] = {5, 1, 5, 5, 0, 2, 7, 0};
Uint8 mapLLE2[8] = {1, 1, 0, 3, 6, 6, 4, 7};
void mapErrors(void)
{
for (Uint8 bitIndex = 0; bitIndex < 8; i++)
{
if (lowLevelErrors1 && (1 << i)) //If error bit is set
{
userErrors |= 1 << mapLLE1[bitIndex]; //Set the corresponding user error
}
}
for (Uint8 bitIndex = 0; bitIndex < 8; i++)
{
if (lowLevelErrors2 && (1 << i)) //If error bit is set
{
userErrors |= 1 << mapLLE2[bitIndex]; //Set the corresponding user error
}
}
}
此实现的问题在于需要映射数组。我需要4x uint8数组[32]=128 uint8变量,并且我们在微控制器上的内存不足。
有没有其他方法可以使用更少的RAM来实现相同的功能?
您有128个输入位,每个输入位映射到从0到63的位数。因此,这是128*6=768位的信息,除非有一些规则的模式,否则至少需要96字节的存储
因此,您至少需要96个字节;即便如此,它也将被存储为压缩的6位整数。解包这些整数的代码可能比打包它们节省的32个字节花费更多。
因此,您基本上有三种选择:如您所建议的,一个128字节的数组;压缩的6字节整数;或者更容易解包的错误代码的一些规则分配(如果特定的错误代码映射是固定的,则这是不可能的)。
由于您还没有给出一个包含所有错误的完整示例,因此很难说什么是"最佳"方法,但我会构建一个"掩码"answers"值"的表:
类似这样的东西:
struct Translate
{
uint32_t mask;
// Maybe have mask[4]?
uint64_t value;
};
// If not mask[4], the
Translate table[] =
{
{ ERR_VOLT_LOW | ERR_NO_BATTERY | ERR_NOT_CHARGING,
// If mask[4] then add 3 more values here - expect typically zeros
US_ERR_POWER_FAIL },
...
};
我不确定表中有4个不同的值和4个不同表哪个更有意义——这取决于LowLevel1和LowLevel2、LowLevel2和LowLevel4等错误映射到同一错误的频率。但是,通过将多个错误映射到一个值,您应该这样做。
现在,一旦我们有了数据结构,代码就会变成这样:
for(auto a : table)
{
if (a.mask & lowLevelErrors1)
{
userErrror |= a.value;
}
}
- 如何从另一个文件继承私有成员变量和公共函数
- 在 Windows 上,是否可以让 dll 在不使用 PATH 环境变量的情况下在另一个文件夹中查找依赖项?
- 一个变量的输入值也会保存到另一个变量中
- 从另一个 cpp 文件更改结构内、映射键内的变量
- 在另一个函数 (c++) 中调用变量
- 将双精度变量设置为另一个变量的值
- 为什么从另一个构造函数内部调用C++构造函数不修改类变量?
- 我有一个类,它创建了另一个类的实例.如何将变量通过第一个类传递到第二个类的实例化中?
- 为什么我可以使用 memcpy 将一个对象变量复制到另一个对象变量
- 为什么一个变量获得与另一个值相同的值
- 类中的一个变量显示,但另一个不显示
- c++问题:给一个变量赋值后,另一个变量发生了变化
- 在一个子程序中输入的变量用于C++中的另一个子程序
- (C++) 从另一个类访问变量时值无效
- 我如何将一个变量与另一个变量进行比较,例如我想如果(var1 > var2 x 1),然后执行此 c++
- 如何在一个函数中定义一个变量,并在另一个函数中访问和更改它?(C++)
- 如果一个变量在它之前释放了另一个(相同的数据类型)变量,如何将其分配给内存?
- 将变量从主窗口传递到另一个qt c++窗体
- memcpy() 在一个类中被调用以复制到另一个类变量中后会引发异常
- 将 int 转换为字符串,然后连接另一个变量以创建完整扩展名,然后将其转换为 const_char*