platformio / platform-ststm32

ST STM32: development platform for PlatformIO
https://registry.platformio.org/platforms/platformio/ststm32
Apache License 2.0
407 stars 312 forks source link

board disco_l072cz_lrwan1 - [upload] Error 1 (OpenOCD init failed) #353

Open lnlp opened 4 years ago

lnlp commented 4 years ago

Configuration

Windows 10 Installed drivers: ST-Link drivers v2.0.1

Platformio version: Core 4.2.2a3, Home 3.1.1 Platform: ST STM 6.0.0 Framework: Arduino Board: disco_l072cz_lrwan1

In Device Manager the board is recognized as: COM port: STMicroelectronics STLink Virtual COM Port (COM17) USB device: ST-Link Debug In System Tray the board is visible as USB device: STM32 STLink, with drive DIS_L072Z (F:) So far this all looks normal.

Problem

When trying to upload a sketch I get the following error

Configuring upload protocol...
AVAILABLE: blackmagic, jlink, mbed, stlink
CURRENT: upload_protocol = stlink
Uploading .pio\build\discovery-l072z-lrwan1\firmware.elf
xPack OpenOCD, 32-bit Open On-Chip Debugger 0.10.0+dev (2019-07-17-07:34)
Licensed under GNU GPL v2
For bug reports, read
        http://openocd.org/doc/doxygen/bugs.html
debug_level: 1

srst_only separate srst_nogate srst_open_drain connect_deassert_srst

Error: init mode failed (unable to connect to the target)
in procedure 'program'
** OpenOCD init failed **
shutdown command invoked

*** [upload] Error 1

upload_protocol = stlink should be fine and is the default for this board.

I tried reconnecting the board, reboot and restart VScode several times but none made any difference.

What could go possibly wrong here? Is this a bug or did I overlook something?

valeros commented 4 years ago

Hi @lnlp . Could you please try the following configuration:

[env:discovery-l072z-lrwan1]
platform = ststm32
board = disco_l072cz_lrwan1
framework = arduino
upload_flags =
  -c
  reset_config none

As a workaround you can use upload_protocol = mbed

lnlp commented 4 years ago

Hi @valeros,

I tried your suggestions (see test 2 and test 3) but they do not solve the issue.

Just to be sure I replaced the previous sketch with a bare minimum sketch that only switches leds on and off (to rule out any possible other factors). This may give slight differences when compared with the output from above.

I have disconnected an reconnected (USB) the board before each test. After connecting the board, the RGB led on the board is red. I have performed a 'Clean' before each compile/upload run.

The board itself works fine which can be seen in Test 4. It is Platformio that causes issues when uploading with the stlink protocol.

The board is connected / uploads are performed via the USB port labeled 'USB STLINK'.

Compared with the previous tests above, the error type has changed from: "Error: init mode failed (unable to connect to the target)" To: "Error: failed erasing sectors 0 to 3" I cannot really explain why, possibly due to the restoring/reflashing to ST-Link.

Test 1

Plain minimal platformio.ini Result: Upload fails. RGB color LED starts red, flashes several times between green and red and ends with green color.

platformio.ini

[env:disco_l072cz_lrwan1]
platform = ststm32
board = disco_l072cz_lrwan1
framework = arduino

Terminal/Upload output:

Configuring upload protocol...
AVAILABLE: blackmagic, jlink, mbed, stlink
CURRENT: upload_protocol = stlink
Uploading .pio\build\disco_l072cz_lrwan1\firmware.elf
xPack OpenOCD, 32-bit Open On-Chip Debugger 0.10.0+dev (2019-07-17-07:34)
Licensed under GNU GPL v2
For bug reports, read
        http://openocd.org/doc/doxygen/bugs.html
debug_level: 1

srst_only separate srst_nogate srst_open_drain connect_deassert_srst

target halted due to debug-request, current mode: Thread 
xPSR: 0xf1000000 pc: 0x08002868 msp: 0x20005000
STM32L0: Enabling HSI16
** Programming Started **
Warn : STM32L flash size failed, probe inaccurate - assuming 192k flash
Error: failed erasing sectors 0 to 3
embedded:startup.tcl:449: Error: ** Programming Failed **
in procedure 'program' 
in procedure 'program_error' called at file "embedded:startup.tcl", line 508
at file "embedded:startup.tcl", line 449
*** [upload] Error 1

Test 2

Added upload_flags to platformio.ini. Result: Upload fails. RGB color LED starts red, flashes several times between green and red and ends with green color. When compared with the output from test 1, the only visible difference is that "none separate" is added to the error message.

platformio.ini

[env:disco_l072cz_lrwan1]
platform = ststm32
board = disco_l072cz_lrwan1
framework = arduino
upload_flags =
  -c
  reset_config none

Terminal/Upload output:

Configuring upload protocol...
AVAILABLE: blackmagic, jlink, mbed, stlink
CURRENT: upload_protocol = stlink
Uploading .pio\build\disco_l072cz_lrwan1\firmware.elf
xPack OpenOCD, 32-bit Open On-Chip Debugger 0.10.0+dev (2019-07-17-07:34)
Licensed under GNU GPL v2
For bug reports, read
        http://openocd.org/doc/doxygen/bugs.html
debug_level: 1

none separate

srst_only separate srst_nogate srst_open_drain connect_deassert_srst

target halted due to debug-request, current mode: Thread 
xPSR: 0xf1000000 pc: 0x08002868 msp: 0x20005000
STM32L0: Enabling HSI16
** Programming Started **
Warn : STM32L flash size failed, probe inaccurate - assuming 192k flash
Error: failed erasing sectors 0 to 3
embedded:startup.tcl:449: Error: ** Programming Failed **
in procedure 'program' 
in procedure 'program_error' called at file "embedded:startup.tcl", line 508
at file "embedded:startup.tcl", line 449
*** [upload] Error 1

Test 3

Removed upload_flags and set upload protocol to embed. This gives below warning during compile and upload but both compile and upload are reported as SUCCESS. But the upload actually never starts and the RGB led stays red.

platformio.ini

[env:disco_l072cz_lrwan1]
platform = ststm32
board = disco_l072cz_lrwan1
framework = arduino
upload_protocol = embed

Terminal/Upload output:

Warning! Unknown upload protocol embed

Test 4

For this test I have upgraded the on-board ST-Link adapter to J-Link by flashing it with with Segger's STLinkReflash tool. Additionally in platformio.ini I have set the upload protocol to jlink. The upload was then performed without any errors which proves that the board is working correctly.

I then restored the ST-Link firmware (ST-LINK/V2-1) to the board (also with STLinkReflash) which made it into ST-Link again. I then performed test 1 to 3 again but upload still fails.

Therefore the upload issue is probably related to Platformio.

lnlp commented 4 years ago

Additional testing (with Arduino IDE):

For ST DISCO-L072CZ-LRWAN1 (official product name is B-L072Z-LRWAN1 Discovery kit) PlatformIO supports the following upload methods:

The ST supported 'Arduino Core STM32' supports the following upload methods in the Arduino IDE:

I'm not sure how the upload protocols supported in PlatformIO compare with the upload methods in the Arduino IDE (which to my knowledge are provided by Arduino Core STM32). But it looks like these protocols and methods are not the same and I would have expected PlatformIO to provide at least the same possibilities as provided by the Arduino Core STM32 but this appears not to be the case.

When testing the same sketch that I used with PlatformIO but now in the Arduino IDE, it was possible to get the upload working in the Arduino IDE. But only when using upload method 'Mass Storage' (none of the STM32CubeProgrammer methods worked, while using USB, without additional hardware)). The 'Mass Storage' option seems not to be supported by PlatformIO.

@fipstm (who maintains Arduino Core STM32) has mentioned elsewhere that he does not know how Arduino Core STM32 and the tools were implemented within PlatformIO.

Hopefully @ivankravets can elaborate on this, and explain the differences in supported upload protocols / methods between PlatformIO and Arduino IDE / Arduino Core STM32.

valeros commented 4 years ago

Mass Storage is equivalent of upload_protocol = mbed. It doesn't work since you have a typo in upload_protocol = embed (it should be upload_protocol = mbed) .

As for the difference between PlatformIO and Arduino Core STM32, PlatformIO added support for ststm32 platform substantially earlier than Arduino Core STM32 was even created. At that moment, different frameworks required different upload tools, so the set of upload methods evolved independently from available frameworks.

lnlp commented 4 years ago

It doesn't work since you have a typo in upload_protocol = embed (it should be upload_protocol = mbed)

Thanks. Part of my brain must have been sleeping.. 🤭

valeros commented 4 years ago

Yes, upload_protocol = mbed works, but it has a handicap that upload_port is not determined automatically and must be specified explicitly. This is not very flexible and not cross platform compatible. Why is it not determined automatically?

There is some basic autodetection. But it looks like, it doesn't work because the name of the mass storage device is DIS_L072Z. You can write an extra script that will select the right device for your project.

It appears that neither of the upload methods is explained in the documentation. Not in the board documentation and not in in the upload options documentation. Where to find it?

That's true, there is only a list of possible upload methods and no detailed information about them (although you can find some info for these upload methods in the Debug Probes section), but, indeed it's not very obvious, so it might be a good improvement to our docs.

also explain/compare PlatformIO supported upload protocols and Arduino Core/Arduino IDE supported upload methods so it is clear which is what.

Since PlatformIO is agnostic to frameworks, it's possible that we might have a different set of upload method in comparison with Arduino Core/Arduino IDE, besides STM32 Arduino Core uses a proprietary upload tool called STM32CubeProgrammer which we do not have support for.

After my testing it appears that the errors that I experience with the stlink protocol are caused by a bug in PlatformIO. Is that correct?

This board might have additional requirements about initialization we are not aware of. If it works with the JLink software, then the problem is with OpenOCD device. The error message Error: failed erasing sectors 0 to 3 is really strange since you don't have any locked flash pages, right? Besides, you mentioned that none of the STM32CubeProgrammer methods worked, what was the error message then?

Anyway, PlatformIO is an open source project, if you think that it lacks any kind of documentation, feel free to submit a PR to an appropriate repository.

copleston commented 4 years ago

I also have this issue. I'm unable to upload to disco_l072cz_lrwan1 using any of the above methods.

lnlp commented 4 years ago

On Windows the following works:

upload_protocol = mbed      ;On Windows PlatformIO fails to recognize DIS_L072Z as drive volume
upload_port = F:            ;Correct drive must be explicitly specified (HW configuration & OS dependent)

But to be honest, having to explicitly specify a driveletter that can change very easily (dependent on e.g. how many flash drives are connected at any moment) just sucks. This is 2020..

@valeros

There is some basic autodetection. But it looks like, it doesn't work because the name of the mass storage device is DIS_L072Z. You can write an extra script that will select the right device for your project.

No I shall not. If PlatformIO supports this board then PlatformIO should improve this. This apparently standard behavior is now known. I do not understand why correctly implementing this is left up to the user (every user).

As for the difference between PlatformIO and Arduino Core STM32, PlatformIO added support for ststm32 platform substantially earlier than Arduino Core STM32 was even created. At that moment, different frameworks required different upload tools, so the set of upload methods evolved independently from available frameworks.

It is understandable that there are historical reasons for differences but historical reasons are not a justification for not making changes in the future.

Arduino Core STM32 is currently THE MAJOR Arduino core for the STM32 platform and it's supported by STMicroelectronics. Isn't it just weird that its maintainer is not aware how PlatformIO has implemented its Arduino support for STM32 and isn't it strange that PlatformIO responds like above while during the last two years 'Arduino Core STM32' has become the major Arduino core for STM32?

I hope for better cooperation between PlatformIO and https://github.com/stm32duino/Arduino_Core_STM32 and its maintainer because the STM32 platform is not just some kind of niche product and neither is the Arduino framework.

fpistm commented 4 years ago

Isn't it just weird that its maintainer is not aware how PlatformIO has implemented its Arduino support

No, the core is dedicated for Arduino environment not for PIO. The core is open source and freely usable. All contribution are welcome :wink; PIO provide a way to use it and this is fine anyway I don't have to know how it is integrated or used. The core is used in several other env or SDK and I always welcome any contribution if it can help to integration/use while it does not break Arduino compatibility and usage in the Arduino IDE. Finally, I would like to thanks @valeros and @ivankravets for their great work and effort. I know how it is sometimes hard to support/integrate several framework in an all in one environment. 👏

valeros commented 4 years ago

No I shall not. If PlatformIO supports this board then PlatformIO should improve this. This apparently standard behavior is now known. I do not understand why correctly implementing this is left up to the user (every user).

There are more than one hundred boards in this platform, obviously we're physically not able to retest all these boards with all possible upload methods. Besides, the OpenOCD initialization can differ from board to board, even a new revision of the same board might not work with the current configuration. As for disco_l072cz_lrwan1, anyone is welcomed to do some research and find why the configuration for OpenOCD doesn't work for this board.

Arduino Core STM32 is currently THE MAJOR Arduino core for the STM32 platform and it's supported by STMicroelectronics. Isn't it just weird that its maintainer is not aware how PlatformIO has implemented its Arduino support for STM32 and isn't it strange that PlatformIO responds like above while during the last two years 'Arduino Core STM32' has become the major Arduino core for STM32?

PlatformIO supports more 20 open source development platform, each of them has a bunch of frameworks that requires time and efforts to maintain. We don't divide framewors/SDKs/platforms/Arduino cores on major/minor, all of them are treated equally.

It is understandable that there are historical reasons for differences but historical reasons are not a justification for not making changes in the future.

There is no point in arguing what should have been done, PlatformIO is an open source project, if you see a drawback feel free to submit a PR with a bugfix.

lnlp commented 4 years ago

@fpistm

No, the core is dedicated for Arduino environment not for PIO.

To my understanding Arduino Core STM32 was meant to support the Arduino framework in general with an implementation for Arduino IDE, but also that the framework implementation itself would be re-usable for other environments/IDE's like PlatformIO. Is that assumption incorrect?

Maybe my view is just too simplistic, caused by limited knowledge.

lnlp commented 4 years ago

@valeros

There is no point in arguing what should have been done, PlatformIO is an open source project, if you see a drawback feel free to submit a PR with a bugfix.

I am not arguing what should have been done. My point is that if a board is supported, that at least one of the supported upload mechanisms should work (without having to manually tweak 'port' in the settings, information that I was not able to find in the PlatformIO documentation). In case of upload mechanism 'mbed' that would mean that it automatically checks for the (possibly) assigned volume drive letter. If that does not work (on Windows at least) then I think it is worth fixing in general or at least document it.

I understand and respect all the work involved. But it is also a fact that it will be much easier to tweak some existing code for the author of that code, or someone already experienced with that code, than for some (any) user who would have to dive in from scratch.

From a user perspective things are not always clear and lack of documentation for the upload protocols does not make it easier. As a user one expects the basic things to work or at least be able to find the documentation for how to get it work. I haven't ran into similar issues before. When something (board/framework) works in the Arduino IDE and is also supported in PlatformIO it usually runs better with PlatformIO, faster and with all benefits of a more professional IDE like VSCode (+plugins).

fpistm commented 4 years ago

@lnlp

To my understanding Arduino Core STM32 was meant to support the Arduino framework in general with an implementation for Arduino IDE, but also that the framework implementation would be re-usable for other environments/IDE's like PlatformIO. Is that assumption incorrect?

STM32duino GitHub organization support only the official Arduino ecosystem (Arduino IDE, arduino-cli, ...) then it follows the Arduino API references, core and libraries specification for its ecosystem. Several of those specifications are not followed by other env/plugin/SDK. Ex: pre/post build recipe, packages dependencies, tools,...

lnlp commented 4 years ago

I do understand that there are differences between IDE's, how boards are supported and that even the (external) tools can be different (latter presumably because of advantages like debugging support).

But what about the Arduino code that the user writes? Are there any possible compatibility issues between developing using Arduino Core STM32 with Arduino IDE and developing for STM32 and Arduino framework using PlatformIO?

Are the underlying Arduino API to STM32 HAL mappings (or whatever their exact/correct names) the same or are there implementation differences here also?

To my understanding if application code was developed for/with Arduino Core STM32, it should also run just fine when using PlatformIO (with its STM32 and Arduino framework support). Or is this not true because of implementation differences. Maybe @valeros or @ivankravets can shine some light on this?

valeros commented 4 years ago

To my understanding if application code was developed for/with Arduino Core STM32, it should also run just fine when using PlatformIO (with its STM32 and Arduino framework support). Or is this not true because of implementation differences.

It's true, the code developed with Arduino Core STM32 should work with PlatformIO without modifications (except .ino files, that need to be converted to proper cpp in order to use intellisense in the IDE). The framework, build flags, linker scripts are identical. What may differ is build workflow (using static libs or objects directly, order of these libs when linking, etc) and upload methods,

copleston commented 4 years ago

I managed to fix the problem by updating the ST-LINK firmware and then using upload_protocol = mbed