-
stm32g0, openocd, and mecrisp stellaris - part 6
01/14/2022 at 02:46 • 0 commentsI 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 commentsSo 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 commentsOne 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.