OpenOCD 探測目標所運行 OS 的原理

OpenOCD 支持 OS 調試,須要在目標配置中加上選項-rtos auto來使能此功能,OpenOCD 文檔中關於 OS 調試的說明以下:html

OpenOCD includes RTOS support, this will however need enabling as it defaults to disabled. It can be enabled by passing -rtos arg to the target. See [RTOS Type], page 63.
See Section 「Debugging Programs with Multiple Threads」 in GDB manual, for details about relevant GDB commands.
An example setup is below:
$_TARGETNAME configure -rtos auto
This will attempt to auto detect the RTOS within your application. Currently supported rtos’s include:
• eCos
• ThreadX
• FreeRTOS • linux
• ChibiOS
• embKernel • mqx
• uCOS-III
Note: Before an RTOS can be detected, it must export certain symbols; other- wise, it cannot be used by OpenOCD.linux

OpenOCD 探測目標所運行 OS 的原理是,它查詢目標所運行的程序中有無 OS 所含有的變量符號,例如 FreeRTOS 有以下符號:app

pxCurrentTCB, pxReadyTasksLists, xDelayedTaskList1, xDelayedTaskList2, pxDelayedTaskList, pxOverowDelayedTaskList, xPendingReadyList, uxCurrentNumberOfTasks, uxTopUsedPriority.tcp

若是這些符號都有,那就說明目標所運行的 OS 是 FreeRTOS。ide

可是 OpenOCD 是在硬件層的調試,它只是根據 gdb 的命令來讀寫內存和寄存器,如何能查詢目標程序內的符號的呢?this

下面是一個 OpenOCD 的啓動日誌,此時 gdb 尚未 attach 上來。debug

Open On-Chip Debugger 0.9.0 (2016-10-26-15:30)
Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
Info : JLink SWD mode enabled
swd
adapter speed: 10000 kHz
adapter_nsrst_delay: 100
adapter_nsrst_delay: 100
none separate
cortex_m reset_config sysresetreq
jtag_init
Info : J-Link V9 compiled Sep 1 2016 18:29:50
Info : J-Link caps 0xb9ff7bbf
Info : J-Link hw version 94000
Info : J-Link hw type J-Link
Info : J-Link max mem block 69920
Info : J-Link configuration
Info : USB-Address: 0x0
Info : Kickstart power on JTAG-pin 19: 0xffffffff
Info : Vref = 3.312 TCK = 0 TDI = 0 TDO = 0 TMS = 1 SRST = 1 TRST = 0
Info : J-Link JTAG Interface ready
Info : clock speed 10000 kHz
Info : SWD IDCODE 0x2ba01477
Info : stm32f4x.cpu: hardware has 6 breakpoints, 4 watchpoints
Info : accepting 'gdb' connection on tcp/3333
target state: halted
target halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0x08000034 msp: 0x2000dd1c調試

能夠看出,此時 OpenOCD 還探測不到目標所運行的 OS。日誌

在 gdb attach 上之後,OpenOCD 日誌以下:code

Info : device id = 0x10006431
Info : flash size = 512kbytes
Info : Auto-detected RTOS: FreeRTOS

能夠看出,在 gdb attach 上之後,OpenOCD 才探測出目標所使用的 OS 是 FreeRTOS。

不難猜想,OpenOCD 應該是查詢 gdb 所加載的 ELF 文件中的符號表來探測 OS 的。

那麼 OpenOCD 如何能查詢到 ELF 文件內的符號表呢?

原來 OpenOCD 能夠向 gdb 發送查詢符號命令 - qSymbol:sym_name,來查詢 ELF 文件內的符號地址。

gdb 文檔中關於此部分的說明以下:

‘qSymbol:sym_name’
The target requests the value of symbol sym name (hex encoded). gdb may provide the value by using the ‘qSymbol:sym_value:sym_name’ message, described below.
‘qSymbol:sym_value:sym_name’
Set the value of sym name to sym value.
sym name (hex encoded) is the name of a symbol whose value the target has previously requested.
sym value (hex) is the value for symbol sym name. If gdb cannot supply a value for sym name, then this eld will be empty.

用 wireshark 抓取 gdb attach 時的 gdb 和 OpenOCD 的通訊包,其中有一段便是查詢符號的部分:

$qSymbol:5f74785f7468726561645f63757272656e745f707472
$qSymbol::5f74785f7468726561645f63757272656e745f707472
$qSymbol:757843757272656e744e756d6265724f665461736b73
$qSymbol:20000b6c:757843757272656e744e756d6265724f665461736b73

OpenOCD 首先發出 qSymbol 命令,數據是 5f74785f7468726561645f63757272656e745f707472,轉化成 ASCII 碼是 _tx_thread_current_ptr,這是 ThreadX 的 symbol,由於咱們的目標運行的是 FreeRTOS,因此 gdb 回覆的 sym_value 是空的,表明沒有這個符號。

而後 OpenOCD 查詢 uxCurrentNumberOfTasks,gdb 回覆中的 sym_value 的值是 20000b6c,即 uxCurrentNumberOfTasks 的地址。

相關文章
相關標籤/搜索