Skip to content

boards/arm/stm32: route nucleo-f412zg console through ST-LINK VCP.#18766

Open
aviralgarg05 wants to merge 1 commit intoapache:masterfrom
aviralgarg05:fix/issue-17722-nucleo-f412zg-stlink-console
Open

boards/arm/stm32: route nucleo-f412zg console through ST-LINK VCP.#18766
aviralgarg05 wants to merge 1 commit intoapache:masterfrom
aviralgarg05:fix/issue-17722-nucleo-f412zg-stlink-console

Conversation

@aviralgarg05
Copy link
Copy Markdown
Contributor

Summary

Fixed the NUCLEO-F412ZG board default console routing so nsh uses the on-board ST-LINK virtual COM port by default.

The board header now maps USART2 to the PA2/PA3 pinmux instead of the PD5/PD6 header pins. This matches the board’s shipped solder-bridge configuration and aligns the default console path with the hardware wiring described in issue #17722.

Impact

This change affects only the boards/arm/stm32/nucleo-f412zg board configuration.

  • User impact: the default nsh console now appears on the ST-LINK VCP, which is the expected out-of-the-box serial path.
  • Build impact: no new files or dependencies were added.
  • Compatibility impact: no ABI/API changes; this is a board-level pinmux correction.
  • Documentation impact: none required for this fix, since it corrects existing default board behavior rather than introducing a new feature.

Testing

Host: macOS on Apple Silicon, using the local NuttX workspace and the Apache NuttX Linux CI container image for a clean build environment.

Validation performed:

  • ./tools/checkpatch.sh -c -u -m -f boards/arm/stm32/nucleo-f412zg/include/board.h
  • Clean configure/build in a fresh tree using the Linux CI container:
    • ./tools/configure.sh -E -l nucleo-f412zg:nsh
    • make -j8
  • Repeated the same clean configure/build in a second fresh tree to confirm the result was reproducible.

Build result:

  • nuttx linked successfully.
  • nuttx.hex and nuttx.bin were generated successfully.
  • No warnings or errors were introduced by the board pinmux change.

@github-actions github-actions Bot added Size: XS The size of the change in this PR is very small Board: arm labels Apr 20, 2026
Copy link
Copy Markdown
Contributor

@linguini1 linguini1 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please document this change on the board docs.

Can you please test on hardware?

@aviralgarg05
Copy link
Copy Markdown
Contributor Author

Please document this change on the board docs.

Can you please test on hardware?

I will update the board documentation for this change.

I do not have NUCLEO-F412ZG hardware available, so I cannot provide a real hardware test log for the issue. I do not want to overstate the validation. At this point, the change has been verified with clean nucleo-f412zg:nsh builds and style checks only.

If this PR needs on-board confirmation before merge, could someone with access to the board please help verify that nsh comes up on the ST-LINK VCP with the default USART2 PA2/PA3 routing?

@cederom
Copy link
Copy Markdown
Contributor

cederom commented Apr 20, 2026

Thank you @aviralgarg05 this comes from my issue #17722 and will help in testing, will check in a free moment on a real hardware!! :-)

@cederom
Copy link
Copy Markdown
Contributor

cederom commented Apr 20, 2026

My testing below, before and after change, also no nsh on console.. let me see what is going on here o_O

% uname -a
FreeBSD hexagon 14.4-RELEASE-p1 FreeBSD 14.4-RELEASE-p1 GENERIC amd64

Before:

% git log -1
commit 02407ad192b3a10aae01f3a977005f06c5b4159c (HEAD -> master, origin/master, origin/HEAD)
Author: yanxingyu17 <v-yanxingyu@xiaomi.com>
Date:   Mon Apr 20 21:20:16 2026 +0800

    arch/risc-v/cmake: fix linker option case in Toolchain.cmake.

    Fix lowercase -wl to correct -Wl for GCC linker pass-through
    option in LTO full configuration. The lowercase form is not
    recognized by the linker, causing --print-memory-usage to be
    silently ignored.

    Signed-off-by: v-yanxingyu <v-yanxingyu@xiaomi.com>

% gmake clean distclean -j; ./tools/configure.sh -B nucleo-f412zg:nsh && gmake flash -j
(..)
#
# configuration written to .config
#
Create version.h
LN: platform/board to /XXX/nuttx/pr/nuttx-apps.git/platform/dummy
Register: dd
Register: nsh
Register: sh
In file included from chip/stm32_flash.c:40:
chip/stm32f20xxf40xx_flash.c:53:4: warning: #warning "Default Flash Configuration Used - See Override Flash Size Designator" [-Wcpp]
   53 | #  warning "Default Flash Configuration Used - See Override Flash Size Designator"
      |    ^~~~~~~
CC:  chip/stm32_pmstop.c chip/stm32_gpio.c:44:11: note: '#pragma message: CONFIG_STM32_USE_LEGACY_PINMAP will be deprecated migrate board.h see tools/stm32_pinmap_tool.py'
   44 | #  pragma message "CONFIG_STM32_USE_LEGACY_PINMAP will be deprecated migrate board.h see tools/stm32_pinmap_tool.py"
      |           ^~~~~~~
LD: nuttx
Memory region         Used Size  Region Size  %age Used
           flash:         70 KB         1 MB      6.84%
            sram:        8024 B       256 KB      3.06%
CP: nuttx.hex
CP: nuttx.bin
hexagon% openocd -f  interface/stlink.cfg -f target/stm32f4x.cfg -c 'program nuttx.bin 0x08000000; reset run; exit'
Open On-Chip Debugger 0.12.0
Licensed under GNU GPL v2
For bug reports, read
	http://openocd.org/doc/doxygen/bugs.html
Info : auto-selecting first available session transport "hla_swd". To override use 'transport select <transport>'.
Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD
Info : clock speed 2000 kHz
Info : STLINK V2J45M30 (API v2) VID:PID 0483:374B
Info : Target voltage: 3.272005
Info : [stm32f4x.cpu] Cortex-M4 r0p1 processor detected
Info : [stm32f4x.cpu] target has 6 breakpoints, 4 watchpoints
Info : starting gdb server for stm32f4x.cpu on 3333
Info : Listening on port 3333 for gdb connections
Info : Unable to match requested speed 2000 kHz, using 1800 kHz
Info : Unable to match requested speed 2000 kHz, using 1800 kHz
[stm32f4x.cpu] halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0x08000996 msp: 0x20002354
Info : Unable to match requested speed 8000 kHz, using 4000 kHz
Info : Unable to match requested speed 8000 kHz, using 4000 kHz
** Programming Started **
Info : device id = 0x30006441
Info : flash size = 1024 KiB
** Programming Finished **
Info : Unable to match requested speed 2000 kHz, using 1800 kHz
Info : Unable to match requested speed 2000 kHz, using 1800 kHz

% cu -l /dev/cuaU0 -s 115200
Connected
<--- SILENCE HERE AS UART PINS ARE NOT ON THE ST-LINK
~
[EOT]

After:

% git checkout aviralgarg05/fix/issue-17722-nucleo-f412zg-stlink-console
Note: switching to 'aviralgarg05/fix/issue-17722-nucleo-f412zg-stlink-console'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by switching back to a branch.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -c with the switch command. Example:

  git switch -c <new-branch-name>

Or undo this operation with:

  git switch -

Turn off this advice by setting config variable advice.detachedHead to false

HEAD is now at 78f49aeae8b boards/arm/stm32: route nucleo-f412zg console through ST-LINK VCP.


% git log -1
commit 78f49aeae8b844975a57c4634dc6c1dcb6fbd91a (HEAD, aviralgarg05/fix/issue-17722-nucleo-f412zg-stlink-console)
Author: aviralgarg05 <gargaviral99@gmail.com>
Date:   Sun Apr 19 23:25:11 2026 +0530

    boards/arm/stm32: route nucleo-f412zg console through ST-LINK VCP.

    Use the default USART2 PA2/PA3 pinmux for the NUCLEO-F412ZG board so the nsh console comes up on the on-board ST-LINK virtual COM port instead of the PD5/PD6 header pins.

    This matches the board's shipped solder-bridge routing and fixes the default console path described in issue #17722.

    Signed-off-by: aviralgarg05 <gargaviral99@gmail.com>

% gmake clean distclean -j; ./tools/configure.sh -B nucleo-f412zg:nsh && gmake flash -j
(..)
#
# configuration written to .config
#
Create version.h
LN: platform/board to /XXX/nuttx/pr/nuttx-apps.git/platform/dummy
Register: nsh
Register: sh
Register: dd
CC:  chip/stm32f40xxx_i2c.c chip/stm32_gpio.c:44:11: note: '#pragma message: CONFIG_STM32_USE_LEGACY_PINMAP will be deprecated migrate board.h see tools/stm32_pinmap_tool.py'
   44 | #  pragma message "CONFIG_STM32_USE_LEGACY_PINMAP will be deprecated migrate board.h see tools/stm32_pinmap_tool.py"
      |           ^~~~~~~
In file included from chip/stm32_flash.c:40:
chip/stm32f20xxf40xx_flash.c:53:4: warning: #warning "Default Flash Configuration Used - See Override Flash Size Designator" [-Wcpp]
   53 | #  warning "Default Flash Configuration Used - See Override Flash Size Designator"
      |    ^~~~~~~
LD: nuttx
Memory region         Used Size  Region Size  %age Used
           flash:         70 KB         1 MB      6.84%
            sram:        8024 B       256 KB      3.06%
CP: nuttx.hex
CP: nuttx.bin

hexagon% openocd -f  interface/stlink.cfg -f target/stm32f4x.cfg -c 'program nuttx.bin 0x08000000; reset run; exit'
Open On-Chip Debugger 0.12.0
Licensed under GNU GPL v2
For bug reports, read
	http://openocd.org/doc/doxygen/bugs.html
Info : auto-selecting first available session transport "hla_swd". To override use 'transport select <transport>'.
Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD
Info : clock speed 2000 kHz
Info : STLINK V2J45M30 (API v2) VID:PID 0483:374B
Info : Target voltage: 3.276770
Info : [stm32f4x.cpu] Cortex-M4 r0p1 processor detected
Info : [stm32f4x.cpu] target has 6 breakpoints, 4 watchpoints
Info : starting gdb server for stm32f4x.cpu on 3333
Info : Listening on port 3333 for gdb connections
Info : Unable to match requested speed 2000 kHz, using 1800 kHz
Info : Unable to match requested speed 2000 kHz, using 1800 kHz
[stm32f4x.cpu] halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0x08000996 msp: 0x20002358
Info : Unable to match requested speed 8000 kHz, using 4000 kHz
Info : Unable to match requested speed 8000 kHz, using 4000 kHz
** Programming Started **
Info : device id = 0x30006441
Info : flash size = 1024 KiB
** Programming Finished **
Info : Unable to match requested speed 2000 kHz, using 1800 kHz
Info : Unable to match requested speed 2000 kHz, using 1800 kHz

hexagon% cu -l /dev/cuaU0 -s 115200
Connected
<--- ALSO SILENCE HERE EVEN AFTER HARDWARE RESET :-(
~
[EOT]

@cederom
Copy link
Copy Markdown
Contributor

cederom commented Apr 20, 2026

Here is the DS for NUCLEO-F412ZG: [1] https://www.st.com/resource/en/user_manual/um1974-stm32-nucleo144-boards-mb1137-stmicroelectronics.pdf.

Looking at Revision History, on 28-Aug-2020, rev 8, they "Removed Electrical schematics." how nice ;-)

Looking at section 7.9 USART communication

The USART3 interface available on PD8 and PD9 of the STM32 can be connected either to ST-LINK or to ST morpho connector. The choice is changed by setting the related solder bridges. By default the USART3 communication is enabled between the target STM32 and both the ST-LINK and the ST morpho connector.

Table 9. USART3 pins

Pin name Function Virtual COM port ST morpho connection
PD8 USART3 TX SB5 ON and SB7 OFF SB5 OFF and SB7 ON
PD9 USART3 RX SB6 ON and SB4 OFF SB6 OFF and SB4 ON

Looks like we need to use PD8 and PD9 at USART3, but NuttX uses USART2 for console, and USART3 is not available in "STM32 Perohperal Support". Let me see the DS for STM32F412ZG as STM chips cannot route any signal to any GPIO ;-)

Here is DS for STM32F412ZG: [2] https://www.st.com/resource/en/datasheet/stm32f412zg.pdf.

Table 9. STM32F412xE/G pin definition (page 49/202) contains function to pin map versus used chip package. Looking back at [1] NUCLEO board uses LQFP144 package. We have:

  • LQFP144.45, PC5, USART3_RX.
  • LQFP144.69, PB10, USART3_TX.
  • LQFP144.70, PB11, USART3_RX.
  • LQFP144.77, PD8, USART3_TX.
  • LQFP144.78, PD9, USART3_RX.
  • LQFP144.111, PC10, USART3_TX.
  • LQFP144.112, PC11, USART3_RX.
  • LQFP144.36, PA2, USART2_TX.
  • LQFP144.37, PA3, USART2_RX.
  • LQFP144.119, PD5, USART2_TX.
  • LQFP144.122, PD6, USART2_RX.

Table 11. STM32F412xE/G alternate functions (page 66/202) shows altenrate function codes: AF7 for SPI3/I2S3/USART1/USART2/USART3, AF8 for DFSDM1/USART3/USART6/CAN1.

That confirms we can replace USART2_RX:PD6->PA3 and USART2_TX:PD5->PA2 as proposed in the patch.

But STM removed schematics from DS in order to make things simple for everyone on top of no gpio-mux and restricted pins routing in their MCUs. Call me whatever you like but ESP breaks the bank here with their any-function-to-any-pin :D

According to [1] ST-LINK CDC is at USART3_TX=PD8, USART3_RX=PD9 and we cannot route USART2 over there.

We probably will have to enable USART3 to get console over ST-LINK.

Let me see the physical board how stuff is connected. I found the schematics here: [3] https://www.st.com/resource/en/schematic_pack/nucleo_144pins_sch.zip. Luckily PDF is included :-)

Following the license [4] www.st.com/opla we have confirmation that STLK_RX uses only PD8 pin of USART3_TX, and STLK_TX uses only PD9 pin of USART3_RX.

shot-2026-04-20_20-12-08 shot-2026-04-20_20-13-05

PA2 is used as RMII_MDIO, PA3 is routed CN9.1, PD5 is routed to CN9.6 and CN11.41, PD6 is routed to CN9.4 and CN11.43, which exhausts possible use of USART2 as ST-LINK connection.

The only was to have NuttX console on STM32-NUCLEO-F412ZG's ST-LINK is to use USART3 and configure for:

  • STLK_RX uses only PD8 pin of USART3_TX.
  • STLK_TX uses only PD9 pin of USART3_RX.

Copy link
Copy Markdown
Contributor

@cederom cederom left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @aviralgarg05 ! :-)

The only way to have NuttX console on STM32-NUCLEO-F412ZG's ST-LINK is to use USART3 and configure for:

  • STLK_RX uses only PD8 pin of USART3_TX.
  • STLK_TX uses only PD9 pin of USART3_RX.

@github-actions github-actions Bot added Area: Documentation Improvements or additions to documentation Arch: arm Issues related to ARM (32-bit) architecture Size: S The size of the change in this PR is small and removed Size: XS The size of the change in this PR is very small labels Apr 21, 2026
Enable USART3 support for STM32F412 and use it as the default NUCLEO-F412ZG nsh console path.

The ST-LINK virtual COM port on this board is wired to USART3 on PD8/PD9. Restore USART2 to its header-pin routing, switch the nsh defconfig to USART3, and update the board documentation to match the shipped solder-bridge configuration described in issue apache#17722.

Signed-off-by: aviralgarg05 <gargaviral99@gmail.com>
@aviralgarg05 aviralgarg05 force-pushed the fix/issue-17722-nucleo-f412zg-stlink-console branch from 437d53c to 8d0f4d8 Compare April 21, 2026 04:42
@cederom
Copy link
Copy Markdown
Contributor

cederom commented Apr 21, 2026

Works now! Great work @aviralgarg05 !! =)

% uname -a
FreeBSD hexagon 14.4-RELEASE-p1 FreeBSD 14.4-RELEASE-p1 GENERIC amd64

% git checkout aviralgarg05/fix/issue-17722-nucleo-f412zg-stlink-console
HEAD is now at 8d0f4d81c0e boards/arm/stm32: switch nucleo-f412zg console to USART3 VCP


hexagon% git log -1
commit 8d0f4d81c0eb25bb6dc65a54f16893ef4876bbac (HEAD, aviralgarg05/fix/issue-17722-nucleo-f412zg-stlink-console)
Author: aviralgarg05 <gargaviral99@gmail.com>
Date:   Tue Apr 21 10:12:17 2026 +0530

    boards/arm/stm32: switch nucleo-f412zg console to USART3 VCP

    Enable USART3 support for STM32F412 and use it as the default NUCLEO-F412ZG nsh console path.

    The ST-LINK virtual COM port on this board is wired to USART3 on PD8/PD9. Restore USART2 to its header-pin routing, switch the nsh defconfig to USART3, and update the board documentation to match the shipped solder-bridge configuration described in issue #17722.

    Signed-off-by: aviralgarg05 <gargaviral99@gmail.com>


% gmake clean distclean -j; ./tools/configure.sh -B nucleo-f412zg:nsh && gmake -j
NuttX has not been configured!
NuttX has not been configured!
To configure the project:
To configure the project:
  tools/configure.sh <config>
  tools/configure.sh <config>
For a list of available configurations:
For a list of available configurations:
  tools/configure.sh -L
  tools/configure.sh -L
  Copy files
  Select CONFIG_HOST_BSD=y
  Refreshing...
(..)
#
# configuration written to .config
#
Create version.h
LN: platform/board to /XXX/nuttx/pr/nuttx-apps.git/platform/dummy
Register: nsh
Register: dd
Register: sh
CC:  pthread/pthread_setname_np.c In file included from chip/stm32_flash.c:40:
chip/stm32f20xxf40xx_flash.c:53:4: warning: #warning "Default Flash Configuration Used - See Override Flash Size Designator" [-Wcpp]
   53 | #  warning "Default Flash Configuration Used - See Override Flash Size Designator"
      |    ^~~~~~~
CC:  pthread/pthread_getname_np.c chip/stm32_gpio.c:44:11: note: '#pragma message: CONFIG_STM32_USE_LEGACY_PINMAP will be deprecated migrate board.h see tools/stm32_pinmap_tool.py'
   44 | #  pragma message "CONFIG_STM32_USE_LEGACY_PINMAP will be deprecated migrate board.h see tools/stm32_pinmap_tool.py"
      |           ^~~~~~~
LD: nuttx
Memory region         Used Size  Region Size  %age Used
           flash:         70 KB         1 MB      6.84%
            sram:        8024 B       256 KB      3.06%
CP: nuttx.hex
CP: nuttx.bin


% openocd -f  interface/stlink.cfg -f target/stm32f4x.cfg -c 'program nuttx.bin 0x08000000; reset run; exit'
Open On-Chip Debugger 0.12.0
Licensed under GNU GPL v2
For bug reports, read
	http://openocd.org/doc/doxygen/bugs.html
Info : auto-selecting first available session transport "hla_swd". To override use 'transport select <transport>'.
Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD
Info : clock speed 2000 kHz
Info : STLINK V2J45M30 (API v2) VID:PID 0483:374B
Info : Target voltage: 3.273594
Info : [stm32f4x.cpu] Cortex-M4 r0p1 processor detected
Info : [stm32f4x.cpu] target has 6 breakpoints, 4 watchpoints
Info : starting gdb server for stm32f4x.cpu on 3333
Info : Listening on port 3333 for gdb connections
Info : Unable to match requested speed 2000 kHz, using 1800 kHz
Info : Unable to match requested speed 2000 kHz, using 1800 kHz
[stm32f4x.cpu] halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0x08000996 msp: 0x20002358
Info : Unable to match requested speed 8000 kHz, using 4000 kHz
Info : Unable to match requested speed 8000 kHz, using 4000 kHz
** Programming Started **
Info : device id = 0x30006441
Info : flash size = 1024 KiB
** Programming Finished **
Info : Unable to match requested speed 2000 kHz, using 1800 kHz
Info : Unable to match requested speed 2000 kHz, using 1800 kHz


% cu -l /dev/cuaU0 -s 115200
Connected

nsh> uname -a
NuttX 10.4.0 8d0f4d81c0e Apr 21 2026 20:05:22 arm nucleo-f412zg
nsh> ?
help usage:  help [-v] [<cmd>]

    .           cd          expr        mv          usleep      unset
    [           cp          false       printf      source      uptime
    ?           cmp         help        pwd         test        watch
    alias       dirname     hexdump     rm          time        xd
    unalias     dmesg       ls          rmdir       true
    basename    echo        mkdir       set         truncate
    break       exec        mkrd        kill        uname
    cat         exit        mount       sleep       umount

Builtin Apps:
    dd     nsh    sh

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Arch: arm Issues related to ARM (32-bit) architecture Area: Documentation Improvements or additions to documentation Board: arm Size: S The size of the change in this PR is small

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEATURE] nucleo-f412zg reroute uart console to stlink.

4 participants