Как проверить связь с чипом (определить, подключен ли чип) с помощью OpenOCD - PullRequest
5 голосов
/ 09 июля 2019

1. Проблема объяснила

Я пытаюсь использовать OpenOCD для чего-то необычного. Вместо подключения к чипу, я хотел бы просто обнаружить чип.
Процедура, которую я имею в виду, будет выглядеть так:

  1. Запустите OpenOCD с файлом конфигурации зонда (например, stlink.cfg), заданным как параметр -f. Таким образом, OpenOCD знает, какой зонд использовать, но не знает, какой чип он найдет.

  2. OpenOCD обнаруживает микросхему и как-то сообщает об этом (например, записывает что-то в стандартный вывод). Если возможно, это действие не должно быть навязчивым для чипа (например, его сброс).

  3. OpenOCD закрывается.

Вот еще несколько примечаний о процедуре:

Примечание 1: Было бы неплохо, если бы OpenOCD не достиг состояния сервера , где мне нужно настроить клиент Telnet или GDB для взаимодействия с ним. Я был бы рад сообщить об обнаружении микросхем в более удобном виде, например, получить информацию о микросхеме на канале вывода.

Примечание 2: Обнаружение должно быть незаметным для чипа. Однако, если OpenOCD ничего не находит, я бы хотел использовать метод резервного копирования, где OpenOCD пытается найти чип более агрессивно (например, удерживая пин nRST). Я могу при необходимости использовать этот другой подход самостоятельно (поэтому OpenOCD не нужно делать это автоматически).

Примечание 3: Сначала я просто применю это «обнаружение микросхем» только к микросхемам STM32 с датчиком STLinkV2 или STLinkV3, а затем и к другим пробникам и чипам.

Примечание 4: Некоторые платы имеют только подключение SWD (без JTAG).

Примечание 5: Я работаю на компьютере под управлением Windows 10 и получил очень свежую сборку OpenOCD (версия 0.10.0_dev00921 , построенная 06 июля 2019 года ) скачано с https://www.playembedded.org/blog/download/


2. Что я пробовал до сих пор

г. Томми Мерфи направил меня к разделу 10.7 справочного руководства по OpenOCD (см. http://openocd.org/doc/pdf/openocd.pdf).. Я прочитал этот раздел и наблюдал следующий пример:

# openocd.cfg file
# -----------------
    source [find interface/olimex-arm-usb-tiny-h.cfg]
    reset_config trst_and_srst
    jtag_rclk 8

Поскольку моя микросхема подключается через STLink и использует протокол SWD transport (вместо JTAG), я сделал несколько модификаций в примере:

# openocd.cfg file
# -----------------
    source [find interface/stlink.cfg]
    transport select hla_swd
    reset_config srst_only
    adapter_khz 480

Я подключаю плату NUCLEO_F303K8 к своему ПК для этого теста. Затем я запускаю следующую команду в моей консоли:

> openocd -s "C:\...\scripts" -f "C:\...\openocd.cfg"

OpenOCD выводит следующее и затем завершается:

Open On-Chip Debugger 0.10.0+dev-00921-gef8c69ff9 (2019-07-06-01:00)
Licensed under GNU GPL v2
For bug reports, read
        http://openocd.org/doc/doxygen/bugs.html
adapter speed: 480 kHz

Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
Info : clock speed 480 kHz
Error: BUG: current_target out of bounds

Поэтому у меня возникает несколько вопросов, касающихся автопробинга.


3. Мои вопросы

Вопрос 1:
Действительно ли мне нужен «Автопробинг» (как описано в разделе 10.7)? Если ответ Нет , игнорируйте следующие вопросы.

Вопрос 2:
Я попытался подражать примеру, приведенному в Разделе 10.7, с некоторыми незначительными изменениями, чтобы сделать пример подходящим для моей платы Nucleo. К сожалению, автопробинг не работает. Это потому, что OpenOCD не поддерживает автопробирование по протоколу SWD? Или я просто делаю ошибку в моем .cfg файле?

Вопрос 3:
Я заметил, что пример Autoprobing из Раздела 10.7 настраивает поведение сброса OpenOCD. Означает ли это, что автопробинг всегда будет «навязчивым» в том смысле, что он сбрасывает чип?

Вопрос 4:
Пример Autoprobing из Раздела 10.7, похоже, переводит OpenOCD в состояние сервера . Можно ли этого избежать? Я хочу упростить эту задачу «обнаружения микросхем» без необходимости использования клиента Telnet или GDB.


редактирует

Спасибо @nattgris за ваш замечательный ответ. У меня есть еще несколько практических вопросов.

1. С ST-Link

Предположим, мы используем ST-Link, несмотря на его неоптимальное сотрудничество с OpenOCD. Вы сказали:

.. если все, что вам нужно, это знать, есть ли вообще чип, в некоторых конфигурациях ST-Link, вероятно, можно убедить предоставить вам эту информацию.

Как мне практически убедить ST-Link сделать это? Другими словами, что я должен поместить в мой файл openocd.cfg, чтобы добиться этого?


2. С SWD-зондом (но не ST-Link)

Предположим, мы используем настоящий SWD-зонд. Вы сказали:

Автопробинг, как описано в разделе 10.7, относится только к JTAG [...]. Простое подключение через SWD распечатывает соответствующую информацию (регистр DPIDR вместо TAP IDCODE). Так или иначе, вы можете получить одинаковую информацию о чипе по обоим протоколам. [...]
Для всех чипов Cortex вы получите «ARM» вместо фактического производителя чипа (например, «ST»). Хотя микросхемы ST (и, возможно, других производителей) имеют отдельный TAP сканирования границы (т.е. только JTAG), который обеспечивает фактический ST IDCODE, который можно использовать для идентификации микросхемы.

Из этого я заключаю, что:

  1. Автоматический зонд, как описано в разделе 10.7, применим только к JTAG, но не к SWD.

  2. Так как автонастройка недоступна для SWD, альтернативный подход состоит в том, чтобы просто подключить к микросхеме, после чего OpenOCD автоматически напечатает регистр DPIDR. Этот регистр DPIDR является, так сказать, SWD-эквивалентом JTAG TAP IDCODE и может в некоторой степени идентифицировать микросхему.
    Но как просто подключить к чипу, если он не знает, какой чип изначально подключен к ПК? Если я не ошибаюсь, OpenOCD всегда нужен определенный файл конфигурации, например stm32f7x.cfg, stm32f4x.cfg, stm32l0.cfg, ... для подключения к чипу.

  3. Очевидно, JTAG IDCODE и SWD-эквивалентный DPIDR регистр предоставляют конструктор чипов, который всегда будет "ARM" для чипов ARM-Cortex. Этого недостаточно для полной идентификации чипа. Однако вы говорите, что ARM-чипы имеют отдельные TAP с граничным сканированием, обеспечивающие дополнительные регистры IDCODE для более полной идентификации. К сожалению, это только JTAG. Это означает, что SWD находится здесь в тупике с точки зрения идентификации чипа?

  4. Автопробинг с JTAG (и, следовательно, чтение IDCODE reg) может быть полностью ненавязчивым. Поэтому можно сделать сигнал сброса системы недоступным:
    reset_config none
    Вы говорите, что чтение DPIDR через SWD (которое я считаю SWD-эквивалентом автопробинга JTAG) также не навязчиво. Могу ли я также применить эту «ненавязчивость», сделав сигнал сброса недоступным?


3. С JTAG-зондом (но не ST-Link)

Протокол JTAG, по-видимому, обеспечивает наилучшую поддержку идентификации чипа (с использованием автопробинга). Мои выводы:

  1. Автопробинг, описанный в разделе 10.7, распечатает TAP IDCODE из чипа. Для ARM-чипов, которые будут просто печатать «ARM», а не фактический производитель (например, «ST») и название чипа (например, «STM32F767ZI»).

  2. Как я могу практически убедиться, что процедура также печатает эту дополнительную информацию, в частности, фактическое название чипа? Другими словами, что я должен поместить в мой openocd.cfg файл (и, возможно, команду запуска openocd), чтобы добиться этого?


Большое спасибо: -)

Ответы [ 2 ]

4 голосов
/ 09 июля 2019

Вопрос 1:

Это то, что вам нужно?Зависит.Автопробинг, как описано в разделе 10.7, относится только к JTAG.Так что само по себе это не покроет ваши потребности.Но простое подключение через SWD печатает соответствующую информацию (регистр DPIDR вместо TAP IDCODE), так что в любом случае вы можете получить одинаковую информацию о чипе по обоим протоколам.

Однако я не уверен, что этодостаточно для вас.Если вы только хотите обнаружить, что чип (любой чип) реагирует, этого, вероятно, достаточно.Если вам также необходимо детально идентифицировать микросхему, в общем случае потребуется дополнительная проверка, поскольку идентификаторы, которые вы получаете с помощью обоих методов, идентифицируют разработчика микросхемы.Таким образом, для всех чипов Cortex вы получите «ARM» вместо фактического производителя чипа (например, «ST»).Хотя ST (и, возможно, другие производители) чипы имеют отдельную TAP сканирования границы (т.е. только JTAG), которая обеспечивает фактический ST IDCODE, который может использоваться для идентификации чипа.

Однако, поскольку SWD относится только к ARM Cortexтипа (или, скорее, ADI v5), если вы можете использовать SWD, вы также можете прочитать таблицу ПЗУ компонентов отладки, в которой, помимо прочего, указывается производитель чипа:

# Your JTAG adapter config
script interface.cfg

transport select swd
adapter_khz 100

swd newdap chip cpu -enable
dap create chip.dap -chain-position chip.cpu
target create chip.cpu cortex_m -dap chip.dap

init
dap info
shutdown

Вывод дляSTM32F103:

Info : SWD DPIDR 0x1ba01477
Info : chip.cpu: hardware has 6 breakpoints, 4 watchpoints
Info : gdb port disabled
AP ID register 0x14770011
    Type is MEM-AP AHB
MEM-AP BASE 0xe00ff003
    Valid ROM table present
        Component base address 0xe00ff000
        Peripheral ID 0x00000a0410
        Designer is 0x0a0, STMicroelectronics
        Part is 0x410, Unrecognized 
        Component class is 0x1, ROM table
        MEMTYPE system memory present on bus
    ROMTABLE[0x0] = 0xfff0f003
        Component base address 0xe000e000
        Peripheral ID 0x04001bb000
        Designer is 0x4bb, ARM Ltd.
        Part is 0x0, Cortex-M3 SCS (System Control Space)
        Component class is 0xe, Generic IP component
    ROMTABLE[0x4] = 0xfff02003
        Component base address 0xe0001000
        Peripheral ID 0x04001bb002
        Designer is 0x4bb, ARM Ltd.
        Part is 0x2, Cortex-M3 DWT (Data Watchpoint and Trace)
        Component class is 0xe, Generic IP component
    ROMTABLE[0x8] = 0xfff03003
        Component base address 0xe0002000
        Peripheral ID 0x04000bb003
        Designer is 0x4bb, ARM Ltd.
        Part is 0x3, Cortex-M3 FPB (Flash Patch and Breakpoint)
        Component class is 0xe, Generic IP component
    ROMTABLE[0xc] = 0xfff01003
        Component base address 0xe0000000
        Peripheral ID 0x04001bb001
        Designer is 0x4bb, ARM Ltd.
        Part is 0x1, Cortex-M3 ITM (Instrumentation Trace Module)
        Component class is 0xe, Generic IP component
    ROMTABLE[0x10] = 0xfff41003
        Component base address 0xe0040000
        Peripheral ID 0x04001bb923
        Designer is 0x4bb, ARM Ltd.
        Part is 0x923, Cortex-M3 TPIU (Trace Port Interface Unit)
        Component class is 0x9, CoreSight component
        Type is 0x11, Trace Sink, Port
    ROMTABLE[0x14] = 0xfff42002
        Component not present
    ROMTABLE[0x18] = 0x0
        End of ROM table

Для чипов, не относящихся к Cortex, вы получите хорошую идентификацию, используя JTAG TAP IDCODE, используя только автоматическое тестирование, как в этом примере со старым STR750:

# Your JTAG adapter config
script interface.cfg

transport select jtag
adapter_khz 100

init
shutdown
Info : JTAG tap: auto0.tap tap/device found: 0x4f1f0041 (mfg: 0x020 (STMicroelectronics), part: 0xf1f0, ver: 0x4)

Вопрос 2:

Как описано выше, «autoprobing» относится только к JTAG, но вы получаете те же функциональные возможности (чтение идентификационного кода), что и SWD.К сожалению, это не поможет вам, потому что у вас нет доступа ни к одному протоколу!

Проблема в том, что вы используете ST-Link.Несмотря на то, что люди склонны думать, это НЕ настоящий адаптер JTAG / SWD.Да, он говорит как на JTAG, так и на SWD, но полностью скрывает протокол внутри прошивки адаптера.Он предоставляет только высокоуровневую команду, установленную для хоста (OpenOCD), типа «Сброс цели», «Шаг цели», «Чтение этой памяти» и т. Д. Как следствие, поддержка OpenOCD ST-Linkэто уродливый хак, который находится на слое target вместо слоя adapter .Таким образом, большинство функций OpenOCD на уровне адаптера, транспорта или DAP просто не существует, и автоматическое зондирование в смысле OpenOCD совершенно не имеет значения для вашей установки.

Для простой перепрошивки и очень простой отладки GDB, ST-Linkработает.Но для чего-то более низкого уровня, просто держитесь подальше от ST-Link.Это совсем не подходит для OpenOCD.

Тем не менее, если все, что вам нужно, это знать, есть ли чип вообще, в некоторых конфигурациях ST-Link, вероятно, можно убедить, чтобы дать вамinfo, например, со следующим файлом конфигурации:

script interface/stlink.cfg

transport select hla_swd
adapter_khz 100

hla newtap chip cpu -enable
dap create chip.dap -chain-position chip.cpu
target create chip.cpu cortex_m -dap chip.dap

Вы получите либо

Warn : UNEXPECTED idcode: 0x2ba01477

, либо

Error: init mode failed (unable to connect to the target)

Остальные вопросы не имеют значения вместес ST-Link, поэтому я буду считать, что вы переключаетесь на настоящий адаптер JTAG / SWD.

Вопрос 3:

JTAG с автопробингом, а также чтениеDPIDR over SWD, абсолютно не навязчивый.В целом, для целей Cortex-M большинство отладочных обращений к цели не являются навязчивыми, поэтому вы можете читать / записывать память и т. Д., Пока цель работает с трудом, не затрагивая ее.

JTAG не определяет или не требуетсигнал сброса системы должен быть доступен вообще.Автопробинг работает без него, вы должны иметь возможность использовать

reset_config none

Вопрос 4:

Вы хотите вообще не запускать сервер gdb / telnet??Затем вы можете отключить их с помощью следующей конфигурации:

gdb_port disabled
telnet_port disabled
tcl_port disabled

Однако, если вы просто запустите OpenOCD, чтобы обнаружить чип, а затем закроете его, временный запуск этих служб в любом случае может не быть проблемой.

Более того, по крайней мере сервер GDB запускается только после создания target , который не является обязательным для выполнения автозондирования JTAG.

Summary

Да, вы должны иметь возможность делать то, что вы хотите, но, возможно, не с ST-Link.С реальным адаптером вы можете выполнить автоматическое зондирование JTAG для печати обнаруженных TAP в цепочке сканирования.Для SWD OpenOCD всегда печатает обнаруженный регистр DPIDR (и обычно прерывается, если цель не найдена; выходные данные будут отличаться, по крайней мере).

Соединение / обнаружение может быть полностью незаметным, если сама цель поддерживает егокак и большинство Cortex-M.Если в целевой микропрограмме отключены контакты отладки или отключена логика отладки, может потребоваться удержание или импульсный сброс в зависимости от цели.

1 голос
/ 11 июля 2019

С помощью основного кода OpenOCD вы можете легко получить доступ к памяти цели. Вы можете прочитать некоторые идентификационные данные с цели, декодировать их и обнаружить чип.

Кстати, это, вероятно, не будет работать с высокоуровневыми адаптерами, такими как STLink. Пожалуйста, используйте общие адаптеры (J-Link, адаптеры на основе FTDI, CMSIS-DAP и т. Д.).

source [find interface/jlink.cfg]
transport select swd
adapter_khz 1000

set _CHIPNAME generic_dap_access

# 1. DECLARE A DAP
# -----------------
# Declare a single DAP (a DAP is the SWD counterpart for a JTAG TAP)
# for the chip's cpu. The command `swd newdap` has the same parameters
# as `jtag newtap`.
# param one:      Name of the module in the JTAG scan chain (usually a chip).
# param two:      Tapname, reflects the role of the TAP (bs, cpu, flash, ...).
# -irlen 4:       Instruction register length is 4 bits
# -ircapture 0x1: The bit pattern loaded by the TAP into the JTAG shift register on entry
#                 to the ircapture state. Default is 0x01.
# -irmask 0xf:    A mask used with-ircaptureto verify that instruction scans work correctly.
swd newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf

# 2. CREATE (?) A DAP AND LINK TO JTAG TAP
# -----------------------------------------
# Since OpenOCD version 0.11.0, the Debug Access Port (DAP) is no longer implicitely
# created together with the target. It must be explicitely declared.
# Declare a DAP instance named $_CHIPNAME.dap linked to the JTAG tap $_CHIPNAME.cpu.
dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu
# Note: Observe important note in manual
#       for ARMv6-M, ARMv7 and ARMv8 targets.


# 3. DECLARE SOME PROCEDURES
# ---------------------------
# 3.1 Writes 'val' to address 'addr' via AP 'ap'
proc mww_ll { ap addr val } {
    global _CHIPNAME
    # I'm a bit confused how the following commands achieve just that.
    $_CHIPNAME.dap apreg $ap 0x04 $addr
    $_CHIPNAME.dap apreg $ap 0x0C $val
}

# 3.2 Reads and displays data from address 'addr' via AP 'ap'
proc mdw_ll { ap addr } {
    global _CHIPNAME
    $_CHIPNAME.dap apreg $ap 0x04 $addr
    $_CHIPNAME.dap apreg $ap 0x0C
}

# 3.3 Reads data from address 'addr' via AP 'ap' and returns it
# Can be used to read data and pass it to other commands
proc mrw_ll { ap addr } {
    global _CHIPNAME
    $_CHIPNAME.dap apreg $ap 0x04 $addr
    set ap [ocd_$_CHIPNAME.dap apreg $ap 0x0C]
    regsub -all {(\s*\n)+} $ap "" ap
    return $ap
}

# 4. INITIALIZE
# --------------
init     # <- What does this actually do? I'm used to see `reset-init`
         #    everywhere in OpenOCD, but I don't know what simple `init` does.

# 5. READ VALUE AT 0x10000000
# ----------------------------
# Reads and displays value at 0x10000000 <- Why? What's special about
mdw_ll 0 0x10000000 #                            this memory location?

# 6. MODIFY RAM DATA
# -------------------
# Modify some data in RAM <- Why?
mdw_ll 0 0x08000000
mww_ll 0 0x08000000 0xdeadbeef
mdw_ll 0 0x08000000
exit

Вывод OpenOCD:

Open On-Chip Debugger 0.10.0+dev-01116-gfc2e5110d-dirty (2019-07-11-16:04)
Licensed under GNU GPL v2
For bug reports, read
    http://openocd.org/doc/doxygen/bugs.html
adapter speed: 1000 kHz
Info : J-Link Ultra V4 compiled May 27 2019 15:49:24
Info : Hardware version: 4.00
Info : VTarget = 4.850 V
Info : clock speed 1000 kHz
Info : SWD DPIDR 0x6ba02477
Warn : gdb services need one or more targets defined
0x976562e5
0x20004602
0xdeadbeef
...