首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

U-Boot 2013.07 移植 Mini2440 實戰:SST39VF1601 Nor Flash CFI 驅動修改詳解

     編輯:關於C語言

背景與問題

Mini2440 開發板搭載 SST39VF1601 Nor Flash。U-Boot 2013.07 預設 CFI 驅動 (drivers/mtd/cfi_flash.c) 僅支援標準 AMD/Intel CFI 查詢流程,不支援 SST39VF1601 進入 CFI Query 模式所需的特殊解鎖序列,導致 Flash 識別失敗、無法擦寫。

核心差異:SST 與標準 CFI 進入 Query 模式對比

SST 老舊芯片需多達 4 組解鎖地址/命令序列嘗試,標準驅動僅嘗試 2 組(FLASH_OFFSET_CFI、FLASH_OFFSET_CFI_ALT)。

關鍵代碼修改點 (Patch 解讀)

1. 新增 SST 命令集常數

// include/mtd/cfi_flash.h
#define CFI_CMDSET_SST_OLD  0x701  // SST 老版本命令集 ID

2. 重構 CFI Query 模式進入邏輯

// 核心函數:嘗試多種解鎖序列進入 Query 模式
static int __cfi_qry_mode_on(flash_info_t *info) {
    // 嘗試序列 1: offset 0x55
    flash_write_cmd(info, 0, 0, AMD_CMD_RESET);      // 0xF0
    flash_write_cmd(info, 0, 0x55, FLASH_CMD_CFI);   // 0x98
    if (__cfi_qry_present(info)) { info->cfi_offset = 0x55; return 1; }

    // 嘗試序列 2: offset 0x555
    flash_write_cmd(info, 0, 0, AMD_CMD_RESET);
    flash_write_cmd(info, 0, 0, FLASH_CMD_RESET);    // 0xFF
    flash_write_cmd(info, 0, 0x555, FLASH_CMD_CFI);
    if (__cfi_qry_present(info)) { info->cfi_offset = 0x555; return 1; }

    // 嘗試序列 3: offset 0x5555 (標準 AMD)
    flash_write_cmd(info, 0, 0, AMD_CMD_RESET);
    flash_write_cmd(info, 0, 0x5555, FLASH_CMD_CFI);
    if (__cfi_qry_present(info)) { info->cfi_offset = 0x5555; return 1; }

    // 嘗試序列 4: 完整 AMD 解鎖序列 0x5555/0x2AAA/0x5555
    flash_write_cmd(info, 0, 0, AMD_CMD_RESET);
    flash_write_cmd(info, 0, 0x5555, 0xAA);
    flash_write_cmd(info, 0, 0x2AAA, 0x55);
    flash_write_cmd(info, 0, 0x5555, FLASH_CMD_CFI);
    if (__cfi_qry_present(info)) { info->cfi_offset = 0x5555; return 1; }

    // 嘗試序列 5: 縮短解鎖 0x555/0x2AA/0x555
    flash_write_cmd(info, 0, 0, AMD_CMD_RESET);
    flash_write_cmd(info, 0, 0x555, 0xAA);
    flash_write_cmd(info, 0, 0x2AA, 0x55);
    flash_write_cmd(info, 0, 0x555, FLASH_CMD_CFI);
    if (__cfi_qry_present(info)) { info->cfi_offset = 0x555; return 1; }

    return 0; // 所有嘗試失敗
}

3. 識別到 SST 命令集時設置專用解鎖地址

if (le16_to_cpu(get_unaligned(&qry->p_id)) == CFI_CMDSET_SST_OLD) {
    info->addr_unlock1 = 0x5555;
    info->addr_unlock2 = 0x2AAA;
}

4. 寫入/擦除/檢測流程中註冊 SST 命令集分支

  • flash_write_cfiword:新增 case CFI_CMDSET_SST_OLD: 分支,使用 addr_unlock1 解鎖寫入。
  • flash_erase:新增 SST 分支,解鎖序列 + AMD_CMD_ERASE_START + 扇區擦除命令。
  • flash_get_size:將 SST 歸入 AMD 標準初始化流程 cmdset_amd_init。

Mini2440 配置確認

// include/configs/mini2440.h
#define CONFIG_SYS_FLASH_CFI
#define CONFIG_FLASH_CFI_DRIVER
#define CONFIG_SYS_FLASH_CFI_WIDTH  FLASH_CFI_16BIT

工程經驗總結

  • CFI 標準不完全統一:早期廠商(SST、AMD 舊版)有私有解鎖序列,驅動需兼容多序列嘗試。
  • QRY 字串檢測是金標準:只識別 "Q""R""Y" 三字節,不依賴廠商 ID。
  • 解鎖地址與命令序列要查數據手冊:SST39VF1601 需 0x5555/0x2AAA 解鎖,而非標準 0x555/0x2AA/0x555。
  • Patch 核心思想:將「嘗試進入 Query 模式」抽離為獨立函數,內部按優先級順序嘗試所有已知序列,成功即返回,失敗則嘗試下一組,極大提升驅動通用性。

總結

本次移植通過擴展 U-Boot CFI 驅動的 Query 模式進入邏輯、註冊 SST 專用命令集與解鎖地址,成功支援 Mini2440 上的 SST39VF1601 Nor Flash。該 Patch 體現了嵌入式驅動開發中「兼容多廠商異構序列、以 QRY 檢測為準、優先級嘗試策略」的核心工程智慧,可作為同類 Flash 移植的參考範本。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
步驟標準 AMD/Intel CFISST39VF1601 (舊版 CFI)
1Reset (0xF0)Reset (0xF0)
2Write 0x98 to 0x55 (或 0x555/0x5555)Write 0x98 to 0x55
3讀取 "QRY" 成功 → 完成讀取 "QRY" 失敗
4—Reset → Write 0x98 to 0x555
5—讀取 "QRY" 失敗
6—Reset → Write 0xAA/0x55 to 0x5555/0x2AAA → Write 0x98 to 0x5555
7—讀取 "QRY" 成功 → 完成