2015-06-23 61 views
2

我有4個名爲lowLevelErrors1,lowLevelErrors2 ...的Uint32變量,最多爲4個。這些變量上的每個位表示低級別錯誤。我需要將它們映射到名爲userErrors的Uint64變量。 userError的每一位表示向用戶顯示的錯誤,可由於1個或更多低級錯誤而設置錯誤。換句話說,每個低級錯誤都映射到1個用戶錯誤。 2個或更多的低級錯誤可以映射到相同的用戶錯誤。從一個變量位到另一個變量的高效映射

我們將它縮小到2x Uint8低級錯誤和1x Uint8用戶錯誤,以便我們可以看到一個示例。

示例:如果設置了以下任一低級錯誤{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 
     } 
    } 

} 

這個實現的問題是需要map數組。我將需要4x uint8數組[32] = 128 uint8個變量,並且我們在微控制器上的內存不足。

是否有任何其他方式使用較少的RAM來實現相同的功能?

+0

我不認爲你可以做得更好,除非你重新安排位數,這樣'userErrors'中的每一位對應'lowLevelErrors'中的一個連續範圍的位。即使那樣,地圖表也將是64個字節。 – user3386109

+0

另一個想法是將'mapLLE'數組聲明爲'const',以便編譯器將它們放入ROM而不是RAM中。如果編譯器不合作,您通常可以選擇使用鏈接器控制文件移動東西。 – user3386109

+0

爲什麼你需要重映射?只要每個用戶錯誤僅來自四個Lowlevel錯誤變量中的一個,您是否可以使用掩碼,例如'#define US_ERR_POWER_FAIL(ERR_VOLT_LOW | ERR_NO_BATTERY | ERR_NOT_CHARGING)'? –

回答

2

你有128個輸入位,每個被映射到比特數從0到63所以這是128 * 6 = 768位信息,除非存在一些常規模式,否則至少需要96字節的存儲空間。

所以你至少需要96個字節;即使如此,它仍將以打包的6位整數進行存儲。解壓這些整數的代碼可能比通過打包保存的32個字節花費更多。

所以你基本上有三種選擇:128字節的數組,如你所建議的;打包的6字節整數;或者更容易解包的錯誤代碼的一些常規分配(如果特定錯誤代碼映射是固定的,則這不是可能的)。

0

因爲我們還沒有給出所有的錯誤一個完整的例子,這是很難說什麼是「最好」的方法,但我會構建「面具」和「價值」的表格:

喜歡的東西這樣的:

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; 
    } 
    } 
+0

雖然整潔的解決方案,它不會減少用於存儲變量的空間量。 – stefanos

相關問題