01、WHY

為什麼要使用到J-LinkCommander呢???大部分情況下,我們使用J-link都是在IDE中debug使用的,出現問題,直接debug復現然後解決。這是最常見的開發方式。

但是有些情況我們不能使用IDE直接debug,比如釋出版本(JTAG或SWD介面可以正常使用),大批量生產時發現幾片異常的板子,重新debug問題就消失了。

這個時候使用IDE直接debug已經不能解決問題,我們需要使用J-LinkCommander讀取關鍵暫存器的值來協助我們定位排查問題。

02、Jlinkcmd使用

Jlinkcmd它可以方便使用者在非模擬的情況下,hold核心、單步、全速、設定斷點、檢視核心和外設暫存器、讀取flash程式碼等等,方便大家擁有最高的許可權檢視在執行中的MCU情況,查詢非IDE模擬情況下,MCU執行異常的原因。

開啟Jlinkcmd,如果單獨安裝了jlink驅動,我們可以在開始選單找到Jlinkcmd。

或者在安裝目錄中找到它

如果你們有獨立安裝Jlink驅動,同樣也可以在Keil的安裝目錄中找到它

首先使用Jlink連線好MCU,開啟軟體“Jlink.exe

按照提示輸入相應資訊connect->?->s->回車(舊版只需要輸入usb即可連線目標晶片

正確的連結目標晶片後:

如上圖所示,選項位元組裡為"5AA5"即為無保護狀態。

Jlinkcommand常用命令簡介:

mem 讀記憶體

mem8 讀8位元組記憶體

mem16 讀16位元組記憶體

mem32 讀32位元組記憶體

w1 寫8位元組記憶體

w2 寫16位元組記憶體

w4 寫32位元組記憶體

h 停止cpu執行的程式

setbp 設定斷點

g 跳到程式碼段地址執行

s 單步執行(除錯用)

r 復位

03、實測

接下來就是實測環節,我們通過一個真實的例子演示一下Jlinkcmd的使用。在之前文章《STM32延時函式的四種方法》中有以下程式碼​

void delay_ms(uint16_t nms)
{
uint32_t temp;
SysTick->LOAD = RCC_Clocks.HCLK_Frequency/1000/8*nms;
SysTick->VAL=0X00;//清空計數器
SysTick->CTRL=0X01;//使能,減到零是無動作,採用外部時鐘源
do
{
temp=SysTick->CTRL;//讀取當前倒計數值
}while((temp&0x01)&&(!(temp&(1<<16))));//等待時間到達
SysTick->CTRL=0x00; //關閉計數器
SysTick->VAL =0X00; //清空計數器
}

呼叫示例

  while (1)
{
GPIO_SetBits(GPIOE,GPIO_Pin_4); //熄滅LED燈
delay_ms(500);//延時500ms
GPIO_ResetBits(GPIOE,GPIO_Pin_4);//點亮LED燈
delay_ms(500);//延時500ms
}

​可以按照晶片使用者手冊直接推算地址。或者如下面這樣,寫段測試程式碼。

從上圖得知,SysTick->LOAD暫存器的地址是0XE000E014,寫入暫存器的值是0X007270E0。

按照上述方案讀取暫存器的值,步驟如下:

可以看到地址0XE000E014的SysTick->LOAD暫存器的值為0X7270E0。

04、後記

這裡只是提供了一個簡單的演示,可以非IDE模擬情況下,讀取暫存器,協助排查MCU執行異常的原因,畢竟如果直接debug就能查到問題,熟悉32系列微控制器的畢業生都可以做到。

我們需要在工作中積累這樣類似的經驗,巧妙使用工具處理一些“詭異”的問題,積累開發經驗。

畢竟,填坑力就是核心競爭力。

點選檢視本文所在的專輯,STM32F207教程