Default linker script fails on STM32L412 - fix included

I’ve been able to get a test blink working on a Nucleo-L412KB (that’s the 32-pin variant, not the 64-pin Nucleo’s). But it took a little tinkering.

First, the default linker script can’t be used, because it sets the stack at 64K, whereas the L412 has 40K max. I changed _estack in framework-stm32cube/platformio/ldscripts/STM32L412KB_DEFAULT.ld to work around this.

Next, stlink does not recognise the L412, which has ID 0x464. This was fixed by building a patched version of texane/stlink on GitHub:

$ git diff
diff --git a/src/chipid.c b/src/chipid.c
index 6f93af1..ca6e815 100644
--- a/src/chipid.c
+++ b/src/chipid.c
@@ -507,6 +507,19 @@ static const struct stlink_chipid_params devices[] = {
             .bootrom_base = 0x1ff00000,
             .bootrom_size = 0x2000
+        {
+            // STM32L41X
+            .chip_id = STLINK_CHIPID_STM32_L41X,
+            .description = "L412 device",
+            .flash_type = STLINK_FLASH_TYPE_L4,
+            .flash_size_reg = 0x1fff75e0,    // "Flash size data register" (sec 49.2, page 1809)
+            .flash_pagesize = 0x800,         // Page erase (2 Kbyte) (sec 3.2, page 93)
+            // SRAM1 is 32k at 0x20000000
+            // SRAM2 is 8k at 0x20008000
+            .sram_size = 0x0A000,
+            .bootrom_base = 0x1fff0000,
+            .bootrom_size = 0x7000
+        },
             // unknown
             .chip_id = STLINK_CHIPID_UNKNOWN,
diff --git a/src/flash_loader.c b/src/flash_loader.c
index 7684680..f2e6367 100644
--- a/src/flash_loader.c
+++ b/src/flash_loader.c
@@ -306,6 +306,7 @@ int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t*
         loader_code = loader_code_stm32f0;
         loader_size = sizeof(loader_code_stm32f0);
     } else if ((sl->chip_id == STLINK_CHIPID_STM32_L4) ||
+              (sl->chip_id == STLINK_CHIPID_STM32_L41X) ||
               (sl->chip_id == STLINK_CHIPID_STM32_L43X) ||
               (sl->chip_id == STLINK_CHIPID_STM32_L46X) ||
               (sl->chip_id == STLINK_CHIPID_STM32_L4RX) ||

The openocd scripts also don’t appear to support the L412 (yet, I hope). The workaround for now (if you don’t patch stlink) is to use mbed as upload protocol.

UPDATE: I’ve also submitted a board file for the Nucleo-L412KB - see Board file for STM32L412KB · Issue #171 · platformio/platform-ststm32 · GitHub

UPDATE # 2: also reported as stlink issue - see Add support for STM32L412 · Issue #754 · stlink-org/stlink · GitHub

Could you try the latest version of openOCD from Release GNU MCU Eclipse OpenOCD v0.10.0-11-20190118 · ilg-archived/openocd · GitHub ? Does it work?

Thx for following up. I think it still fails - in one shell, I did:

$ bin/openocd -f board/st_nucleo_l4.cfg
GNU MCU Eclipse 64-bit Open On-Chip Debugger 0.10.0+dev-00462-gdd1d90111 (2019-01-15-13:49)
Licensed under GNU GPL v2
For bug reports, read
Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD
adapter speed: 500 kHz
adapter_nsrst_delay: 100
none separate
srst_only separate srst_nogate srst_open_drain connect_deassert_srst
Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
Info : clock speed 500 kHz
Info : STLINK V2J32M22 (API v2) VID:PID 0483:374B
Info : Target voltage: 3.247337
Info : stm32l4x.cpu: hardware has 6 breakpoints, 4 watchpoints
Info : Listening on port 3333 for gdb connections
Info : accepting 'gdb' connection on tcp/3333
Info : device id = 0x10006464
Warn : Cannot identify target as an STM32L4 family device.
Error: auto_probe failed
Error: Connect failed. Consider setting up a gdb-attach event for the target to prepare target for GDB connect, or use 'gdb_memory_map disable'.
Error: attempted 'gdb' connection rejected

And in another one:

$ arm-none-eabi-gdb
GNU gdb (GNU Tools for Arm Embedded Processors 8-2018-q4-major)
Type "apropos word" to search for commands related to "word".
(gdb) tar ext :3333
Remote debugging using :3333
Remote connection closed

I’m assuming -f looks relative to the openocd executable, i.e. in the new release.

One more tweak is needed to get STM32L412 uploads working under openocd. I ended up rebuilding openocd from source with this change:

diff --git a/src/flash/nor/stm32l4x.c b/src/flash/nor/stm32l4x.c
index f680542c..33f27497 100644
--- a/src/flash/nor/stm32l4x.c
+++ b/src/flash/nor/stm32l4x.c
@@ -619,6 +619,9 @@ static int stm32l4_probe(struct flash_bank *bank)
        case 0x435:
                max_flash_size_in_kb = 256;
+       case 0x464:
+               max_flash_size_in_kb = 128;
+               break;
                LOG_WARNING("Cannot identify target as an STM32L4 family device.");
                return ERROR_FAIL;
1 Like

Did you report this to openOCD team?

No, because I didn’t see how/where. Feel free to submit where it makes sense.

(and got a bit discouraged by my stlink bug report for this same L412 issue - instead of just adding a few lines, the developer wanted me to submit a pull request - I’m all for convenience, but that sort of jumping through hoops for a trivial tweak was just being silly)

UPDATE - this seems related:

But we use openOCD compiled in April, so these changes should be applied?

I’m getting the same error as jcw with the default current versions of everything. It looks like another change was made to stlink in May ( – if that’s not included, could it be causing this problem?

We use openOCD, not st-link util. Do you still have this issue? If yes, please report to GitHub - platformio/platform-ststm32: ST STM32: development platform for PlatformIO