Skip to content
This repository has been archived by the owner on Aug 27, 2021. It is now read-only.

GD32F103C8 RTT initialization fails due to failing read of channel name from flash memory #30

Open
G33KatWork opened this issue Jul 15, 2021 · 0 comments
Labels
bug Something isn't working

Comments

@G33KatWork
Copy link

G33KatWork commented Jul 15, 2021

Describe the bug
I have a small blinky program running on a GD32F103C8 microcontroller which uses defmt over RTT to print debug messages. I am using the STM32F1xx HAL because the controllers are somewhat compatible and there is no specific crate for the Gigadevices chip.

I am using probe-run to flash the binary and use it to print the log messages over RTT. When I try it on an STM32, it works as expected. The GD32 on the other hand gets flashed successfully and then the RTT initialization fails. The program runs fine.

I tried a J-Link and an ST-Link v2 and both fail in a similar way:

J-Link:

Error: Error communicating with probe: A core architecture specific error occured

Caused by:
    0: A core architecture specific error occured
    1: Failed to read register DRW at address 0x0000000c
    2: An error specific to the selected architecture occured
    3: Target device did not respond to request.

ST-Link v2:

Error: Error communicating with probe: An error with the usage of the probe occured

Caused by:
    0: An error with the usage of the probe occured
    1: An error specific to a probe type occured
    2: Command failed with status SwdDpWait

I started debugging this and this is the tracing output of rtthost using a J-Link before it fails:

DEBUG probe_rs::architecture::arm::ap                              > Writing register CSW, value=CSW { DbgSwEnable: 0, HNONSEC: 1, PROT: 2, CACHE: 3, SPIDEN: 0, _RES0: 0, MTE: 0, Type: 0, Mode: 0, TrinProg: 0, DeviceEn: 0, AddrInc: Single, _RES1: 0, SIZE: U32 }
 TRACE probe_rs::probe::jlink::swd                                  > Adding 2 idle cycles after transfer!
 DEBUG probe_rs::probe::jlink::swd                                  > Performing 2 transfers (1 additional transfers)
 TRACE jaylink                                                      > write 34 bytes: [cf, 0, 72, 0, ff, 83, ff, ff, ff, ff, ff, ff, f, 0, 0, 0, 0, fc, 3, 8c, 2, 9, 0, 80, 31, 0, d0, b, 0, 0, 0, 0, 0, 0]
 TRACE jaylink                                                      > read 16 bytes: [ff, 4, ff, ff, ff, ff, ff, ff, 20, ff, ff, ff, ff, 3, 0, 0]
 DEBUG probe_rs::probe::jlink::swd                                  > Transfer result 0: Ok(0)
 DEBUG probe_rs::probe::jlink::swd                                  > Transfer result 1: Err(WaitResponse)
 DEBUG probe_rs::probe::jlink::swd                                  > DAP WAIT, (write), retries remaining 1000.
 TRACE probe_rs::probe::jlink::swd                                  > Adding 2 idle cycles after transfer!
 DEBUG probe_rs::probe::jlink::swd                                  > Performing 1 transfers (0 additional transfers)
 TRACE jaylink                                                      > write 20 bytes: [cf, 0, 3a, 0, ff, 83, ff, ff, ff, ff, ff, 3, 4, 2, 8, 0, 0, 80, 0, 0]
 TRACE jaylink                                                      > read 9 bytes: [ff, 4, ff, ff, ff, ff, ff, 0, 0]
 DEBUG probe_rs::probe::jlink::swd                                  > Transfer result 0: Ok(0)
 DEBUG probe_rs::probe::jlink::swd                                  > Cleared sticky overrun bit
 TRACE probe_rs::probe::jlink::swd                                  > Adding 4 idle cycles after transfer!
 DEBUG probe_rs::probe::jlink::swd                                  > Performing 2 transfers (1 additional transfers)
 TRACE jaylink                                                      > write 34 bytes: [cf, 0, 74, 0, ff, 83, ff, ff, ff, ff, ff, ff, 3f, 0, 0, 0, 0, f0, f, 8c, 2, 9, 0, 80, 31, 0, 40, 2f, 0, 0, 0, 0, 0, 0]
 TRACE jaylink                                                      > read 16 bytes: [ff, 70, ff, ff, ff, ff, ff, ff, 0, ff, ff, ff, ff, f, 0, 0]
 DEBUG probe_rs::probe::jlink::swd                                  > Transfer result 0: Err(FaultResponse)
 DEBUG probe_rs::probe::jlink::swd                                  > Transfer result 1: Err(FaultResponse)
 DEBUG probe_rs::probe::jlink::swd                                  > DAP FAULT
 DEBUG probe_rs::probe::jlink::swd                                  > Performing 1 transfers (0 additional transfers)
 TRACE jaylink                                                      > write 18 bytes: [cf, 0, 38, 0, ff, 3, 0, 0, 0, 0, ff, 34, 2, 0, 0, 0, 0, 0]
 TRACE jaylink                                                      > read 8 bytes: [ff, 64, 10, 0, 0, fe, ff, 0]
 TRACE probe_rs::probe::jlink::swd                                  > DAP read 4026531971.
 DEBUG probe_rs::probe::jlink::swd                                  > Transfer result 0: Ok(f0000083)
 TRACE probe_rs::probe::jlink::swd                                  > Writing DAP register failed. Ctrl/Stat register value is: Ctrl {
    .0: 4026531971,
    csyspwrupack: true,
    csyspwrupreq: true,
    cdbgpwrupack: true,
    cdbgpwrupreq: true,
    cdbgrstack: false,
    c_dbg_rst_req: false,
    trn_cnt: 0,
    mask_lane: 0,
    w_data_err: true,
    read_ok: false,
    sticky_err: false,
    stick_cmp: false,
    trn_mode: 0,
    sticky_orun: true,
    orun_detect: true,
}
 TRACE probe_rs::probe::jlink::swd                                  > Adding 2 idle cycles after transfer!
 DEBUG probe_rs::probe::jlink::swd                                  > Performing 1 transfers (0 additional transfers)
 TRACE jaylink                                                      > write 20 bytes: [cf, 0, 3a, 0, ff, 83, ff, ff, ff, ff, ff, 3, 4, 2, 8, 0, 0, 80, 0, 0]
 TRACE jaylink                                                      > read 9 bytes: [ff, 4, ff, ff, ff, ff, ff, 0, 0]
 DEBUG probe_rs::probe::jlink::swd                                  > Transfer result 0: Ok(0)
 DEBUG probe_rs::architecture::arm::ap                              > Writing register CSW, value=CSW { DbgSwEnable: 0, HNONSEC: 1, PROT: 2, CACHE: 3, SPIDEN: 0, _RES0: 0, MTE: 0, Type: 0, Mode: 0, TrinProg: 0, DeviceEn: 0, AddrInc: Single, _RES1: 0, SIZE: U32 }
 TRACE probe_rs::probe::jlink::swd                                  > Adding 2 idle cycles after transfer!
 DEBUG probe_rs::probe::jlink::swd                                  > Performing 2 transfers (1 additional transfers)
 TRACE jaylink                                                      > write 34 bytes: [cf, 0, 72, 0, ff, 83, ff, ff, ff, ff, ff, ff, f, 0, 0, 0, 0, fc, 3, 8c, 2, 9, 0, 80, 31, 0, d0, b, 0, 0, 0, 0, 0, 0]
 TRACE jaylink                                                      > read 16 bytes: [ff, 70, ff, ff, ff, ff, ff, ff, c0, ff, ff, ff, ff, 3, 0, 0]
 DEBUG probe_rs::probe::jlink::swd                                  > Transfer result 0: Err(FaultResponse)
 DEBUG probe_rs::probe::jlink::swd                                  > Transfer result 1: Err(FaultResponse)
 DEBUG probe_rs::probe::jlink::swd                                  > DAP FAULT
 DEBUG probe_rs::probe::jlink::swd                                  > Performing 1 transfers (0 additional transfers)
 TRACE jaylink                                                      > write 18 bytes: [cf, 0, 38, 0, ff, 3, 0, 0, 0, 0, ff, 34, 2, 0, 0, 0, 0, 0]
 TRACE jaylink                                                      > read 8 bytes: [ff, 64, 10, 0, 0, fe, ff, 0]
 TRACE probe_rs::probe::jlink::swd                                  > DAP read 4026531971.
 DEBUG probe_rs::probe::jlink::swd                                  > Transfer result 0: Ok(f0000083)
 TRACE probe_rs::probe::jlink::swd                                  > Writing DAP register failed. Ctrl/Stat register value is: Ctrl {
    .0: 4026531971,
    csyspwrupack: true,
    csyspwrupreq: true,
    cdbgpwrupack: true,
    cdbgpwrupreq: true,
    cdbgrstack: false,
    c_dbg_rst_req: false,
    trn_cnt: 0,
    mask_lane: 0,
    w_data_err: true,
    read_ok: false,
    sticky_err: false,
    stick_cmp: false,
    trn_mode: 0,
    sticky_orun: true,
    orun_detect: true,
}
 TRACE probe_rs::probe::jlink::swd                                  > Adding 2 idle cycles after transfer!
 DEBUG probe_rs::probe::jlink::swd                                  > Performing 1 transfers (0 additional transfers)
 TRACE jaylink                                                      > write 20 bytes: [cf, 0, 3a, 0, ff, 83, ff, ff, ff, ff, ff, 3, 4, 2, 8, 0, 0, 80, 0, 0]
 TRACE jaylink                                                      > read 9 bytes: [ff, 4, ff, ff, ff, ff, ff, 0, 0]
 DEBUG probe_rs::probe::jlink::swd                                  > Transfer result 0: Ok(0)
 WARN  probe_rs::session                                            > Could not clear all hardware breakpoints: ArchitectureSpecific(RegisterWriteError { address: 0, name: "CSW", source: ArchitectureSpecific(FaultResponse) })
Error attaching to RTT: Error communicating with probe: A core architecture specific error occured

When I try it with an ST-Link, the trace becomes a bit more readable, but it is also operating on a much higher level when communicating with the debug subsystem:

 TRACE probe_rs::probe::stlink                              > read_mem_8bit
 DEBUG probe_rs::probe::stlink                              > Read mem 8 bit, address=0800168c, length=64
 TRACE probe_rs::probe::stlink::usb_interface               > Sending command [f2, c, 8c, 16, 0, 8, 40, 0, 0] to STLink, timeout: 1s
 TRACE probe_rs::probe::stlink::usb_interface               > Read 64 bytes, 0 bytes remaining
 TRACE probe_rs::probe::stlink::usb_interface               > Sending command [f2, 3e] to STLink, timeout: 1s
 TRACE probe_rs::probe::stlink::usb_interface               > Read 12 bytes, 0 bytes remaining
 WARN  probe_rs::probe::stlink                              > send_jtag_command 242 got SwdDpWait, retrying
 TRACE probe_rs::probe::stlink::usb_interface               > Sending command [f2, 3e] to STLink, timeout: 1s
 TRACE probe_rs::probe::stlink::usb_interface               > Read 12 bytes, 0 bytes remaining
 WARN  probe_rs::probe::stlink                              > send_jtag_command 242 got SwdDpWait, retrying
 TRACE probe_rs::probe::stlink::usb_interface               > Sending command [f2, 3e] to STLink, timeout: 1s
 TRACE probe_rs::probe::stlink::usb_interface               > Read 12 bytes, 0 bytes remaining
 WARN  probe_rs::probe::stlink                              > send_jtag_command 242 got SwdDpWait, retrying
 TRACE probe_rs::probe::stlink::usb_interface               > Sending command [f2, 3e] to STLink, timeout: 1s
 TRACE probe_rs::probe::stlink::usb_interface               > Read 12 bytes, 0 bytes remaining
 WARN  probe_rs::probe::stlink                              > send_jtag_command 242 got SwdDpWait, retrying
 TRACE probe_rs::probe::stlink::usb_interface               > Sending command [f2, 3e] to STLink, timeout: 1s
 TRACE probe_rs::probe::stlink::usb_interface               > Read 12 bytes, 0 bytes remaining
 WARN  probe_rs::probe::stlink                              > send_jtag_command 242 got SwdDpWait, retrying
 TRACE probe_rs::probe::stlink::usb_interface               > Sending command [f2, 3e] to STLink, timeout: 1s
 TRACE probe_rs::probe::stlink::usb_interface               > Read 12 bytes, 0 bytes remaining
 WARN  probe_rs::probe::stlink                              > send_jtag_command 242 got SwdDpWait, retrying
 TRACE probe_rs::probe::stlink::usb_interface               > Sending command [f2, 3e] to STLink, timeout: 1s
 TRACE probe_rs::probe::stlink::usb_interface               > Read 12 bytes, 0 bytes remaining
 WARN  probe_rs::probe::stlink                              > send_jtag_command 242 got SwdDpWait, retrying
 TRACE probe_rs::probe::stlink::usb_interface               > Sending command [f2, 3e] to STLink, timeout: 1s
 TRACE probe_rs::probe::stlink::usb_interface               > Read 12 bytes, 0 bytes remaining
 WARN  probe_rs::probe::stlink                              > send_jtag_command 242 got SwdDpWait, retrying
 TRACE probe_rs::probe::stlink::usb_interface               > Sending command [f2, 3e] to STLink, timeout: 1s
 TRACE probe_rs::probe::stlink::usb_interface               > Read 12 bytes, 0 bytes remaining
 WARN  probe_rs::probe::stlink                              > send_jtag_command 242 got SwdDpWait, retrying
 TRACE probe_rs::probe::stlink::usb_interface               > Sending command [f2, 3e] to STLink, timeout: 1s
 TRACE probe_rs::probe::stlink::usb_interface               > Read 12 bytes, 0 bytes remaining
 WARN  probe_rs::probe::stlink                              > send_jtag_command 242 got SwdDpWait, retrying
 TRACE probe_rs::probe::stlink::usb_interface               > Sending command [f2, 3e] to STLink, timeout: 1s
 TRACE probe_rs::probe::stlink::usb_interface               > Read 12 bytes, 0 bytes remaining
 WARN  probe_rs::probe::stlink                              > send_jtag_command 242 got SwdDpWait, retrying
 TRACE probe_rs::probe::stlink::usb_interface               > Sending command [f2, 3e] to STLink, timeout: 1s
 TRACE probe_rs::probe::stlink::usb_interface               > Read 12 bytes, 0 bytes remaining
 WARN  probe_rs::probe::stlink                              > send_jtag_command 242 got SwdDpWait, retrying
 TRACE probe_rs::probe::stlink::usb_interface               > Sending command [f2, 3e] to STLink, timeout: 1s
 TRACE probe_rs::probe::stlink::usb_interface               > Read 12 bytes, 0 bytes remaining
 WARN  probe_rs::probe::stlink                              > send_jtag_command 242 got SwdDpWait, retrying
 WARN  probe_rs::probe::stlink                              > too many retries, giving up
 DEBUG probe_rs::probe::stlink                              > Read mem 32 bit, address=e0002000, length=4
 TRACE probe_rs::probe::stlink::usb_interface               > Sending command [f2, 7, 0, 20, 0, e0, 4, 0, 0] to STLink, timeout: 1s
 TRACE probe_rs::probe::stlink::usb_interface               > Read 4 bytes, 0 bytes remaining
 TRACE probe_rs::probe::stlink::usb_interface               > Sending command [f2, 3e] to STLink, timeout: 1s
 TRACE probe_rs::probe::stlink::usb_interface               > Read 12 bytes, 0 bytes remaining
 DEBUG probe_rs::probe::stlink                              > Read mem 32 bit, address=e0002000, length=4
 TRACE probe_rs::probe::stlink::usb_interface               > Sending command [f2, 7, 0, 20, 0, e0, 4, 0, 0] to STLink, timeout: 1s
 TRACE probe_rs::probe::stlink::usb_interface               > Read 4 bytes, 0 bytes remaining
 TRACE probe_rs::probe::stlink::usb_interface               > Sending command [f2, 3e] to STLink, timeout: 1s
 TRACE probe_rs::probe::stlink::usb_interface               > Read 12 bytes, 0 bytes remaining
 DEBUG probe_rs::probe::stlink                              > Read mem 32 bit, address=e0002008, length=4
 TRACE probe_rs::probe::stlink::usb_interface               > Sending command [f2, 7, 8, 20, 0, e0, 4, 0, 0] to STLink, timeout: 1s
 TRACE probe_rs::probe::stlink::usb_interface               > Read 4 bytes, 0 bytes remaining
 TRACE probe_rs::probe::stlink::usb_interface               > Sending command [f2, 3e] to STLink, timeout: 1s
 TRACE probe_rs::probe::stlink::usb_interface               > Read 12 bytes, 0 bytes remaining
 DEBUG probe_rs::probe::stlink                              > Read mem 32 bit, address=e0002000, length=4
 TRACE probe_rs::probe::stlink::usb_interface               > Sending command [f2, 7, 0, 20, 0, e0, 4, 0, 0] to STLink, timeout: 1s
 TRACE probe_rs::probe::stlink::usb_interface               > Read 4 bytes, 0 bytes remaining
 TRACE probe_rs::probe::stlink::usb_interface               > Sending command [f2, 3e] to STLink, timeout: 1s
 TRACE probe_rs::probe::stlink::usb_interface               > Read 12 bytes, 0 bytes remaining
 DEBUG probe_rs::probe::stlink                              > Read mem 32 bit, address=e000200c, length=4
 TRACE probe_rs::probe::stlink::usb_interface               > Sending command [f2, 7, c, 20, 0, e0, 4, 0, 0] to STLink, timeout: 1s
 TRACE probe_rs::probe::stlink::usb_interface               > Read 4 bytes, 0 bytes remaining
 TRACE probe_rs::probe::stlink::usb_interface               > Sending command [f2, 3e] to STLink, timeout: 1s
 TRACE probe_rs::probe::stlink::usb_interface               > Read 12 bytes, 0 bytes remaining
 DEBUG probe_rs::probe::stlink                              > Read mem 32 bit, address=e0002000, length=4
 TRACE probe_rs::probe::stlink::usb_interface               > Sending command [f2, 7, 0, 20, 0, e0, 4, 0, 0] to STLink, timeout: 1s
 TRACE probe_rs::probe::stlink::usb_interface               > Read 4 bytes, 0 bytes remaining
 TRACE probe_rs::probe::stlink::usb_interface               > Sending command [f2, 3e] to STLink, timeout: 1s
 TRACE probe_rs::probe::stlink::usb_interface               > Read 12 bytes, 0 bytes remaining
 DEBUG probe_rs::probe::stlink                              > Read mem 32 bit, address=e0002010, length=4
 TRACE probe_rs::probe::stlink::usb_interface               > Sending command [f2, 7, 10, 20, 0, e0, 4, 0, 0] to STLink, timeout: 1s
 TRACE probe_rs::probe::stlink::usb_interface               > Read 4 bytes, 0 bytes remaining
 TRACE probe_rs::probe::stlink::usb_interface               > Sending command [f2, 3e] to STLink, timeout: 1s
 TRACE probe_rs::probe::stlink::usb_interface               > Read 12 bytes, 0 bytes remaining
 DEBUG probe_rs::probe::stlink                              > Read mem 32 bit, address=e0002000, length=4
 TRACE probe_rs::probe::stlink::usb_interface               > Sending command [f2, 7, 0, 20, 0, e0, 4, 0, 0] to STLink, timeout: 1s
 TRACE probe_rs::probe::stlink::usb_interface               > Read 4 bytes, 0 bytes remaining
 TRACE probe_rs::probe::stlink::usb_interface               > Sending command [f2, 3e] to STLink, timeout: 1s
 TRACE probe_rs::probe::stlink::usb_interface               > Read 12 bytes, 0 bytes remaining
 DEBUG probe_rs::probe::stlink                              > Read mem 32 bit, address=e0002014, length=4
 TRACE probe_rs::probe::stlink::usb_interface               > Sending command [f2, 7, 14, 20, 0, e0, 4, 0, 0] to STLink, timeout: 1s
 TRACE probe_rs::probe::stlink::usb_interface               > Read 4 bytes, 0 bytes remaining
 TRACE probe_rs::probe::stlink::usb_interface               > Sending command [f2, 3e] to STLink, timeout: 1s
 TRACE probe_rs::probe::stlink::usb_interface               > Read 12 bytes, 0 bytes remaining
 DEBUG probe_rs::probe::stlink                              > Read mem 32 bit, address=e0002000, length=4
 TRACE probe_rs::probe::stlink::usb_interface               > Sending command [f2, 7, 0, 20, 0, e0, 4, 0, 0] to STLink, timeout: 1s
 TRACE probe_rs::probe::stlink::usb_interface               > Read 4 bytes, 0 bytes remaining
 TRACE probe_rs::probe::stlink::usb_interface               > Sending command [f2, 3e] to STLink, timeout: 1s
 TRACE probe_rs::probe::stlink::usb_interface               > Read 12 bytes, 0 bytes remaining
 DEBUG probe_rs::probe::stlink                              > Read mem 32 bit, address=e0002018, length=4
 TRACE probe_rs::probe::stlink::usb_interface               > Sending command [f2, 7, 18, 20, 0, e0, 4, 0, 0] to STLink, timeout: 1s
 TRACE probe_rs::probe::stlink::usb_interface               > Read 4 bytes, 0 bytes remaining
 TRACE probe_rs::probe::stlink::usb_interface               > Sending command [f2, 3e] to STLink, timeout: 1s
 TRACE probe_rs::probe::stlink::usb_interface               > Read 12 bytes, 0 bytes remaining
 DEBUG probe_rs::probe::stlink                              > Read mem 32 bit, address=e0002000, length=4
 TRACE probe_rs::probe::stlink::usb_interface               > Sending command [f2, 7, 0, 20, 0, e0, 4, 0, 0] to STLink, timeout: 1s
 TRACE probe_rs::probe::stlink::usb_interface               > Read 4 bytes, 0 bytes remaining
 TRACE probe_rs::probe::stlink::usb_interface               > Sending command [f2, 3e] to STLink, timeout: 1s
 TRACE probe_rs::probe::stlink::usb_interface               > Read 12 bytes, 0 bytes remaining
 DEBUG probe_rs::probe::stlink                              > Read mem 32 bit, address=e000201c, length=4
 TRACE probe_rs::probe::stlink::usb_interface               > Sending command [f2, 7, 1c, 20, 0, e0, 4, 0, 0] to STLink, timeout: 1s
 TRACE probe_rs::probe::stlink::usb_interface               > Read 4 bytes, 0 bytes remaining
 TRACE probe_rs::probe::stlink::usb_interface               > Sending command [f2, 3e] to STLink, timeout: 1s
 TRACE probe_rs::probe::stlink::usb_interface               > Read 12 bytes, 0 bytes remaining
 TRACE probe_rs::probe::stlink                              > Getting current mode of device...
 TRACE probe_rs::probe::stlink::usb_interface               > Sending command [f5] to STLink, timeout: 1s
 TRACE probe_rs::probe::stlink::usb_interface               > Read 2 bytes, 0 bytes remaining
 DEBUG probe_rs::probe::stlink                              > Current device mode: Jtag
Error attaching to RTT: Error communicating with probe: An error specific to a probe type occured

Here command [f2, 3e] seems to repeatedly fail. 0xf2, 0x3e is a JTAG command named JTAG_GETLASTRWSTATUS2, so apparently some read or write is failing. After littering the code with debug logging, I managed to narrow down what is exactly happening here:

It manages to find the RTT descriptors in SRAM after scanning for them linearly, it parses everything and then tries to read the channel name. In my case, the name is located in flash at address 0x0800168c. This read fails on the GD32. Both the J-Link and the ST-Link fail to read the flash in the same way as far as I can tell from the tracing output. (I left out the sweeping part in the traces, it's just the failing read until it gives up and errors out)

I then created a small test application using probe-rs which replicates reads from beginning of SRAM and flash using both the MemoryAP directly, as well as using a session with the STM32F103 target selected. On both of these versions, the read from RAM always succeeds and the flash read always fails UNLESS the CPU core is halted. As soon as I halt the CPU core, the flash read succeeds all the time (when using the MemoryAP it really fails with an error, when using the Session it returns zeros).

Example for the reads with the session:

use probe_rs::{
    Probe,
    MemoryInterface,
    config::TargetSelector
};
use anyhow::{Result, Context};

fn main() -> Result<()> {
    let probes = Probe::list_all();
    println!("probes: {:?}", probes);

    let probe = probes[0].open()?;

    let mut session = probe
        .attach(TargetSelector::from("STM32F103C8"))
        .context("Failed to attach probe to target")?;
    let mut core = session.core(0).context("Failed to attach to core")?;

    let mut bytes = vec![0u8; 4];
    core.read_8(0x20000000, bytes.as_mut())?;
    println!("ram: {:#x?}", bytes);

    let mut bytes = vec![0u8; 4];
    core.halt(std::time::Duration::from_millis(100))?;
    core.read_8(0x08000000, bytes.as_mut())?;
    core.run()?;
    println!("flash: {:#x?}", bytes);

    Ok(())
}

After that I added the code to halt the CPU core for just the flash read to probe-rs-rtt and rebuilt probe-run using my patched version which magically started to work.

The patch:

diff --git a/probe-rs-rtt/src/channel.rs b/probe-rs-rtt/src/channel.rs
index be9b600..746fe88 100644
--- a/probe-rs-rtt/src/channel.rs
+++ b/probe-rs-rtt/src/channel.rs
@@ -394,7 +394,11 @@ fn read_c_string(
 
     // Read up to 128 bytes not going past the end of the region
     let mut bytes = vec![0u8; min(128, (range.end - ptr) as usize)];
-    session.core(0)?.read_8(ptr, bytes.as_mut())?;
+
+    let mut core = session.core(0)?;
+    core.halt(std::time::Duration::from_millis(100))?;
+    core.read_8(ptr, bytes.as_mut())?;
+    core.run()?;
 
     // If the bytes read contain a null, return the preceding part as a string, otherwise None.
     Ok(bytes

Now I don't know enough about the internals of the GD32 to exactly know what's going on or if there is another way to make it work by poking the right registers during startup, but something is definitely wonky here.

For a short time, because the naming scheme confused me, I used the gd32f1x0-hal crate which is the correct HAL for the F130 instead of the F103. When I used this and just had a tight loop with some prints going over RTT, it worked fine. It dawned on me that this is the wrong crate when I got hard faults for accessing the GPIO controller to make an LED blink. I don't know yet what the exact difference between the two crates is that makes RTT work or not.

So if anybody has an idea what to try out to make this flash read work without halting the core, I would be happy to try it.

edit: I am not able to make RTT work again by using the wrong crate. I wanted to disassemble and diff the resulting binaries, but I seem to be unable to make it work again :-/

To Reproduce
Steps to reproduce the behavior:

  1. Get a GD32F103C8T6
  2. Build a blinky with some RTT code
  3. Use probe-run to flash and run your code, watch the RTT part fail

Expected behavior
RTT should work

@G33KatWork G33KatWork added the bug Something isn't working label Jul 15, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant