以下內容由 DeepSeek R1 生成根據你提供的批處理腳本和現象分析,問題的核心在于 srec_cat工具對HEX文件的裁剪邏輯不完整,導致未勾選批處理時HEX文件中殘留了編譯器生成的填充數據,而勾選批處理時意外截斷了這些數據。以下是詳細分析和解決方案:
問題根源編譯器填充行為 Keil編譯器在生成HEX文件時,默認會根據Flash扇區(qū)大小(如STM32F407的16KB/128KB)對代碼段進行填充,填充內容通常為0xFF或未定義值。這些填充數據在MAP文件中不會顯示,但實際會存在于HEX文件中。 批處理腳本的裁剪缺陷 你的批處理腳本通過srec_cat裁剪HEX文件時,僅保留了0x08020000到CRC_ADDR之間的數據,忽略了CRC_ADDR之后可能存在的填充數據。這導致:
Flash擦除差異 Keil燒錄時可能僅擦除代碼占用的扇區(qū),而J-Flash默認擦除整個扇區(qū),導致未初始化區(qū)域被填充為隨機值(如0x00),覆蓋了中斷向量表或其他關鍵數據。
解決方案修改批處理腳本,確保在計算CRC后,保留原HEX文件中CRC_ADDR之后的所有填充數據。以下是修正后的腳本關鍵步驟: 1. 修改srec_cat命令將第二個srec_cat命令改為合并三部分數據: 原HEX的CRC地址前部分 (0x08020000到CRC_ADDR) 新生成的CRC部分 (CRC_ADDR到CRC_ADDR_END) 原HEX的CRC地址后部分 (CRC_ADDR_END到Flash末尾)
REM 合并三部分:原HEX的CRC前部分 + 新CRC部分 + 原HEX的CRC后部分
CRC_BIN\srec_cat.exe ^
1.hex -intel -crop %CRCA_START_ADDR% %CRC_ADDR% ^
BRMU\BRMU_checked.hex -intel -crop %CRC_ADDR% %CRC_ADDR_END% ^
1.hex -intel -crop %CRC_ADDR_END% 0x08080000 ^
-o 1.hex -intel -output_Block_Size 0x102. 添加Flash范圍參數明確指定Flash的完整地址范圍(如0x08000000到0x08080000),確保填充未使用的區(qū)域為0xFF: REM 生成臨時CRC文件時填充未使用區(qū)域
CRC_BIN\srec_cat.exe ^
1.hex -intel ^
-crop %CRCA_START_ADDR% %CRC_ADDR% ^
-fill 0xFF %CRCA_START_ADDR% 0x08080000 ^
-stm32-l-e %CRC_ADDR% ^
-o BRMU\BRMU_checked.hex -intel
完整修正腳本 @echo off
ECHO Computing CRC
ECHO -------------------------------------
SET MAP_FILE=1.map
SET TMP_FILE=crc_temp.txt
REM 提取CRC地址
FINDSTR /R /C:"^ *CHECKSUM" %MAP_FILE% > %TMP_FILE%
SET /p crc_search=<%TMP_FILE%
DEL %TMP_FILE%
FOR /F "tokens=1 delims=(" %%a IN ("%crc_search%") DO SET crc_search=%%a
SET crc_search=%crc_search:CHECKSUM=%
FOR /F "tokens=1 delims= " %%a IN ("%crc_search%") DO SET CRC_ADDR=%%a
SET /a CRC_ADDR_END=%CRC_ADDR% + 4
SET CRCA_START_ADDR=0x08020000
REM 生成包含CRC的臨時文件,并填充未使用區(qū)域為0xFF
CRC_BIN\srec_cat.exe ^
1.hex -intel ^
-crop %CRCA_START_ADDR% %CRC_ADDR% ^
-fill 0xFF %CRCA_START_ADDR% 0x08080000 ^
-stm32-l-e %CRC_ADDR% ^
-o BRMU\BRMU_checked.hex -intel
REM 合并原HEX的CRC前部分、新CRC部分、原HEX的CRC后部分
CRC_BIN\srec_cat.exe ^
1.hex -intel -crop %CRCA_START_ADDR% %CRC_ADDR% ^
BRMU\BRMU_checked.hex -intel -crop %CRC_ADDR% %CRC_ADDR_END% ^
1.hex -intel -crop %CRC_ADDR_END% 0x08080000 ^
-o 1.hex -intel -output_Block_Size 0x10
REM 清理臨時文件
DEL BRMU\BRMU_checked.hex
ECHO -------------------------------------
關鍵改進點保留填充數據 通過-crop %CRC_ADDR_END% 0x08080000顯式保留原HEX文件中CRC地址后的所有數據,避免截斷編譯器生成的填充。 統一填充值 使用-fill 0xFF ...確保未使用的Flash區(qū)域被初始化為0xFF,避免J-Flash讀取到隨機值。 完整Flash覆蓋 指定Flash的完整地址范圍(0x08080000為STM32F407VGT6的Flash末尾地址),確保操作覆蓋整個空間。
驗證方法HEX文件對比 使用二進制工具(如HexCompare)對比Keil生成的原始HEX和批處理后的HEX,確認CRC地址后的數據是否一致。 Flash內容檢查 在Keil調試模式下,通過Memory窗口查看CRC_ADDR之后的Flash內容,確認是否為0xFF或有效數據。 J-Flash燒錄測試 使用修正后的HEX文件通過J-Flash燒錄,驗證App是否能正常啟動。
通過上述修正,批處理腳本將正確保留編譯器生成的填充數據,同時確保CRC校驗碼的完整性,解決J-Flash反讀多余數據導致程序無法運行的問題。
|