---
# System prepended metadata

title: Untitled

---

# VU Table 對齊步驟指南（修正版）

## 一、對齊原則

**重要**：**FW 版本是正確的基準版本**，Regression Test 版本需要對齊到 FW 版本。

| 版本 | 狀態 | 用途 |
|------|------|------|
| **FW 版本** | ✅ **基準版本** | 實際 Firmware 使用，使用 Designated Initializers |
| **Regression Test 版本** | ⚠️ **需要對齊** | 測試環境使用，使用傳統語法，必須對齊 FW 版本 |

## 二、檔案位置

| 項目 | 檔案位置 | 行數範圍 | 條件編譯 |
|------|---------|---------|---------|
| **ENUM_VU_STATE** | `Source/UFS/ISP/Vcmd/ISP_UFS_Vcmd.h` | 40-296 | - |
| **FW VU_TABLE** | `Source/UFS/ISP/Vcmd/ISP_UFS_Vcmd_Para.c` | 20-1053 | `#ifndef SMI_REGRESSION_TEST` |
| **Regression VU_TABLE** | `Source/UFS/ISP/Vcmd/ISP_UFS_Vcmd_Para.c` | 1054-1637 | `#ifdef SMI_REGRESSION_TEST` |
| **FW VUHandler** | `Source/UFS/ISP/Vcmd/ISP_UFS_Vcmd_Rsp.c` | 182-389 | `#ifndef SMI_REGRESSION_TEST` |
| **Regression VUHandler** | `Source/UFS/ISP/Vcmd/ISP_UFS_Vcmd_Rsp.c` | 390-693 | `#ifdef SMI_REGRESSION_TEST` |

## 三、對齊步驟

### 步驟 1：確認 FW 版本的 VU_TABLE（基準）

**目標**：確認 FW 版本中所有已定義的狀態

**操作**：
1. 打開 `Source/UFS/ISP/Vcmd/ISP_UFS_Vcmd_Para.c`
2. 找到 `#ifndef SMI_REGRESSION_TEST` 區塊 (Line 19-1053)
3. **列出所有已初始化的狀態**，例如：
   ```c
   [VU_STATE_STRSMI_ENTER] = { ... }
   [VU_STATE_STRDVT1_ENTER] = { ... }
   [VU_STATE_GET_BADBLOCK_CNT_IND] = { ... }
   ```

**重點**：
- ✅ FW 版本使用 Designated Initializers，可以跳過不需要的狀態
- ✅ 記錄每個狀態的完整設定值
- ✅ 注意條件編譯（`#ifdef`）的狀態

**範例**：
```c
#ifndef SMI_REGRESSION_TEST
const ST_VU_CHK VU_TABLE[VU_STATE_END] =
{
    [VU_STATE_STRSMI_ENTER] = {
        .u32CMD_Sig = VCMD_ARG_SMIPAR,
        .u08Opcode  = UPIU_CMD_WRITE_BUFFER,
        .Next_State = VU_STATE_CHK_ENTER,
        .u32Len     = 0x00,
        .u32Mode_SP_BT = ALL_MODE_SP
    },
    // ... 其他狀態
};
#endif
```

### 步驟 2：確認 ENUM_VU_STATE 的順序

**目標**：確認每個狀態在 enum 中的索引值

**操作**：
1. 打開 `Source/UFS/ISP/Vcmd/ISP_UFS_Vcmd.h`
2. 找到 `typedef enum { ... } ENUM_VU_STATE;` (Line 40-296)
3. **建立索引對照表**：
   ```
   VU_STATE_START = 0
   VU_STATE_STRDVT1_ENTER = 1
   VU_STATE_STRDVT2_ENTER = 2
   ...
   VU_STATE_GET_BADBLOCK_CNT_IND = 84  (假設)
   VU_STATE_GET_BADBLOCK_CNT_SIG = 225 (假設)
   ...
   VU_STATE_END = N  // 最後一個狀態的索引 + 1
   ```

**重點**：
- ✅ 確認 `VU_STATE_END` 的值
- ✅ 確認 `VU_STATE_CHK_ENTER` 不在陣列範圍內
- ✅ 注意條件編譯的狀態

### 步驟 3：對齊 Regression Test 版本的 VU_TABLE

**目標**：讓 Regression Test 版本對齊 FW 版本

**操作流程**：

#### 3.1 建立對照表

**從 FW 版本提取狀態設定**：
```c
// FW 版本 (基準)
[VU_STATE_GET_BADBLOCK_CNT_IND] = {
    .u32CMD_Sig = VCMD_GET_BADBLOCK_CNT,
    .u08Opcode  = UPIU_CMD_WRITE_BUFFER,
    .Next_State = VU_STATE_GET_BADBLOCK_CNT_SIG,
    .u32Len     = 0x0,
    .u32Mode_SP_BT = DVT1_MODE_SP|SMI_MODE_SP
}
```

**轉換為 Regression Test 格式**：
```c
// Regression Test 版本 (需要對齊)
// 假設 VU_STATE_GET_BADBLOCK_CNT_IND = 84
// 結構體成員順序：{ u32CMD_Sig, u32Len, u32Mode_SP_BT, Next_State, u08Opcode }
{ VCMD_GET_BADBLOCK_CNT, 0x0, DVT1_MODE_SP|SMI_MODE_SP, 
  VU_STATE_GET_BADBLOCK_CNT_SIG, UPIU_CMD_WRITE_BUFFER }, // [84] VU_STATE_GET_BADBLOCK_CNT_IND
```

#### 3.2 按照 ENUM 順序填入

**關鍵規則**：
- ⚠️ **必須按照 ENUM_VU_STATE 的順序**（從 0 到 VU_STATE_END-1）
- ⚠️ **不能跳過任何元素**（即使 FW 版本沒有初始化，也要填預設值）
- ⚠️ **註解必須標註狀態名稱和索引**

**對齊方法**：

1. **從索引 0 開始，逐一對齊**：
   ```c
   #ifdef SMI_REGRESSION_TEST
   const ST_VU_CHK VU_TABLE[VU_STATE_END] =
   {
       // [0] VU_STATE_START
       // 檢查 FW 版本是否有定義
       // 如果 FW 版本沒有定義，使用預設值
       { 0x00, 0x00, 0x00, VU_STATE_CHK_ENTER, 0x00 }, //    VU_STATE_START,
       
       // [1] VU_STATE_STRDVT1_ENTER
       // 從 FW 版本複製設定值
       { VCMD_ARG_DVT1PAR, 0x00, ALL_MODE_SP, VU_STATE_CHK_ENTER, UPIU_CMD_WRITE_BUFFER }, //      VU_STATE_STRDVT1_ENTER,
       
       // ... 繼續對齊所有狀態
   };
   #endif
   ```

2. **處理 FW 版本中未定義的狀態**：
   ```c
   // 如果 FW 版本中某個狀態沒有初始化（跳過），Regression Test 版本要填預設值
   { 0x00, 0x00, 0x00, VU_STATE_START, 0x00 }, // VU_STATE_XXX (FW 版本未定義)
   ```

3. **處理條件編譯**：
   ```c
   // FW 版本
   #ifdef VCMD_GET_BADBLOCK_CNT
     [VU_STATE_GET_BADBLOCK_CNT_IND] = { ... },
   #endif
   
   // Regression Test 版本（必須保留位置）
   #ifdef VCMD_GET_BADBLOCK_CNT
     { VCMD_GET_BADBLOCK_CNT, 0x0, DVT1_MODE_SP|SMI_MODE_SP, 
       VU_STATE_GET_BADBLOCK_CNT_SIG, UPIU_CMD_WRITE_BUFFER }, // [84] VU_STATE_GET_BADBLOCK_CNT_IND
   #else
     { 0x00, 0x00, 0x00, VU_STATE_START, 0x00 }, // [84] VU_STATE_GET_BADBLOCK_CNT_IND (未啟用)
   #endif
   ```

#### 3.3 結構體成員順序

**重要**：Regression Test 版本使用傳統語法，成員順序必須正確：

```c
// ST_VU_CHK 結構定義
typedef struct {
    LWORD u32CMD_Sig;        // 第 1 個成員
    LWORD u32Len;            // 第 2 個成員
    LWORD u32Mode_SP_BT;     // 第 3 個成員
    ENUM_VU_STATE Next_State; // 第 4 個成員
    BYTE u08Opcode;          // 第 5 個成員
} ST_VU_CHK;

// Regression Test 初始化順序
{ u32CMD_Sig, u32Len, u32Mode_SP_BT, Next_State, u08Opcode }
```

**對照範例**：
```c
// FW 版本 (Designated Initializers)
[VU_STATE_GET_BADBLOCK_CNT_IND] = {
    .u32CMD_Sig = VCMD_GET_BADBLOCK_CNT,           // 成員 1
    .u32Len     = 0x0,                             // 成員 2
    .u32Mode_SP_BT = DVT1_MODE_SP|SMI_MODE_SP,     // 成員 3
    .Next_State = VU_STATE_GET_BADBLOCK_CNT_SIG,   // 成員 4
    .u08Opcode  = UPIU_CMD_WRITE_BUFFER            // 成員 5
}

// Regression Test 版本 (傳統語法)
{ VCMD_GET_BADBLOCK_CNT,                           // 成員 1: u32CMD_Sig
  0x0,                                              // 成員 2: u32Len
  DVT1_MODE_SP|SMI_MODE_SP,                        // 成員 3: u32Mode_SP_BT
  VU_STATE_GET_BADBLOCK_CNT_SIG,                   // 成員 4: Next_State
  UPIU_CMD_WRITE_BUFFER },                         // 成員 5: u08Opcode
  // [84] VU_STATE_GET_BADBLOCK_CNT_IND
```

### 步驟 4：對齊 Regression Test 版本的 VUHandler

**目標**：讓 Regression Test 版本的 VUHandler 對齊 FW 版本

**操作流程**：

#### 4.1 從 FW 版本提取處理函數

```c
// FW 版本 (基準)
#ifndef SMI_REGRESSION_TEST
FuncVUHandle VUHandler[VU_STATE_END] =
{
    [VU_STATE_GET_BADBLOCK_CNT_SIG] = ISP_UFS_VCmd_GeneralVU_Read,
    [VU_STATE_GETFWVERSION_SIG] = ISP_UFS_VCmd_GetFWVersion,
    // ... 其他狀態
};
#endif
```

#### 4.2 按照 ENUM 順序填入 Regression Test 版本

```c
// Regression Test 版本 (需要對齊)
#ifdef SMI_REGRESSION_TEST
FuncVUHandle VUHandler[VU_STATE_END] =
{
    NULL,  // [0] VU_STATE_START (FW 版本未定義)
    ISP_UFS_VCmd_Enter_DVT1,  // [1] VU_STATE_STRDVT1_ENTER (從 FW 版本複製)
    ISP_UFS_VCmd_Enter_DVT2,  // [2] VU_STATE_STRDVT2_ENTER (從 FW 版本複製)
    // ...
    NULL,  // [84] VU_STATE_GET_BADBLOCK_CNT_IND (FW 版本未定義)
    // ...
    ISP_UFS_VCmd_GeneralVU_Read,  // [225] VU_STATE_GET_BADBLOCK_CNT_SIG (從 FW 版本複製)
    // ...
};
#endif
```

**重點**：
- ✅ 如果 FW 版本有定義處理函數，複製到對應位置
- ✅ 如果 FW 版本沒有定義（跳過），填 `NULL`
- ✅ 必須按照 ENUM 順序，不能跳過任何元素

## 四、完整對齊範例

### 範例：對齊 VU_STATE_GET_BADBLOCK_CNT_IND 和 VU_STATE_GET_BADBLOCK_CNT_SIG

#### 1. FW 版本（基準）

**VU_TABLE**：
```c
#ifndef SMI_REGRESSION_TEST
const ST_VU_CHK VU_TABLE[VU_STATE_END] =
{
    // ...
    [VU_STATE_GET_BADBLOCK_CNT_IND] = {  // 假設 enum 值 = 84
        .u32CMD_Sig = VCMD_GET_BADBLOCK_CNT,
        .u08Opcode  = UPIU_CMD_WRITE_BUFFER,
        .Next_State = VU_STATE_GET_BADBLOCK_CNT_SIG,
        .u32Len     = 0x0,
        .u32Mode_SP_BT = DVT1_MODE_SP|SMI_MODE_SP
    },
    // ...
    [VU_STATE_GET_BADBLOCK_CNT_SIG] = {  // 假設 enum 值 = 225
        .u32CMD_Sig = VCMD_GET_BADBLOCK_CNT,
        .u08Opcode  = UPIU_CMD_READ_BUFFER,
        .Next_State = VU_STATE_START,
        .u32Len     = 0x1000,
        .u32Mode_SP_BT = ALL_MODE_SP
    },
    // ...
};
#endif
```

**VUHandler**：
```c
#ifndef SMI_REGRESSION_TEST
FuncVUHandle VUHandler[VU_STATE_END] =
{
    // ...
    [VU_STATE_GET_BADBLOCK_CNT_SIG] = ISP_UFS_VCmd_GeneralVU_Read,  // 索引 225
    // ... (VU_STATE_GET_BADBLOCK_CNT_IND 沒有處理函數，跳過)
};
#endif
```

#### 2. Regression Test 版本（對齊）

**VU_TABLE**：
```c
#ifdef SMI_REGRESSION_TEST
const ST_VU_CHK VU_TABLE[VU_STATE_END] =
{
    // ... 前面的 83 個元素 ...
    
    // [84] VU_STATE_GET_BADBLOCK_CNT_IND
    // 從 FW 版本複製：{ u32CMD_Sig, u32Len, u32Mode_SP_BT, Next_State, u08Opcode }
    { VCMD_GET_BADBLOCK_CNT,                    // u32CMD_Sig
      0x0,                                      // u32Len
      DVT1_MODE_SP|SMI_MODE_SP,                 // u32Mode_SP_BT
      VU_STATE_GET_BADBLOCK_CNT_SIG,            // Next_State
      UPIU_CMD_WRITE_BUFFER },                  // u08Opcode
      // VU_STATE_GET_BADBLOCK_CNT_IND
    
    // ... 中間的元素 ...
    
    // [225] VU_STATE_GET_BADBLOCK_CNT_SIG
    // 從 FW 版本複製
    { VCMD_GET_BADBLOCK_CNT,                    // u32CMD_Sig
      0x1000,                                   // u32Len
      ALL_MODE_SP,                              // u32Mode_SP_BT
      VU_STATE_START,                           // Next_State
      UPIU_CMD_READ_BUFFER },                   // u08Opcode
      // VU_STATE_GET_BADBLOCK_CNT_SIG
    
    // ... 後面的元素 ...
};
#endif
```

**VUHandler**：
```c
#ifdef SMI_REGRESSION_TEST
FuncVUHandle VUHandler[VU_STATE_END] =
{
    // ... 前面的元素 ...
    
    NULL,  // [84] VU_STATE_GET_BADBLOCK_CNT_IND (FW 版本未定義處理函數)
    
    // ... 中間的元素 ...
    
    ISP_UFS_VCmd_GeneralVU_Read,  // [225] VU_STATE_GET_BADBLOCK_CNT_SIG (從 FW 版本複製)
    
    // ... 後面的元素 ...
};
#endif
```

## 五、對齊檢查清單

### 新增狀態時的對齊步驟

1. **在 FW 版本中添加狀態**：
   - [ ] 在 `ENUM_VU_STATE` 中添加新狀態
   - [ ] 在 FW VU_TABLE 中添加狀態初始化（使用 Designated Initializers）
   - [ ] 在 FW VUHandler 中添加處理函數（如果需要）

2. **在 Regression Test 版本中對齊**：
   - [ ] 確認新狀態在 ENUM 中的索引位置
   - [ ] 在 Regression Test VU_TABLE 的**對應索引位置**添加狀態（使用傳統語法）
   - [ ] 在 Regression Test VUHandler 的**對應索引位置**添加處理函數（或 NULL）
   - [ ] 確認註解標註正確的狀態名稱和索引

3. **驗證**：
   - [ ] 確認陣列大小 = `VU_STATE_END`
   - [ ] 確認 Regression Test 版本的元素數量正確
   - [ ] 確認結構體成員順序正確
   - [ ] 編譯測試（FW 和 Regression Test 版本）

### 修改狀態時的對齊步驟

1. **修改 FW 版本**：
   - [ ] 修改 FW VU_TABLE 中的狀態設定
   - [ ] 修改 FW VUHandler 中的處理函數（如果需要）

2. **同步到 Regression Test 版本**：
   - [ ] 找到對應的索引位置
   - [ ] 更新 Regression Test VU_TABLE 中對應位置的設定
   - [ ] 更新 Regression Test VUHandler 中對應位置的處理函數
   - [ ] 確認註解正確

## 六、常見錯誤與解決方法

### 錯誤 1：索引位置錯誤

**症狀**：Regression Test 版本中狀態對應錯誤

**原因**：
- 沒有按照 ENUM 順序填入
- 索引計算錯誤

**解決方法**：
1. 確認狀態在 ENUM 中的索引值
2. 確認 Regression Test 版本中該索引位置的元素正確
3. 使用註解標註索引和狀態名稱

### 錯誤 2：結構體成員順序錯誤

**症狀**：編譯通過但執行時行為錯誤

**原因**：
- 傳統語法的成員順序與結構定義不一致

**解決方法**：
```c
// 正確順序（對照結構定義）
{ u32CMD_Sig, u32Len, u32Mode_SP_BT, Next_State, u08Opcode }

// 檢查方法：對照 FW 版本的 Designated Initializers
```

### 錯誤 3：遺漏未定義的狀態

**症狀**：陣列大小不匹配

**原因**：
- FW 版本跳過的狀態，Regression Test 版本沒有填預設值

**解決方法**：
- 所有索引位置都要有元素（即使填 `{ 0x00, 0x00, 0x00, VU_STATE_START, 0x00 }`）

### 錯誤 4：條件編譯處理不一致

**症狀**：不同編譯條件下行為不一致

**原因**：
- FW 和 Regression Test 版本的條件編譯分支不一致

**解決方法**：
- 確保兩個版本的 `#ifdef` 條件一致
- Regression Test 版本必須保留位置（即使條件不滿足）

## 七、實用工具腳本

### 提取 FW 版本狀態列表

```bash
# 提取 FW VU_TABLE 中所有定義的狀態
grep -E "\[VU_STATE_" Source/UFS/ISP/Vcmd/ISP_UFS_Vcmd_Para.c | \
    grep -v "^#" | \
    sed 's/.*\[\(VU_STATE_[^]]*\)\].*/\1/' | \
    sort > fw_states.txt
```

### 檢查 Regression Test 版本註解

```bash
# 檢查 Regression Test 版本的註解是否正確
grep -E "//.*VU_STATE_" Source/UFS/ISP/Vcmd/ISP_UFS_Vcmd_Para.c | \
    grep -A 1 "#ifdef SMI_REGRESSION_TEST" | \
    head -50
```

### 驗證陣列大小

```c
// 在程式碼中加入編譯時檢查
#ifdef SMI_REGRESSION_TEST
    // 確認陣列大小
    static_assert(sizeof(VU_TABLE) / sizeof(VU_TABLE[0]) == VU_STATE_END, 
                  "Regression VU_TABLE size mismatch!");
    
    static_assert(sizeof(VUHandler) / sizeof(VUHandler[0]) == VU_STATE_END, 
                  "Regression VUHandler size mismatch!");
#endif
```

## 八、總結

**對齊原則**：
1. ✅ **FW 版本是基準**：所有修改先在 FW 版本進行
2. ✅ **Regression Test 版本對齊 FW**：按照 ENUM 順序，複製 FW 版本的設定
3. ✅ **不能跳過元素**：Regression Test 版本必須填滿所有索引位置
4. ✅ **註解必須正確**：標註狀態名稱和索引，方便維護
5. ✅ **結構體順序**：傳統語法必須按照結構定義的順序

**關鍵檢查點**：
- ✅ 陣列大小 = `VU_STATE_END`
- ✅ 索引對應 ENUM 值
- ✅ 結構體成員順序正確
- ✅ 條件編譯分支一致
- ✅ 註解標註正確



