Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Serious problem with STM32F103 some clones #2

Open
thanks4opensource opened this issue Nov 18, 2020 · 10 comments
Open

Serious problem with STM32F103 some clones #2

thanks4opensource opened this issue Nov 18, 2020 · 10 comments

Comments

@thanks4opensource
Copy link
Owner

Problem: "logic" command does not terminate on some "Blue Pill" MCUs

Reason: MCU does not generate interrupt when writing past end of RAM

Workaround: None. Do not use "logic edges=" or "logic edges=unlimited" feature. Set "logic duration=" or manually halt sampling via ENTER key.

Background info: Firmware sampling code is infinite loop terminated by write past end of memory, elapsed timer, or user halt command from host via USB. See Infinite loop.

Details:
Manufacturers of "Blue Pill" development boards are known to use cloned/bootleg/reject STM MCUs. See https://github.com/keirf/Greaseweazle/wiki/STM32-Fakes and other online resources. Note that visual inspection of the MCU is likely not sufficient to determine genuine chips vs clones. Note also that some clones may perform perfectly/adequately, and that the buck50 firmware exercises more STM32F103 subsystems/peripherals than does Greaseweazle. Also that there are at least two variants of "Blue Pill" PC boards (silkscreen labels, components -- round metal reset switch vs rectangular plastic, and USB connector) but these differences are not sufficient to tell if a board/MCU has the interrupt problem. The failing MCUs I have tested return a 0x2BA01477 CPUTAPID as reported by openocd software, compared to working chips with 0x1BA01477 which matches documentation in ST Reference Manual RM0008. Again, this may or may not be a 100% reliable means of detecting "good" vs "bad" chips, and I have seen 0x2BA01477 chips explicitly marked as clones with "CKS32F103C8T6" but also with seemingly correct STM markings. Finally, I assume triggering the ARM HardFault IRQ when writing to reserved locations in the CPU memory map is correct behavior (0x2BA01477 chips do not raise HardFault or any other IRQ) but do not have a definitive documentation reference stating this, nor a 100% known-to-be-genuine STM32F103 chip to test. One more: Clone chips likely will eventually terminate sampling when addresses increment into the 0x40000000 peripherals area of the memory map (in approx. 85.9 seconds with max 6.25MHz sampling speed input signals, or 4.3 years with none), probably resulting in CPU lockup requiring hardware reset.

@ranma
Copy link

ranma commented Nov 23, 2020

If the clone uses a compatible-enough Cortext-M3 configuration, the DWT (Data Watchpoint & Trace) unit could be configured with a watchpoint on either the last ram address or the first address after then end of ram.
With the right configuration it should raise the Debug Monitor exception, e.g. from https://electronics.stackexchange.com/questions/325560/can-cortex-m4-data-watchpoint-trigger-an-interrupt-without-a-debugger:

CoreDebug->DEMCR = CoreDebug_DEMCR_TRCENA_Msk /*enable tracing*/ |
                       CoreDebug_DEMCR_MON_EN_Msk /*enable debug interrupt*/;
DWT->COMP1 = <First address past end of ram>;
DWT->MASK1 = 0; //match all comparator bits, don't ignore any
DWT->FUNCTION1 = (1 << 11)/*DATAVSIZE 1 - match whole word*/
           | (1 << 1) | (1 << 2)/*generate a watchpoint event on write*/;
// Attempt to write past end of ram should now trigger DebugMon_Handler

BTW the DWT could also help figure out why your inner loop is slower than expected since it has performance counters, e.g.:
DWT LSU [Load Store Unit] Count Register
Use the DWT LSU Count Register to count the total number of cycles during which the
processor is processing an LSU operation beyond the first cycle.

In particular the reads from the APB bus (GPIO) will take at least 2 cycles, so that should show up in the LSU count.

@thanks4opensource
Copy link
Owner Author

Thanks for the info, @ranma. I'll try it when I get a chance. I'm a little afraid of going even deeper into the black hole of clone incompatibilities -- if the chips that fail can't get the hardfault trigger right, they're going to correctly implement DWT? And different builds (no way!) or runtime vectoring to one of multiple versions of the code? At some point I have to throw up my hands and say "it only runs on genuine chips or fully-compatible clones".

Also, do you know if using DWT programmatically in these kinds of ways precludes using a debugger (GDB) at the same time? I never would have been able to get past step 1 of the ARM projects I've done without GDB (and, as useful as it can be, semihosting or plain serial output print statements aren't a substitute).

I never managed to come up with a clear formula that matched my observed cycle counts, like "the ARM core cycles plus 2 if accessing APB", so seeing the LSU counts would be very interesting.

@ranma
Copy link

ranma commented Nov 24, 2020

if the chips that fail can't get the hardfault trigger right, they're going to correctly implement DWT?

I don't have one of the clones for comparison, but I'd assume they use a genuine arm block, so it mostly boils down to is the optional DWT feature included or not (https://developer.arm.com/documentation/ddi0337/h/introduction/configurable-options).

The reason the hardfault doesn't trigger as expected is more likely to be related to how the memory is mapped and address decoding, which is of course specific to the soc implementation, it will only fault if the address is fully decoded and out of range accesses cause a bus error. The implementation might instead ignore the write or wrap-around to the beginning of memory.

Also, do you know if using DWT programmatically in these kinds of ways precludes using a debugger (GDB) at the same time?

I'd assume it'll interfere with using watchpoints in gdb, yes.
Though you could test in the init code if the hardfault is triggered as expected and only set up the DWT fallback if the hardfault was not triggered in a test.

@thanks4opensource
Copy link
Owner Author

I've blindly speculated about the clone chips, with guesses ranging from stolen fab masks to ARM licensing and independent development of the surrounding silicon.

Testing on the clone showed writes above the end of RAM were being ignored (not wrapping or being aliased):

    (gdb) p/x *(unsigned)0x2000504c
    $3 = 0x0
    (gdb) set *(unsigned)0x2000504c = 0x98765432
    (gdb) p/x *(unsigned)0x2000504c
    $4 = 0x0

As interesting as the underlying reasons are, the bottom line is "the clones don't work", so it's back to a difficult decision about whether or not to support them.

@ranma
Copy link

ranma commented Nov 24, 2020

As interesting as the underlying reasons are, the bottom line is "the clones don't work", so it's back to a difficult decision about whether or not to support them.

True :)

Also some more interesting info about clones: https://github.com/keirf/Greaseweazle/wiki/STM32-Fakes
Which includes code to detect some: https://github.com/keirf/Greaseweazle/blob/master/src/blinky.c

@phil-barrett
Copy link

There is an epic thread about this subject here.

For the TL;DR crowd, it is very unlikely that you will actually get a real STM32F103 when you buy a "Blue Pill". There are something like 7 different chips identified (via decapping and comparing photos of the die). Interestingly enough, they are mostly all remarked with the ST logo.

@thanks4opensource
Copy link
Owner Author

Thanks, @phil-barrett. Yes, I had seen the eevblog forum pages. I haven't come across any incompatibilities other than the missing HardFault IRQ but would be interested in reports of any other buck50 command failures. Not much can be done about the situation other than possible workarounds, so as always it's caveat emptor.

@phil-barrett
Copy link

Well, that's good. Any plans to support the F411 or F401? Would love to see the iMXRT1062 (Teensy4.1) supported but suspect that is somewhere between never and NEVER.

@thanks4opensource
Copy link
Owner Author

No current 411/401 plans. I have a few in-house but haven't gotten around to playing with them. The biggest issue is USB -- I won't touch ST HAL, so doing buck50 or anything else on them requires a port of papoon_usb which is a complete rewrite that I've been warned is even more difficult to code than the STM32F1xx version. I may eventually do it as the newer USB peripheral is used on most of the current STM chips, but it's not on the schedule right now.

I'm a big fan of Paul Stoffregen and his "Teensy" designs, but at a distance. He seems to be married to the Arduino environment and last I checked any plans to support JTAG/SWD/xxx-Link/GDB are permanently on hold. That's his privilege, but I think he'd open up new markets for his products if he'd do it. I for one absolutely need a full development environment as IMO Arduino is great for beginners and hobbyists but not adequate for serious use. The saddest part is that there shouldn't be any reason why the auxiliary Cortext-M0 on boards like theTeensy4.1 couldn't run Black Magic Probe just like the ST Nucleo and Discovery boards have built-in ST-Link. Oh, well. :(

@phil-barrett
Copy link

Yeah, Paul has been resistant to supporting debug, even on the big Teensys. I use the T4.1 in a CNC breakout board - sold several hundred of them so far.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants