How to store data from a remote target in a variable in order to compare it in GDB?

0

I am scripting a GDB command file in order to control GPIO Registers of my STM32F407 Discovery Board. I am using an OpenOCD server and gdb.

So far i managed to reset BRR register in order to shut down some leds. It works quite well.

My goal is to toggle LD3 (connected to GPIOD PIN15) each time the program breaks. So I found the addresses of the registers and what to write in it. In order to toggle the led i have to write something different in the BSRR register.

I wrote this in 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  

Obviously it can't work because the command monitor mdw phys 0x40020C14 don't contain the result it just print it.

How to store the value of the reading in a variable in order to compare it in the if statement ?

Thanks for helping !

c
gdb
remote-debugging
openocd
asked on Stack Overflow Nov 13, 2020 by Gautier LEGRAND

1 Answer

0

Gdb's if command typically evaluates expressions written in the target's programming language. It can also evaluate expressions that contain character string output from other gdb commands, with the help of the following convenience function written in Python.

First, define a convenience function named $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()

(This is taken from my answer to GDB script flow control for remote target).

You can put this in a file named cmdeval.py and type source cmdeval.py in gdb to load it.

Then, in your scripts, you can use $cmdeval("monitor mdw phys 0x40020C14") to produce the output of the monitor command as a string, store that string in a convenience variable, and use that variable in an expression:

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

(This is untested; I don't have the setup required to run monitor mdw).

answered on Stack Overflow Nov 17, 2020 by Mark Plotnick • edited Nov 20, 2020 by Mark Plotnick

User contributions licensed under CC BY-SA 3.0