PlatformIO Community

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

UPDATE # 2: also reported as stlink issue - see

Could you try the latest version of openOCD from ? 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;