在當(dāng)今電子科技飛速發(fā)展的時代, MCU 芯片成為眾多企業(yè)追求技術(shù)突破與創(chuàng)新的關(guān)鍵領(lǐng)域。而芯片的調(diào)試過程則是確保其性能與可靠性的重要環(huán)節(jié)。本文以國科安芯自研 AS32A601為例,旨在詳細(xì)記錄基于 RISC-V 架構(gòu)的 MCU 芯片JTAG 調(diào)試過程及操作,為后續(xù)類似調(diào)試工作提供詳實參考的依據(jù),助力研發(fā)團(tuán)隊高效推進(jìn)芯片研發(fā)進(jìn)程。
RISC-V 架構(gòu)以其開源、模塊化等優(yōu)勢在 MCU 芯片領(lǐng)域嶄露頭角。JTAG(Joint Test Action Group)調(diào)試技術(shù)作為芯片調(diào)試的主流手段之一,為我們深入芯片內(nèi)部、精準(zhǔn)定位問題提供了有力支持。
我們將深入記錄 MCU 芯片AS32A601在 JTAG 調(diào)試過程中的具體操作步驟。從硬件連接的細(xì)節(jié),包括如何正確設(shè)置 JTAG 接口與仿真器的連接,確保信號傳輸?shù)姆€(wěn)定與準(zhǔn)確;到軟件調(diào)試工具的配置與使用技巧,如調(diào)試環(huán)境的搭建、調(diào)試指令的編寫與執(zhí)行等,都將一一呈現(xiàn)。同時,針對調(diào)試過程中可能遇到的常見問題,如通信故障、數(shù)據(jù)讀取錯誤等,也會詳細(xì)分析原因并提供相應(yīng)的解決方法。
通過這份詳盡的記錄,我們期望為后續(xù)的芯片研發(fā)與調(diào)試工作積累寶貴經(jīng)驗,幫助研發(fā)團(tuán)隊更加高效、精準(zhǔn)地完成自研 MCU 芯片的開發(fā)與優(yōu)化任務(wù)。這不僅有助于提升芯片產(chǎn)品的質(zhì)量和性能,也對推動整個團(tuán)隊在 RISC-V 架構(gòu)領(lǐng)域的技術(shù)進(jìn)步具有重要意義,為未來在復(fù)雜芯片設(shè)計與調(diào)試領(lǐng)域的深入探索奠定堅實基礎(chǔ)。
JTAG簡介
接口
TCK 應(yīng)接下拉電阻,按照 IEEE 1149.1 的要求,被測芯片在 TCK 保持低電平的情況下將保持原有的狀態(tài),所以 TCK 應(yīng)該拉低,確保在沒有接仿真器時 TCK 是低電平狀態(tài)。
TMS 應(yīng)接上拉電阻,根據(jù) TAP 狀態(tài)機(jī),任意狀態(tài)下,只要 TMS 保持高電平 5 個時鐘,那么就會進(jìn)入復(fù)位狀態(tài),所以 TMS 拉高是安全的。
TAP狀態(tài)機(jī)
所有JTAG操作的源頭都是由一個具有16個狀態(tài)的同步狀態(tài)機(jī)控制。該控制器使用TCK作為時鐘,使用TMS作為輸入。如果需要復(fù)位時使用TRSTN。狀態(tài)的跳轉(zhuǎn)是由TMS輸入1或0決定。 JTAG的TAP狀態(tài)機(jī)
狀態(tài)機(jī)介紹: 寄存器可以分為兩大類,數(shù)據(jù)寄存器和指令寄存器。 標(biāo)識有DR的這些狀態(tài)是用來訪問數(shù)據(jù)寄存器的,標(biāo)識有IR的這些狀態(tài)是用來訪問指令寄存器的。
常用的狀態(tài)說明如下所示:
- Test-Logic-Select(TLS):系統(tǒng)上電后,TAP Controller 自動進(jìn)入該狀態(tài)。在該狀態(tài)下,測試部分的邏輯電路全部被禁用,以保證芯片核心邏輯電路的正常工作。通過 TRST 信號也可以對測試邏輯電路進(jìn)行復(fù)位,使得 TAP Controller 進(jìn)入 Test-Logic Reset 狀態(tài)。TRST 是可選的一個信號接口,這是因為在 TMS 上連續(xù)加 5 個 TCK 脈沖寬度的“1”信號也可以對測試邏輯電路進(jìn)行復(fù)位,使得 TAP Controller 進(jìn)入 Test-Logic Reset 狀態(tài)。所以,在不提供 TRST信號的情況下,也不會產(chǎn)生影響。在該狀態(tài)下,如果 TMS 一直保持為“1”,TAP Controller將保持在 Test-Logic Reset 狀態(tài)下;如果 TMS 由“1”變?yōu)椤?”(在 TCK 的上升沿觸發(fā)), 將使 TAP Controller 進(jìn)入 Run-Test/Idle 狀態(tài)。
- Run-Test/Idle:這個是 TAP Controller 在不同操作間的一個中間狀態(tài)。這個狀態(tài)下的動作取決于當(dāng)前指令寄存器中的指令。有些指令會在該狀態(tài)下執(zhí)行一定的操作,而有些指令在該狀態(tài)下不需要執(zhí)行任何操作。在該狀態(tài)下,如果 TMS 一直保持為“0”,TAP Controller 將一直保持在 Run-Test/Idle 狀態(tài)下;如果 TMS 由“0”變?yōu)椤?”(在 TCK 的上升沿觸發(fā)),將使 TAPController 進(jìn)入 Select-DR-Scan 狀態(tài)。
- Select-DR-Scan:這是一個臨時的中間狀態(tài)。如果 TMS 為“0” (在 TCK 的上升沿觸發(fā)),TAP Controller進(jìn)入 Capture-DR 狀態(tài),后續(xù)的系列動作都將以數(shù)據(jù)寄存器作為操作對象;如果 TMS 為“1” (在 TCK 的上升沿觸發(fā)),TAP Controller 進(jìn)入 Select-IR-Scan 狀態(tài)。
- Capture-DR:當(dāng) TAP Controller 在這個狀態(tài)中,且當(dāng)前指令是SAMPLE/PRELOAD指令,那么邊界掃描寄存器BSR在TCK信號的上升沿捕 獲輸入管腳的數(shù)據(jù)。如果此時不是SAMPLE/PRELOAD指令,那么BSR保持它們先前的值,另外BSR的值被放入連接在TDI和TDO管腳之間的移 位寄存器中。如果 TMS 為“0” (在 TCK 的上升沿觸發(fā)),TAP Controller 進(jìn)入 Shift-DR 狀態(tài);如果 TMS 為“1” (在 TCK 的上升沿觸發(fā)),TAPController 進(jìn)入 Exit1-DR 狀態(tài)。
- Shift-DR:在這個狀態(tài)中,由 TCK 驅(qū)動,每一個時鐘周期,被連接在 TDI 和 TDO 之間的數(shù)據(jù)寄存器將從 TDI 接收一位數(shù)據(jù),同時通過 TDO 輸出一位數(shù)據(jù)。如果 TMS 為“0” (在 TCK的上升沿觸發(fā)),TAP Controller 保持在 Shift-DR 狀態(tài); 如果 TMS 為“1” (在 TCK 的上升沿觸發(fā)),TAP Controller 進(jìn)入到 Exit1-DR 狀態(tài)。假設(shè)當(dāng)前的數(shù)據(jù)寄存器的長度為 4。如果 TMS 保持為 0,那在 4 個 TCK 時鐘周期后,該數(shù)據(jù)寄存器中原來的 4 位數(shù)據(jù)(一般是在 Capture-DR 狀態(tài)中捕獲的數(shù)據(jù))將從 TDO 輸出來;同時該數(shù)據(jù)寄存器中的每個寄存器單元中將分別獲得從 TDI 輸入的 4 位新數(shù)據(jù)。
- Exit1-DR:Exit1-DR是TAP控制器的一個臨時狀態(tài),如果TMS信號在下一個TCK上升沿處于高電平,TAP進(jìn)入Update-DR狀態(tài);如果TMS信號在下一個TCK上升沿處于低電平,則TAP進(jìn)入Pause-DR狀態(tài)。處于Exit1-DR狀態(tài)時,指令不會被改變。
- Pause-DR: Pause-DR狀態(tài)允許TAP控制器暫時停止TDI-移位寄存器-TDO串行通道的移位操作。處于Pause-DR狀態(tài)時,指令不會被改變。如果TMS信號在下一個TCK上升沿處于高電平,TAP進(jìn)入Exit2-DR狀態(tài);如果TMS信號處于低電平,則TAP一直保持暫停狀態(tài)。
- Exit2-DR:Exit2-DR也是TAP控制器的臨時狀態(tài),如果TMS信號在下一個TCK上升沿處于高電平,TAP進(jìn)入Update-DR狀態(tài),結(jié)束掃描操作;如果TMS信號在下一個TCK上升沿處于低電平,則TAP重新進(jìn)入Shift-DR狀態(tài)。處于Exit2-D狀態(tài)時,指令不會被改變。
- Update-DR:在 Update-DR 狀態(tài)下,由 TCK 上升沿驅(qū)動,數(shù)據(jù)寄存器當(dāng)中的數(shù)據(jù)將被加載到相應(yīng)的芯片管腳上去,用以驅(qū)動芯片。在該狀態(tài)下,如果 TMS 為“0”,TAP Controller 將回到Run-Test/Idle 狀態(tài);如果 TMS 為“1”,TAP Controller 將進(jìn)入 Select-DR-Scan 狀態(tài)。
- Select-IR-Scan:這是一個臨時的中間狀態(tài)。如果 TMS 為“0” (在 TCK 的上升沿觸發(fā)),TAP Controller進(jìn)入 Capture-IR 狀態(tài),后續(xù)的系列動作都將以指令寄存器作為操作對象;如果 TMS 為“1” (在 TCK 的上升沿觸發(fā)),TAP Controller 進(jìn)入 Test-Logic Reset 狀態(tài)。
- Capture-IR:當(dāng) TAP Controller 在這個狀態(tài)中,在 TCK 的上升沿,一個特定的邏輯序列將被裝載到指令寄存器中去。如果 TMS 為“0” (在 TCK 的上升沿觸發(fā)),TAP Controller 進(jìn)入 Shift-IR狀態(tài);如果 TMS 為“1” (在 TCK 的上升沿觸發(fā)),TAP Controller 進(jìn)入 Exit1-IR 狀態(tài)。
- Shift-IR:在這個狀態(tài)中,由 TCK 驅(qū)動,每一個時鐘周期,被連接在 TDI 和 TDO 之間的指令寄存器將從 TDI 接收一位數(shù)據(jù),同時通過 TDO 輸出一位數(shù)據(jù)。如果 TMS 為“0” (在 TCK的上升沿觸發(fā)),TAP Controller 保持在 Shift-IR 狀態(tài); 如果 TMS 為“1” (在 TCK 的上升沿觸發(fā)),TAP Controller 進(jìn)入到 Exit1-IR 狀態(tài)。假設(shè)指令寄存器的長度為 4。如果TMS 保持為 0,那在 4 個 TCK 時鐘周期后,指令寄存器中原來的 4bit 長的特定邏輯序列(在 Capture-IR 狀態(tài)中捕獲的特定邏輯序列)將從 TDO 輸出來,該特定的邏輯序列可以用來判斷操作是否正確;同時指令寄存器將獲得從 TDI 輸入的一個 4bit 長的新指令。
- Exit1-IR:Exit1-IR是TAP控制器的一個臨時狀態(tài),如果TMS信號在下一個TCK上升沿處于高電平,TAP進(jìn)入Update-IR狀態(tài);如果TMS信號在下一個TCK上升沿處于低電平,則TAP進(jìn)入Pause-IR狀態(tài)。處于Exit1-IR狀態(tài)時,指令不會被改變。
- Pause-IR:Pause-IR狀態(tài)允許TAP控制器暫時停止TDI-移位寄存器-TDO串行通道的移位操作。處于Pause-IR狀態(tài)時,指令不會被改變。如果TMS信號在下一個TCK上升沿處于高電平,TAP進(jìn)入Exit2-IR狀態(tài);如果TMS信號處于低電平,則TAP一直處于暫停狀態(tài)。
- Exit2-IR:Exit2-IR也是TAP控制器的臨時狀態(tài),如果TMS信號在下一個TCK上升沿處于高電平,TAP進(jìn)入Update-IR狀態(tài),結(jié)束掃描操作;如果TMS信號在下一個TCK上升沿處于低電平,則TAP重新進(jìn)入Shift-IR狀態(tài)。處于Exit2-D狀態(tài)時,指令不會被改變。
- Update-IR:在這個狀態(tài)中,在 Shift-IR 狀態(tài)下輸入的新指令將被用來更新指令寄存器。
JTAG訪問的一般過程:
- 系統(tǒng)上電,TAP Controller 進(jìn)入 Test-Logic Reset 狀態(tài),然后依次進(jìn)入:Run-Test/Idle → Select-DR-Scan → Select-IR-Scan →Capture-IR →Shift-IR →Exit1-IR→Update-IR,最后回到 Run-Test/Idle 狀態(tài)。在 Capture-IR 狀態(tài)中,一個特定的邏輯序列被加載到指令寄存器當(dāng)中;然后進(jìn)入到 Shift-IR 狀態(tài)。在 Shift-IR 狀態(tài)下,通過 TCK 的驅(qū)動,可以將一條特定的指令送到指令寄存器當(dāng)中去。每條指令都將確定一條相關(guān)的數(shù)據(jù)寄存器。然后從 Shift-IR →Exit1-IR → Update-IR。在 Update-IR 狀態(tài),剛才輸入到指令寄存器中的指令將用來更新指令寄存器。最后,進(jìn)入到 Run-Test/Idle 狀態(tài),指令生效,完成對指令寄存器的訪問。
- 當(dāng)前可以訪問的數(shù)據(jù)寄存器由指令寄存器中的當(dāng)前指令決定。要訪問由剛才的指令選定的數(shù)據(jù)寄存器,需要以 Run-Test/Idle 為起點,依次進(jìn)入 Select-DR-Scan →Capture-DR →Shift-DR →Exit1-DR →Update-DR,最后回到 Run-Test/Idle 狀態(tài)。在這個過程當(dāng)中,被當(dāng)前指令選定的數(shù)據(jù)寄存器會被連接在 TDI 和 TDO 之間。通過TDI 和 TDO,就可以將新的數(shù)據(jù)加載到數(shù)據(jù)寄存器當(dāng)中去,同時,也可以捕獲數(shù)據(jù)寄存器中的數(shù)據(jù)。具體過程如下。在 Capture-DR 狀態(tài)中,由 TCK 的驅(qū)動,芯片管腳上的輸出信號會被“捕獲”到相應(yīng)的邊界掃描寄存器單元中去。這樣,當(dāng)前的數(shù)據(jù)寄存器當(dāng)中就記錄了芯片相應(yīng)管腳上的輸出信號。接下來從 Capture-DR 進(jìn)入到Shift-DR 狀態(tài)中去。在 Shift-DR 狀態(tài)中,由 TCK 驅(qū)動,在每一個時鐘周期內(nèi),一位新的數(shù)據(jù)可以通過 TDI 串行輸入到數(shù)據(jù)寄存器當(dāng)中去,同時,數(shù)據(jù)寄存器可以通過TDO 串行輸出一位先前捕獲的數(shù)據(jù)。在經(jīng)過與數(shù)據(jù)寄存器長度相同的時鐘周期后,就可以完成新信號的輸入和捕獲數(shù)據(jù)的輸出。接下來通過 Exit1-DR 狀態(tài)進(jìn)入到Update-DR 狀態(tài)。在 Update-DR 狀態(tài)中,數(shù)據(jù)寄存器中的新數(shù)據(jù)被加載到與數(shù)據(jù)寄存器的每個寄存器單元相連的芯片管腳上去。最后,回到 Run-Test/Idle 狀態(tài),完成對數(shù)據(jù)寄存器的訪問。
debug寄存器
目前RISC-V的官方調(diào)試上位機(jī)是openocd,調(diào)試工具可以是JLink或者CMSIS-DAP,RISCV調(diào)試框架如圖所示。 RISC-V調(diào)試系統(tǒng)框架
DTM模塊
作為DTM使用的JTAG tap必須具有至少5位的IR。當(dāng)TAP時,IR必須默認(rèn)為00001,選擇IDCODE指令。DTM模塊的寄存器定義如圖所示。 DTM寄存器
IDCODE寄存器(0x01)
當(dāng)TAP狀態(tài)機(jī)復(fù)位時,IR寄存器的值默認(rèn)為0x01,即選擇的是IDCODE寄存器。IDCODE寄存器的每一位含義如圖5所示。IDCODE是只讀寄存器。 IDCODE寄存器
Version:只讀,版本號,可為任意值。 PartNumber:只讀,可為任意值。 Manufld:只讀,廠商號,遵循JEP106標(biāo)準(zhǔn)分配,實際中可為任意值,只要不與已分配的廠商號沖突即可。
DTM控制和狀態(tài)寄存器(dtmcs,0x10)
dtmcs寄存器
dmihardreset:DTM模塊硬復(fù)位,寫1有效。 dmireset:清除出錯,寫1有效。 idle:只讀,JTAG 主機(jī)在Run-Test-Idle狀態(tài)停留的時鐘周期數(shù),0表示不需要進(jìn)入Run-Test-Idle狀態(tài),1表示進(jìn)入 Run-Test-Idle狀態(tài)后可以馬上進(jìn)入下一個狀態(tài),以此類推。 dmistat:只讀,上一次操作的狀態(tài)。0表示無出錯,1或者2表示操作出錯,3表示操作還未完成。 abits:只讀,dmi寄存器中address域的大小(位數(shù))。 version:只讀,實現(xiàn)所對應(yīng)的spec版本,0表示0.11版本,1表示0.13版本。
DM模塊接口訪問寄存器(dmi,0x11)
dmi寄存器
address:可讀可寫,DM寄存器的長度(位數(shù))。 data:可讀可寫,往DM寄存器讀、寫的數(shù)據(jù),固定為32位。 op:可讀可寫,讀或者寫這個域時有不同的含義。當(dāng)寫這個域時,寫0表示忽略address和data的值,相當(dāng)于nop操作;寫1表示從address指定的寄存器讀數(shù)據(jù);寫2表示把data的數(shù)據(jù)寫到address指定的寄存器。寫3為保留值。當(dāng)讀這個域時,0表示上一個操作正確完成;1為保留值;2表示上一個操作失敗,這個狀態(tài)是會被記住的,因此需要往dtmcs寄存器的dmireset域?qū)?才能清除這個狀態(tài)。3表示上一個操作還未完成。
在Update-DR狀態(tài)時,DTM開始執(zhí)行op指定的操作。在Capture-DR狀態(tài)時,DTM更新data域。
BYPASS寄存器(0x1f)
只讀,長度為1,值固定為0。
DM模塊
DM模塊的寄存器都為32位,定義如圖所示(只描述主要寄存器)。
data0寄存器(0x04)
此寄存器是用于abstract command的數(shù)據(jù)寄存器,長度為32位,可讀可寫。
dmcontrol寄存器(0x10)
dmcontrol寄存器
haltreq:只寫,寫1表示halt(暫停)當(dāng)前hart(hart表示CPU核,存在多核的情況)。 resumereq:只能寫1,寫1表示resume(恢復(fù))當(dāng)前hart,即go。 hartreset:可讀可寫,寫1表示復(fù)位DM模塊,寫0表示撤銷復(fù)位,這是一個可選的位。 ackhavereset:只能寫1,寫1表示清除當(dāng)前hart的havereset狀態(tài)。 hasel:可讀可寫,0表示當(dāng)前只有一個已經(jīng)被選擇了的hart,1表示當(dāng)前可能有多個已經(jīng)被選擇了的hart。 hartsello:可讀可寫,當(dāng)前選擇的hart的低10位。1位表示一個hart。 hartselhi:可讀可寫,當(dāng)前選擇的hart的高10位。1位表示一個hart。如果只有一個hart,那么hasel的值為0, hartsello的值為1,hartselhi的值為0。 setresethaltreq:只能寫1,寫1表示當(dāng)前選擇的hart復(fù)位后處于harted狀態(tài)。 clrresethaltreq:只能寫1,寫1表示清除setresethaltreq的值。 ndmreset:可讀可寫,寫1表示復(fù)位整個系統(tǒng),寫0表示撤銷復(fù)位。 dmactive:可讀可寫,寫0表示復(fù)位DM模塊,寫1表示讓DM模塊正常工作。正常調(diào)試時,此位必須為1。
dmstatus寄存器(0x11)
dmstatus寄存器
impebreak:1表示執(zhí)行完progbuf的指令后自動插入一條ebreak指令,這樣就可以節(jié)省一個progbuf。當(dāng)progbufsize的 值為1時,此值必須為1。 allhavereset:1表示當(dāng)前選擇的hart已經(jīng)復(fù)位。 anyhavereset:1表示當(dāng)前選擇的hart至少有一個已經(jīng)復(fù)位。 allresumeack:1表示當(dāng)前選擇的所有hart已經(jīng)應(yīng)答上一次的resume請求。 anyresumeack:1表示當(dāng)前選擇的hart至少有一個已經(jīng)應(yīng)答上一次的resume請求。 allnonexistent:1表示當(dāng)前選擇的hart不存在于當(dāng)前平臺。 anynonexistent:1表示至少有一個選擇了的hart不存在于當(dāng)前平臺。 allunavail:1表示當(dāng)前選擇的hart都不可用。 anyunavail:1表示至少有一個選擇了的hart不可用。 allrunning:1表示當(dāng)前選擇的hart都處于running狀態(tài)。 anyrunning:1表示至少有一個選擇了的hart處于running狀態(tài)。 allhalted:1表示當(dāng)前選擇的hart都處于halted狀態(tài)。 anyhalted:1表示至少有一個選擇了的hart處于halted狀態(tài)。 authenticated:0表示使用DM模塊之前需要進(jìn)行認(rèn)證,1表示已經(jīng)通過認(rèn)證。 authbusy:0表示可以進(jìn)行正常的認(rèn)證,1表示認(rèn)證處于忙狀態(tài)。 hasresethaltreq:1表示DM模塊支持復(fù)位后處于halted狀態(tài),0表示不支持。 confstrptrvalid:1表示confstrptr0~3寄存器保存了配置字符串的地址。 version:0表示DM模塊不存在,1表示DM模塊的版本為0.11,2表示DM模塊的版本為0.13。
abstractcs寄存器(0x16)
abstractcs寄存器
progbufsize:只讀,program buffer的個數(shù),取值范圍為0~16,每一個的大小為32位。 busy:只讀,1表示abstract命令正在執(zhí)行,當(dāng)寫command寄存器后該位應(yīng)該馬上被置位直到命令執(zhí)行完成。 cmderr:可讀、只能寫1,cmderr的值僅當(dāng)busy位為0時有效。0表示無錯誤,1表示正在操作command、abstractcs、 data或者progbuf寄存器,2表示不支持當(dāng)前命令,3表示執(zhí)行命令時出現(xiàn)異常,4表示由于當(dāng)前hart不可用,或者不是處 于halted/running狀態(tài)而不能被執(zhí)行,5表示由于總線出錯(對齊、訪問大小、超時)導(dǎo)致的錯誤,7表示其他錯誤。寫1清 零cmderr。 datacount:只讀,所實現(xiàn)的data寄存器的個數(shù)。
command寄存器(0x17)
當(dāng)寫這個寄存器時,相應(yīng)的操作就會被執(zhí)行,command寄存器只能寫。 command寄存器
cmdtype:只寫,命令類型,0為表示訪問寄存器,1表示快速訪問,2表示訪問內(nèi)存。 control:只寫,不同的命令類型有不同的含義,說明如下。
當(dāng)cmdtype為0時,control定義下圖所示。
cmdtype:值為0。 aarsize:2表示訪問寄存器的最低32位,3表示訪問寄存器的最低64位,4表示訪問寄存器的最低128位。如果大于實際寄存器的大小則此次訪問是失敗的。 aarpostincrement:1表示成功訪問寄存器后自動增加regno的值。 postexec:1表示執(zhí)行progbuf里的內(nèi)容(指令)。 transfer:0表示不執(zhí)行write指定的操作,1表示執(zhí)行write指定的操作。 write:0表示從指定的寄存器拷貝數(shù)據(jù)到arg0指定的data寄存器。1表示從arg0指定的data寄存器拷貝數(shù)據(jù)到指定的寄存器。 regno:要訪問的寄存器。
綜上,可知:
- 當(dāng)write=0,transfer=1時,從regno指定的寄存器拷貝數(shù)據(jù)到arg0對應(yīng)的data寄存器。
- 當(dāng)write=1,transfer=1時,從arg0對應(yīng)的data寄存器拷貝數(shù)據(jù)到regno指定的寄存器。
- 當(dāng)aarpostincrement=1時,將regno的值加1。
- 當(dāng)postexec=1時,執(zhí)行progbuf寄存器里的指令。
當(dāng)cmdtype為1時,control定義下圖所示。
cmdtyte:值為1。
此命令會執(zhí)行以下操作:
- halt住當(dāng)前hart。
- 執(zhí)行progbuf寄存器里的指令。
- resume當(dāng)前hart。
當(dāng)cmdtype為2時,control定義下圖所示。
cmdtype:值為2。 aamvirtual:0表示訪問的是物理地址,1表示訪問的是虛擬地址。 aamsize:0表示訪問內(nèi)存的低8位,1表示訪問內(nèi)存的低16位,2表示訪問內(nèi)存的低32位,3表示訪問內(nèi)存的低64位,4表示訪問內(nèi)存的低128位。 aampostincrement:1表示訪問成功后,將arg1對應(yīng)的data寄存器的值加上aamsize對應(yīng)的字節(jié)數(shù)。 write:0表示從arg1指定的地址拷貝數(shù)據(jù)到arg0指定的data寄存器,1表示從arg0指定的data寄存器拷貝數(shù)據(jù)到arg1指 定的地址。 target-specific:保留。
綜上,可知:
- 當(dāng)write=0時,從arg1指定的地址拷貝數(shù)據(jù)到arg0指定的data寄存器。
- 當(dāng)write=1時,從arg0指定的data寄存器拷貝數(shù)據(jù)到arg1指定的地址。
- 當(dāng)aampostincrement=1時,增加arg1對應(yīng)的data寄存器的值。
abstractauto寄存器(0x18)
abstractauto寄存器
autoexecprogbuf:當(dāng)該字段中的一個位為1時,對對應(yīng)進(jìn)程單詞的讀寫訪問會導(dǎo)致DM在進(jìn)程訪問完成后將命令中的當(dāng)前值再次寫入其中。 autoexecdata:當(dāng)該字段中的一個位為1時,對相應(yīng)數(shù)據(jù)字的讀寫訪問會導(dǎo)致DM在數(shù)據(jù)訪問完成后將命令中的當(dāng)前值再次寫入那里。
progbuf0寄存器(0x20)
progbuf0寄存器
progbuf寄存器必須提供program buffer的寫訪問權(quán)限,debugger可通過這些寄存器對program buffer讀訪問,讀不支持時返回0。 progbufsize 表示從progbuf0開始實現(xiàn)多少progbuf寄存器。 在執(zhí)行抽象命令時訪問這些寄存器時,如果cmderr為0,則會將其設(shè)置為1(busy)。 在busy時嘗試編寫它們不會改變它們的值。
操作流程
debug讀寫內(nèi)存和寄存器步驟
Reading Memory
使用 Program Buffer 從內(nèi)存中讀取數(shù)據(jù)
program buffer 方式讀取單字
program buffer 方式讀取塊
Writing Memory
使用 Program Buffer 往內(nèi)存中寫入數(shù)據(jù)
program buffer 方式寫單字
program buffer方式寫塊
debug實際運行狀態(tài)
邏輯分析儀解析JTAG協(xié)議配置
注:下圖TDI為仿真器輸入信號,TDO為仿真器輸出信號。
讀取內(nèi)存步驟
本例:讀取0x20000000地址的數(shù)據(jù),以openocd指令操作為例(指令操作為mdw 0x20000000),返回數(shù)據(jù)為0x100002bc。
- 此波形為操作dmi(0x11)寄存器,向progbuf0寄存器寫入lw s0, 0(s0)指令(以gcc/openocd操作為例)。
2.此波形為nop操作。
3.此波形為操作dmi(0x11)寄存器,向progbuf1寄存器寫入ebreak指令(以gcc/openocd操作為例)。
- 此波形為nop操作。
- 此波形為操作dmi(0x11)寄存器,向data0寄存器寫數(shù)據(jù)0x20000000,表示要寫入要讀取的地址。
- 此波形為nop操作。
- 此波形為操作dmi(0x11)寄存器,從而操作command(0x17)寄存器,從而進(jìn)行執(zhí)行progbuf寄存器里的指令、data0數(shù)據(jù)寫入s0的操作。
- 此波形為操作dmi(0x11)寄存器,發(fā)送讀取abstractcs(0x16)寄存器操作。
- 此波形為nop操作,通過TDO線數(shù)據(jù)獲取狀態(tài)正常。
- 此波形為操作dmi(0x11)寄存器,從而操作command(0x17)寄存器,從而進(jìn)行將s0的數(shù)據(jù)拷貝到data0的操作。
- 此波形為操作dmi(0x11)寄存器,發(fā)送讀取abstractcs(0x16)寄存器操作。
- 此波形為nop操作,通過TDO線數(shù)據(jù)獲取狀態(tài)正常。
- 此波形為操作dmi(0x11)寄存器,進(jìn)行讀取data0寄存器的操作。
- 此波形為nop操作,通過TDO線數(shù)據(jù)獲取要讀取內(nèi)存地址的數(shù)據(jù):0x100002bc。
上述流程描述了通過Program Buffer方式讀內(nèi)存操作,實際操作中會加入讀取狀態(tài)寄存器等操作,確保操作正常。mdw實際操作還會加入保存恢復(fù)s0寄存器,執(zhí)行fence指令等,這里不進(jìn)行過多描述。
寫內(nèi)存步驟
本例:向0x20000000地址寫入數(shù)據(jù)0x12345678,以openocd指令操作為例(指令操作為mww 0x20000000 0x12345678)。
- 此波形為操作dmi(0x11)寄存器,向progbuf0寄存器寫入sw s1,0(s0)指令(以gcc/openocd操作為例)。
- 此波形為nop操作
3.此波形為操作dmi(0x11)寄存器,向progbuf1寄存器寫入addi s0, s0, 4指令(以gcc/openocd操作為例)。
- 此波形為nop操作
- 此波形為操作dmi(0x11)寄存器,向data0寄存器寫數(shù)據(jù)0x20000000,表示要寫入要操作的地址。
- 此波形為nop操作
- 此波形為操作dmi(0x11)寄存器,從而操作command(0x17)寄存器,從而進(jìn)行data0數(shù)據(jù)寫入s0的操作。
- 此波形為操作dmi(0x11)寄存器,發(fā)送讀取abstractcs(0x16)寄存器操作。
- 此波形為nop操作,通過TDO線數(shù)據(jù)獲取狀態(tài)正常。
- 此波形為操作dmi(0x11)寄存器,向data0寄存器寫數(shù)據(jù)0x12345678,表示要寫入0x20000000地址的數(shù)據(jù)。
- 此波形為nop操作
- 此波形為操作dmi(0x11)寄存器,從而操作command(0x17)寄存器,從而進(jìn)行執(zhí)行progbuf寄存器里的指令,data0數(shù)據(jù)寫入s1的操作。
- 此波形為操作dmi(0x11)寄存器,發(fā)送讀取abstractcs(0x16)寄存器操作。
- 此波形為nop操作,通過TDO線數(shù)據(jù)獲取狀態(tài)正常。
上述流程描述了通過Program Buffer方式寫內(nèi)存操作,實際操作中會加入讀取狀態(tài)寄存器等操作,確保操作正常。mww實際操作還會加入保存恢復(fù)s0寄存器,執(zhí)行fence指令等,這里不進(jìn)行過多描述。
此流程為可以連續(xù)操作內(nèi)存的一個步驟,下面將進(jìn)行操作的講解:
- sw s1,0(s0)指令為將s1的值寫入到s0地址。
- addi s0, s0, 4指令為執(zhí)行一次操作后地址增加4字節(jié)。
- 此步驟沒有ebreak指令,能正常運行的原因是debug支持執(zhí)行完progbuf指令自動添加ebreak指令,此設(shè)置可以查看dmstatus(0x11)寄存器impebreak位。
- 連續(xù)操作步驟為編程abstractauto(0x18)寄存器,可以在寫完data0寄存器后自動執(zhí)行progbuf的指令。
連接時循環(huán)查詢狀態(tài)
- 此波形為操作dmi(0x11)寄存器,發(fā)送讀取dmstatus(0x11)寄存器操作。
- 此波形為nop操作,通過TDO線數(shù)據(jù)獲取cpu狀態(tài)為halted狀態(tài)。
審核編輯 黃宇
-
芯片
+關(guān)注
關(guān)注
459文章
51988瀏覽量
434216 -
mcu
+關(guān)注
關(guān)注
146文章
17751瀏覽量
358767 -
RISC-V
+關(guān)注
關(guān)注
46文章
2463瀏覽量
48098
發(fā)布評論請先 登錄
關(guān)于RISC-V芯片的應(yīng)用學(xué)習(xí)總結(jié)
RISC-V MCU技術(shù)
RISC-V架構(gòu)及MRS開發(fā)環(huán)境回顧
淺聊深入淺出RISC-V調(diào)試
RISC-V Summit China 2024 青稞RISC-V+接口PHY,賦能RISC-V高效落地

RISC-V Summit China 2024 | 青稞RISC-V+接口PHY,賦能RISC-V高效落地
走進(jìn)RISC-V:芯片界的新革命

評論