• stm32g0, openocd, and mecrisp stellaris - part 6

    5 days ago 0 comments

    I apologize for not catching this sooner, but I did not include my process for reading binaries from the chips.   here's a little short post on that.

    The commands are all very similar and I'm using the same two config files as before, openocd-1.cfg and openocd-2.cfg.  The commands for reading your binaries off of multiple chips are as follows.  The blurb at the top is the relevant bit from the openocd manual.

    # Command: flash read_bank num filename [offset [length]]
    # Read length bytes from the flash bank num starting at offset and write 
    # the contents to the binary filename. If offset is omitted, start at 
    # the beginning of the flash bank. If length is omitted, read the 
    # remaining bytes from the flash bank. The num parameter is a 
    # value shown by flash banks.
    
    
    openocd -d0 -f openocd-1.cfg -c 'reset halt' -c 'flash read_bank 0 a5-1.bin 0x08000000' -c 'reset' -c 'exit'
    
    openocd -d0 -f openocd-2.cfg -c 'reset halt' -c 'flash read_bank 0 a5-2.bin 0x08000000' -c 'reset' -c 'exit'

    If I run my little script with those commands in it...

    ./read-binaries 
    Open On-Chip Debugger 0.11.0+dev-00546-g5795f4d3e (2021-12-22-14:13)
    Licensed under GNU GPL v2
    For bug reports, read
    	http://openocd.org/doc/doxygen/bugs.html
    debug_level: 0
    
    target halted due to debug-request, current mode: Thread 
    xPSR: 0xf1000000 pc: 0x00003660 msp: 0x20000330
    wrote 16384 bytes to file a5-1.bin from flash bank 0 at offset 0x00000000 in 0.155701s (102.761 KiB/s)
    
    Open On-Chip Debugger 0.11.0+dev-00546-g5795f4d3e (2021-12-22-14:13)
    Licensed under GNU GPL v2
    For bug reports, read
    	http://openocd.org/doc/doxygen/bugs.html
    debug_level: 0
    
    target halted due to debug-request, current mode: Thread 
    xPSR: 0xf1000000 pc: 0x00003660 msp: 0x20000330
    wrote 16384 bytes to file a5-2.bin from flash bank 0 at offset 0x00000000 in 0.154476s (103.576 KiB/s)
    
    

    You can see that it starts correctly and reads until the end, giving the correct 16384 byte size files.  And here are the files:

    -rw-rw-r-- 1 clapp clapp 16384 Jan 13 18:42 a5-1.bin
    -rw-rw-r-- 1 clapp clapp 16384 Jan 13 18:42 a5-2.bin
    

     Then a quick little reprogram and verify that they run and we now have vetted binary files.

    Cheers!


  • stm32g0, openocd, and mecrisp stellaris - part 5

    11/24/2021 at 00:54 0 comments

    So just a short one today to describe briefly how to change option bytes.  The documentation does not seem to have examples, but I was finally able to stumble my way into getting it working by looking at the methods and steps of a few different articles about changing option bytes for other stm32 chips.

    With the stm32g031, you must use the stm32l4x flash driver.  This may vary for your chip, so research that.  Since I found that out the long way round, I hope it saves you time.  Using my new friend openocd, I wanted to enable the BOR enable bit in the option bytes (change from 0xfffffeaa to 0xffffffaa).  It's a one bit change, how hard could it be?

    Earlier I showed how you can read option bytes. You can verify they are set at the default. This command:

    openocd -d0 -f read-opt-bytes-1 -c "stm32l4x option_read 0 0x20" -c "exit"

    gives this result:

    Option Register: <0x40022020> = 0xfffffeaa

    And this matches the datasheet RM0444 p. 81.  Hooray!

    I've tried every combination of option_write and option_load I can think of based on what others had got to work for them, and I was finally able to toggle one single bit in the option bytes. I had to use these two commands in order:

    openocd -f read-opt-bytes-1 -c "stm32l4x option_write 0 0x20 0xffffffaa 0xffffffaa" -c "reset" -c "exit"

    openocd -f read-opt-bytes-1 -c "stm32l4x option_load 0 0x20" -c "reset" -c "exit"

    Then we have the new values: Option Register: <0x40022020> = 0xffffffaa

    Recall from earlier, that I had made my own read-opt-bytes-1 config file for openocd.  It basically just sets some defaults, but more importantly, let's me specify exactly which st-linkv2 interface I want to use when there are more than one plugged in at one time.  This is done with the hla_serial line in the config file...

    hla_serial "\x55\x3f\x66\x06\x48\x3f\x57\x54\x12\x27\x07\x3f"

    It would be nice if openocd could read this style ID instead: 55FF66064887575412270787, but I'll take what I can get. 

    Cheers!

    ... also, *changing* the BOR bits from default settings (BOR turned off) did help with power ups when the supply voltage ramps up slowly.  If you have something like that, be sure to turn on the BOR EN bit.  :-)

    *update* Thanks to Paul F. on the openocd chat for catching the error in my build environment.  We're now running openocd 0.11 (the latest release).  And also thank you for the config tips!  You do not need the full path in the config files to get to interface and target directories, and the creation of the dap is automatic.  Now, the new shorter format of my config files are something like this:

    source [find interface/stlink.cfg]
    source [find target/stm32g0x.cfg]
    gdb_memory_map enable
    gdb_flash_program enable
    
    adapter serial "\x55\x3f\x66\x06\x48\x3f\x57\x54\x12\x27\x07\x3f"
    gdb_port disabled
    tcl_port disabled
    telnet_port disabled
    
    init

     Cleaner.  Smaller.  Learn something every day!

  • stm32g0, openocd, and mecrisp stellaris - part 4

    11/17/2021 at 00:18 0 comments

    One of the cool things about using openocd is that you can interact with it, say to figure stuff out for the first time.  Then you can program it to be consistent.  For example, reading the option bytes worked out like this.

    1) Make this openocd.cfg:

    source [find /usr/local/share/openocd/scripts/interface/stlink.cfg]
    source [find /usr/local/share/openocd/scripts/target/stm32g0x.cfg]
    gdb_memory_map enable
    gdb_flash_program enable
    init
    reset_config trst_and_srst
    jtag configure stm32g0x.jrc -event setup "jtag tapenable stm32g0x.cpu"
    jtag tapisenabled stm32g0x.cpu
    dap create CPU -chain-position stm32g0x.cpu

    2) Now, fire up openocd.

    et:option-bytes$ openocd
    Open On-Chip Debugger 0.10.0+dev-00937-g8021aef90 (2021-11-03-16:13)
    Licensed under GNU GPL v2
    For bug reports, read
            http://openocd.org/doc/doxygen/bugs.html
    Info : auto-selecting first available session transport "hla_swd". To override use 'transport select '.
    Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD
    Info : clock speed 2000 kHz
    Info : STLINK V2J38S7 (API v2) VID:PID 0483:3748
    Info : Target voltage: 3.278873
    Info : stm32g0x.cpu: hardware has 4 breakpoints, 2 watchpoints
    Info : Listening on port 3333 for gdb connections
    1
    Info : Listening on port 6666 for tcl connections
    Info : Listening on port 4444 for telnet connections

     3) In another window, connect to it via telnet:

    telnet localhost 4444
    Trying 127.0.0.1...
    Connected to localhost.
    Escape character is '^]'.
    Open On-Chip Debugger
    > jtag tapisenabled stm32g0x.cpu
    1
    > stm32l4x option_read 0 0x00
    device id = 0x10016466
    flash size = 16kbytes
    Single Bank 16 kiB STM32G03x/G04x/G07x/G08x found
    Option Register: <0x40022000> = 0x40600
    > exit
    Connection closed by foreign host.
    
    

    I verified that the config worked, and the trap is enabled, just nice to know.  Then I read the option bytes.  Now that I have figured out exactly what was needed to read the option bytes, I don't want to have to fire up openocd and telnet to the instance every time.  That would be great for doing some real time debug work, but I am using forth, which pretty much does that for me already.  So, I want a convenient way to get the option bytes.  I have the command I want the output of, so I just tell openocd to run the command and exit.

    et:option-bytes$ openocd -d0 -f read-opt-bytes-1 -c "stm32l4x option_read 0 0x20" -c "exit"
    Open On-Chip Debugger 0.10.0+dev-00937-g8021aef90 (2021-11-03-16:13)
    Licensed under GNU GPL v2
    For bug reports, read
            http://openocd.org/doc/doxygen/bugs.html
    debug_level: 0
    
    Option Register: <0x40022020> = 0xfffffeaa
    
    et:option-bytes$ openocd -d0 -f read-opt-bytes-2 -c "stm32l4x option_read 0 0x20" -c "exit"
    Open On-Chip Debugger 0.10.0+dev-00937-g8021aef90 (2021-11-03-16:13)
    Licensed under GNU GPL v2
    For bug reports, read
            http://openocd.org/doc/doxygen/bugs.html
    debug_level: 0
    
    Option Register: <0x40022020> = 0xfffffeaa

    So there it is, running the same process interactively, then programming it to be a scripted command that can be run.  I hope you find this information useful.