Как сохранить данные от удаленной цели в переменной, чтобы сравнить их в GDB?

Я пишу командный файл GDB для управления регистрами GPIO моей платы обнаружения STM32F407. Я использую сервер OpenOCD и gdb.

Пока мне удалось сбросить регистр BRR, чтобы отключить некоторые светодиоды. Это работает очень хорошо.

Моя цель - переключать LD3 (подключенный к GPIOD PIN15) каждый раз, когда программа ломается. Вот я и нашел адреса регистров и что в них писать. Чтобы переключить светодиод, я должен написать что-то другое в регистре BSRR.

Я написал это в gdb:

commands 1

    # display GPIOD_BSRR write only reg (expected 0x00000000 )
    monitor mdw phys 0x40020C18 
    
    # display GPIOD_ODR reg  (expected 0x0000F000 when LED 12,13,14,15 are ON)
    monitor mdw phys 0x40020C14 
    
    #Toggle LD3 ( GPIO_PIN_13) using GPIOD_BSRR reg

    if monitor mdw phys 0x40020C14 == 0x0000F000 or 0x 00007000
        monitor mww phys 0x40020C18 0x20000000
    else
        monitor mww phys 0x40020C18 0x00002000
    end
end  

Очевидно, что это не может работать, потому что команда monitor mdw phys 0x40020C14 не содержит результата, она просто печатает его.

Как сохранить значение чтения в переменной, чтобы сравнить его в операторе if?

Спасибо за помощь !


person Gautier LEGRAND    schedule 13.11.2020    source источник
comment
Что выводит monitor mdw phys 0x40020C14? Что-то вроде 0x40020C14: 0000F000 ?   -  person Mark Plotnick    schedule 14.11.2020
comment
0x40020C14: 0000F000 Точно. Я не знаю, каков тип этого вывода и можно ли разделить его для сравнения.   -  person Gautier LEGRAND    schedule 17.11.2020


Ответы (1)


Команда Gdb if обычно оценивает выражения, написанные на целевом языке программирования. Он также может оценивать выражения, содержащие строку символов, выводимые другими командами gdb, с помощью следующих удобная функция, написанная на Python.

Во-первых, определите вспомогательную функцию с именем $cmdeval:

import gdb

class CmdEval(gdb.Function):
    """$cmdeval(str) - evaluate argument string as a gdb command
    and return the result as a string. Trailing newlines are removed.
    """

    def __init__(self):
        super(CmdEval, self).__init__("cmdeval")

    def invoke(self, gdbcmd):
        return gdb.execute(gdbcmd.string(), from_tty=False, to_string=True).rstrip('\n')

CmdEval()

(Это взято из моего ответа на управление потоком сценариев GDB для удаленной цели).

Вы можете поместить это в файл с именем cmdeval.py и ввести source cmdeval.py в gdb, чтобы загрузить его.

Затем в своих сценариях вы можете использовать $cmdeval("monitor mdw phys 0x40020C14") для создания вывода команды monitor в виде строки, сохранить эту строку в удобной переменной и использовать эту переменную в выражении:

set $odr = $cmdeval("monitor mdw phys 0x40020C14")
if $_streq($odr, "0x40020C14: 0000F000") || $_streq($odr, "0x40020C14: 00007000")
    monitor mww phys 0x40020C18 0x20000000
else
    monitor mww phys 0x40020C18 0x00002000
end

(Это не проверено; у меня нет настроек, необходимых для запуска monitor mdw).

person Mark Plotnick    schedule 17.11.2020
comment
Большое спасибо! Я попробую и дам вам обратную связь - person Gautier LEGRAND; 20.11.2020
comment
Привет ! Итак, я попробовал предоставленное вами решение, и, по-видимому, monitor не работает в сценарии Python... Вот что он возвращает: `Исключение Python ‹class 'gdb.error'› команда монитора не поддерживается этой целью .: debug_cmd:8 : Ошибка в исходном командном файле: Произошла ошибка в Python: команда монитора не поддерживается этой целью. (ГДБ) ` - person Gautier LEGRAND; 08.01.2021
comment
Возможно, я могу использовать команду gdb для установки этих регистров, потому что monitor используется для вызова команды openOCD mww - person Gautier LEGRAND; 08.01.2021
comment
@GautierLEGRAND Возможно ли, что этот скрипт был запущен до запуска команды target? Если вы поместите команду monitor mdw phys 0x40020C14 в сценарий непосредственно перед командой set $odr и снова запустите сценарий, вы также получите ошибку в этой строке? - person Mark Plotnick; 08.01.2021