一、總線錯誤
1.1 arm總線設計
要了解什么是總線錯誤,就要先了解arm的總線設計。
AMBA(Advanced Micro-Controller Bus Architecture)是由ARM Limited公司推出的On-Chip Bus片上總線規范,是目前芯片總線的主流標準(該標準在不斷演進),常用的總線:高性能總線(AdvancedHigh Performance Bus,AHB)、系統總線(AdvancedSystem Bus,ASB)和外設總線(Advanced PeripheralBus,APB)。
ARM 處理器內核系列 典型內核型號 AMBA 版本 主要總線協議 應用場景 Cortex-M0/M0+ Cortex-M0, Cortex-M0+ AMBA 2.0 AHB-Lite, APB 低功耗、低成本微控制器 Cortex-M3/M4/M7 Cortex-M3, Cortex-M4, M7 AMBA 3.0 AHB-Lite, APB 主流嵌入式應用 Cortex-M23/M33/M55 Cortex-M23, Cortex-M33, M55 AMBA 4.0 AXI4, APB 安全關鍵型應用、IoT Cortex-A 系列(早期) Cortex-A5, A7, A9 AMBA 3.0 AHB, AXI3 智能手機、平板電腦 Cortex-A 系列(現代) Cortex-A15, A53, A57, A72 AMBA 4.0 AXI4, ACE, ACE-Lite 高性能移動設備、服務器 Cortex-A 系列(最新) Cortex-A76, A78, X1 AMBA 5.0 CHI, AXI5 旗艦手機、數據中心 Cortex-R 系列 Cortex-R4, R5, R7, R8 AMBA 3.0/4.0 AXI3, AXI4 汽車電子、工業控制(實時應用) ARM7/ARM9 系列(經典內核) ARM7TDMI, ARM926EJ-S AMBA 2.0 AHB, ASB, APB 傳統嵌入式系統 Neoverse 系列(服務器) Neoverse N1, E1, V1 AMBA 5.0 CHI, AXI5 云計算、數據中心
ARM 系統總線BUS從 CPU 內核開始。這是在 MMU 和 CPU?緩存單元之后,它連接到外圍設備。此 CPU 總線由主時鐘?(fclk) 運行。這與高頻時鐘是同一個概念。對于內存和低速外圍設備來說,這個時鐘非常高。因此,有一個橋bridge將時鐘除以 4 倍(hclk),這用于高速外設。此總線也稱為?AHB 或 ARM 高速總線。內存和圖形外設(Memory and Graphics peripherals)應連接到此總線。同樣,這個 AHB 進入一個橋,以進一步將時鐘除以 2。這用于低速外圍設備。這稱為 APB。ARM 外設總線 (APB)。低速外設(Low speed peripherals),如串行端口、I2C、SPI。
M0采用馮諾依曼結構,而M3,M4采用哈佛結構,具有獨立的數據總線和指令總線。這種將數據總線和指令總線分開的結構,可以大大提高總線的數據存儲量,消除瓶頸效應。
在上圖中,對應總線矩陣(Bus Matrix), 總線矩陣中還有其他總線。需要注意的是,雖然M3,M4的數據總線和指令總線分開,兩者的存儲并沒有分開。以M4內核為例,從官方參考手冊(Documentation – Arm Developer)上可以看出:
I-Code 總線
I-Code的作用是取指令&執行指令,只和指令有關,I-Code 總線是一條基于 AHB-Lite 總線協議的 32 位總線,負責在 0x0000_0000 – 0x1FFF_FFFF 之間的取指操作。取指以字(32位)的長度執行,即使是對于 16 位指令也如此。因此 CPU 內核可以一次取出兩條 16 位 Thumb 指令。
D-Code 總線
D-Code 的作用是對數據讀寫訪問,只和數據有關,D-Code 總線也是一條基于 AHB-Lite 總線協議的 32 位總線,負責在 0x0000_0000 – 0x1FFF_FFFF(與I-Code相同)之間的數據訪問操作。盡管 CM3 支持非對齊訪問,但你絕不會在該總線上看到任何非對齊的地址,這是因為處理器的總線接口會把非對齊的數據傳送都轉換成對齊的數據傳送。因此,連接到 D-Code總線上的任何設備都只需支持 AHB-Lite 的對齊訪問,不需要支持非對齊訪問。
系統總線
系統總線也是一條基于 AHB-Lite 總線協議的 32 位總線,負責在 0x2000_0000 – 0xDFFF_FFFF 和0xE010_0000 – 0xFFFF_FFFF 之間的所有數據傳送,取指和數據訪問都算上。和 D-Code 總線一樣,所有的數據傳送都是對齊的
外設總線
這是一條基于 APB 總線協議的 32 位總線。此總線來負責 0xE004_0000 – 0xE00F_FFFF 之間的私有外設訪問。但是,由于此 APB 存儲空間的一部分已經被 TPIU、 ETM 以及 ROM 表用掉了,就只留下了 0xE004_2000-E00F_F000 這個區間用于配接附加的(私有)外設。
調試訪問端口總線
調試訪問端口總線接口是一條基于“增強型 APB 規格”的 32 位總線,它專用于掛接調試接口,例如 SWJ-DP 和 SW-DP。
1.2?總線錯誤
- 取指,通常被稱作“預取流產”(prefetch abort)
- 數據讀/寫,通常被稱作“數據流產”(data abort)
哪些因素會導致 AHB 回復一個錯誤信號??
- 企圖訪問無效的存儲器 region。常見于訪問的地址沒有相對應的存儲器。
- 設備還沒有作好傳送數據的準備。比如,在尚未初始化 SDRAM 控制器的時候試圖訪問 SDRAM。?
- 在企圖啟動一次數據傳送時,傳送的尺寸不能為目標設備所支持。例如,某設備只接受字型數據,卻試圖送給它字節型數據。?
- 因為某些原因,設備不能接受數據傳送。例如,某些設備只有在特權級下才允許訪問,可當前卻是用戶級。
二、非精準總線錯誤的由來
非精準總線錯誤(Imprecise Bus Fault)的存在主要源于現代處理器為提高性能而采用的異步內存訪問機制和硬件優化設計。這類錯誤的核心特點是:內存訪問失敗與異常觸發之間存在時間差,導致處理器無法精確定位錯誤發生點。以下是具體原因和場景分析:
1. 寫緩沖(Write Buffer)機制
- 原理:處理器為加速內存寫入操作,會將寫請求暫存到寫緩沖中,繼續執行后續指令而不必等待內存寫入完成。若寫緩沖在后續刷新到內存時失敗(如地址未映射、總線斷開),則觸發非精準錯誤。
2. DMA(直接內存訪問)操作
- 原理:DMA 控制器直接訪問系統總線進行數據傳輸,與處理器并行工作。若 DMA 訪問內存失敗(如地址沖突、外設故障),處理器無法立即感知,需等待 DMA 完成或錯誤檢測機制觸發。
- 示例:
若 DMA 傳輸過程中// 啟動DMA傳輸(從外設到內存) DMA_StartTransfer(src_addr, dst_addr, size);// 處理器繼續執行其他代碼(不等待DMA完成) do_something_else();
dst_addr
無效,錯誤會在 DMA 操作后期被檢測到,此時處理器可能已執行多條指令。
3. 緩存(Cache)與預取(Prefetch)機制
- 緩存失效:若緩存行失效后需要從主存重新加載數據,但主存地址不可訪問,可能觸發非精準錯誤。
- 指令預取失敗:處理器預取指令時若發生內存訪問錯誤,可能繼續執行已預取的后續指令,導致錯誤報告延遲。
4. 多周期內存訪問
- 突發傳輸(Burst Transfer):處理器進行連續內存訪問時(如讀取數組),可能采用突發模式。若傳輸過程中某地址出錯,整個突發操作可能完成后才報告錯誤。
- 示例:
若// 連續讀取數組(可能觸發突發傳輸) for (int i = 0; i < 1000; i++) {sum += array[i]; }
array[500]
地址無效,錯誤可能在循環結束后才被檢測到。
5. 外設總線異步錯誤
- 外設通信失敗:如 SPI、I2C 等外設訪問共享內存時發生錯誤,可能通過中斷或狀態標志異步通知處理器,導致錯誤與處理不同步。
- 示例:
// 向外設發送數據(通過內存映射寄存器) PERIPHERAL_DATA_REG = data;// 繼續執行其他代碼(外設可能在后臺處理數據)
若外設訪問內存時出錯,處理器可能已執行到后續代碼。
三、小結
特性 | 精準的總線錯誤 | 非精準的總線錯誤 |
---|---|---|
錯誤發生與處理的關系 | 同步:指令執行立即暫停,異常立即觸發 | 異步:指令繼續執行,異常在后續階段觸發 |
錯誤定位精確性 | 精確:BFAR 寄存器保存錯誤地址 | 不精確:BFAR 通常無效,無法準確定位錯誤 |
LR 寄存器(鏈接寄存器)值 | 指向引發錯誤的指令 | 指向錯誤檢測點之后的指令 |
BFAR 寄存器有效性 | SCB->HFSR.BFARVALID = 1 (有效) | SCB->HFSR.BFARVALID = 0 (無效) |
典型觸發場景 | 指令直接訪問內存失敗(如訪問未映射地址) | 外設或 DMA 異步操作導致的內存訪問失敗 |
觸發條件對比
精準的總線錯誤
- 內存訪問未映射地址:例如訪問
0xFFFFFFFF
。 - 內存訪問權限沖突:如向只讀區域寫入數據。
- 非對齊訪問:例如在不支持非對齊訪問的架構上執行非對齊的字訪問。
- 指令預取失敗:取指階段訪問指令存儲器失敗。
非精準的總線錯誤
- DMA 操作錯誤:直接內存訪問過程中發生總線故障。
- 外設異步錯誤:如 SPI/I2C 傳輸時的 FIFO 溢出。
- 緩存或寫緩沖錯誤:寫緩沖刷新到內存時失敗。
- 多周期內存訪問:如突發傳輸(burst transfer)過程中出錯。
四、調試與排查建議
場景 | 精準錯誤排查方法 | 非精準錯誤排查方法 |
---|---|---|
錯誤地址定位 | 讀取SCB->BFAR | 分析上下文,檢查 DMA / 外設操作 |
寄存器檢查 | SCB->HFSR.BFARVALID == 1 | SCB->HFSR.BFARVALID == 0 |
典型代碼問題 | 野指針、數組越界、錯誤的內存映射 | DMA 配置錯誤、外設中斷處理不當 |
ref:
HardFault錯誤信息分析定位_hardfault定位問題-CSDN博客
https://mbb.eet-china.com/forum/topic/114149_1_1.html
HardFault全解析:從寄存器診斷到精準定位-CSDN博客
Documentation – Arm Developer
《ARMv7-M Architecture Reference Manual》
C 總線錯誤 (bus error) - 段錯誤 (segmentation fault)-CSDN博客
ARM異常處理(3):Bus faults、Memory management faults、Usage faults、Hard faults詳解-CSDN博客
《Cortex‐M3 權威指南》 ,第七章,總線 Faults
AMBA – Arm?
?ARM bus hierarchy - ARM highspeed bus/AHB and ARM peripheral bus/APB
AMBA Specifications – Arm?
嵌入式調試必修課11_MCU總線接口深度解析(Part I):I-Code/D-Code/S-Bus的工作原理_嗶哩嗶哩_bilibili
Cortex-M3 I-Code,D-Code,系統總線及其他總線接口_m3 編譯區分 如何d總線,s總線-CSDN博客?