Skip to main content
jumman_JHINGA
Senior III
November 3, 2025
Question

USART6 (PF13/PF14) on STM32MP257-DK - /dev/ttySTM6 never appears; SSH broke

  • November 3, 2025
  • 4 replies
  • 417 views

Hello ST community,

I’m an embedded software beginner working with the STM32MP257-DK board and OpenSTLinux (Yocto). I need help getting USART6 working on the external GPIO connector (PF13 = TX, PF14 = RX — CN5 pins). I have rebuilt device trees and copied DTBs to the board, but the USART6 device never appears in the running system (/dev/ttySTM6), and at one point my Ethernet/SSH stopped working after applying a DTB change.

I will be blunt: I have spent many hours following suggestions, debugging, and fixing syntax errors in DTS files. I may be missing one critical detail about how ST maps peripherals on the DK board or about kernel bindings. I have documented exactly what I tried and the exact outputs — please read fully before replying. I am a beginner; please do not assume I know advanced DT or U-Boot internals.


Environment / versions

  • Board: STMicroelectronics STM32MP257F-DK (discovery/“DK” board)

  • Host SDK: SDK-x86_64-stm32mp2-openstlinux-6.6-yocto-scarthgap-mpu-v25.06.11

  • Kernel source / sources used: linux-stm32mp-6.6.78-stm32mp-r2-r0 (from provided sources set)

  • Yocto/OpenSTLinux release: 5.0.8-openstlinux-6.6-yocto-scarthgap-mpu-v25.06.11 (as shown at boot)

  • Toolchain: aarch64-linux-gnu- (CROSS_COMPILE used when building dtbs)


Goal

Enable UART6 on PF13 / PF14 (the CN5 GPIO connector) so the kernel instantiates ttySTM6 (device node /dev/ttySTM6) and make it usable from Linux (minicom / echo test).


What I changed and why

  1. I added pinmux entries for USART6 (PF13, PF14) into the pinctrl include arch/arm64/boot/dts/st/stm32mp25xxai-pinctrl.dtsi because I could not find existing usart6_pins_a labels there.

    The block I added (conceptually — exact content below) defines:

    • usart6_pins_a (pins1: PF13 AF7 TX, pins2: PF14 AF7 RX)

    • usart6_idle_pins_a and usart6_sleep_pins_a set to ANALOG for low-power states

  2. I edited the board DTS to enable USART6. Important files edited:

    • arch/arm64/boot/dts/st/stm32mp257f-ev1.dts (I tried EV1 earlier)

    • Realized board boots DK DTB (st,stm32mp257f-dk), so I also applied the same changes to arch/arm64/boot/dts/st/stm32mp257f-dk.dts.

    • In board DTS I added:

&usart6 {
 pinctrl-names = "default", "idle", "sleep";
 pinctrl-0 = <&usart6_pins_a>;
 pinctrl-1 = <&usart6_idle_pins_a>;
 pinctrl-2 = <&usart6_sleep_pins_a>;
 uart-has-rtscts;
 status = "okay";
};
  • I tried a more invasive approach earlier where I attempted to declare the serial@40380000 node under &soc (to create the peripheral node), but this caused parsing errors and I reverted to just overriding &usart6 in the board DTS.
  • I rebuilt device trees:
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- dtbs​

— verified DTC arch/arm64/boot/dts/st/stm32mp257f-dk.dtb finished.

  • I copied the new DTB to the board with scp into /boot/ (I also checked /boot/extlinux/extlinux.conf when advised).

  • I rebooted the board after copying DTB.

Things I fixed while debugging (common gotchas I ran into)

  • Fixed many dtc syntax issues:

    • Trimmed BOMs (sed -i '1s/^\xEF\xBB\xBF//' file),

    • Converted CRLF to LF (dos2unix),

    • Removed an extra stray } that caused dtc to fail,

    • Fixed node scoping: learned that label: node { ... }; defines a node and &label { ... }; is a reference — you cannot define &label inside the same scope as the label definition.

  • Validated device tree compile with:

dtc -I dts -O dtb -o /dev/null arch/arm64/boot/dts/st/stm32mp257f-dk.dts
  • Verified which DTB is actually used by bootloader by checking:
strings /proc/device-tree/compatible
cat /proc/device-tree/model​

Output shows st,stm32mp257f-dk (so the DK DTS is the important one).

Exact commands I ran (representative)

On host (kernel tree top):

# check and edit the DK DTS
sudo nano arch/arm64/boot/dts/st/stm32mp257f-dk.dts

# add pinctrl to pinctrl dtsi
sudo nano arch/arm64/boot/dts/st/stm32mp25xxai-pinctrl.dtsi

# syntax check and compile dtb
dtc -I dts -O dtb -o /dev/null arch/arm64/boot/dts/st/stm32mp257f-dk.dts
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- dtbs

# copy dtb to board
scp arch/arm64/boot/dts/st/stm32mp257f-dk.dtb root@192.168.7.1:/boot/

# reboot board
ssh root@192.168.7.1 'sync; reboot'

On target (after reboot):

strings /proc/device-tree/compatible
dmesg | grep -i usart
dmesg | grep -i uart
ls /dev/ttySTM*
grep -R "40380000" /sys/firmware/devicetree/base/ 2>/dev/null
cat /sys/firmware/devicetree/base/soc/serial@40380000/status 2>/dev/null || true

What I observed (actual output excerpts)

  • Boot banner via minicom shows:

ST OpenSTLinux - Weston - (A Yocto Project Based Distro) 5.0.8-openstlinux-6.6-yocto-scarthgap-mpu-v25.06.11 stm32mp2-e3-cc-dd ttySTM0
  • Running strings /proc/device-tree/compatible:
st,stm32mp257f-dk
st,stm32mp257
  • dmesg | grep -i usart shows several usart lines but no USART6:
STM32 USART driver initialized
stm32-usart 40220000.serial: ttySTM1 at MMIO 0x40220000 ...
stm32-usart 40330000.serial: ttySTM2 at MMIO 0x40330000 ...
stm32-usart 400e0000.serial: ttySTM0 at MMIO 0x400e0000 ...​
  • ls /dev/ttySTM* shows:
/dev/ttySTM0 /dev/ttySTM1 (sometimes /dev/ttySTM2)​
  • but NOT /dev/ttySTM6.

  • At one point, after I deployed a modified EV1 DTB, SSH stopped working (no network), but serial console still worked. That told me the DTB I made must have broken Ethernet pinmux/regulator or that I deployed the wrong DTB to the boot partition path.

Exact DTS / pinctrl changes I made (copyable)

pinctrl (added to stm32mp25xxai-pinctrl.dtsi)

 

/* USART6 PF13 (TX) PF14 (RX) */
usart6_pins_a: usart6-0 {
 pins1 {
 pinmux = <STM32_PINMUX('F', 13, AF7)>; /* TX */
 bias-disable;
 drive-push-pull;
 slew-rate = <1>;
 };
 pins2 {
 pinmux = <STM32_PINMUX('F', 14, AF7)>; /* RX */
 bias-disable;
 };
};

usart6_idle_pins_a: usart6-idle-0 {
 pins {
 pinmux = <STM32_PINMUX('F', 13, ANALOG)>,
 <STM32_PINMUX('F', 14, ANALOG)>;
 };
};

usart6_sleep_pins_a: usart6-sleep-0 {
 pins {
 pinmux = <STM32_PINMUX('F', 13, ANALOG)>,
 <STM32_PINMUX('F', 14, ANALOG)>;
 };
};

board DTS (added to stm32mp257f-dk.dts)

&usart6 {
 pinctrl-names = "default", "idle", "sleep";
 pinctrl-0 = <&usart6_pins_a>;
 pinctrl-1 = <&usart6_idle_pins_a>;
 pinctrl-2 = <&usart6_sleep_pins_a>;
 uart-has-rtscts;
 status = "okay";
};

Expected behavior vs actual behavior

  • Expected: After replacing DTB and rebooting, kernel binds driver to USART6, creates /dev/ttySTM6, and I am able to stty -F /dev/ttySTM6 115200 and send/receive data with minicom or simple echo tests.

  • Actual: /dev/ttySTM6 not created; kernel enumerates other UARTs (ttySTM0, ttySTM1, ttySTM2) only. When I deployed an edited EV1 DTB previously, Ethernet stopped coming up and SSH failed though serial console remained alive. After restoring working DTB the board network worked again.

What I tried to debug (commands & checks)

  • dmesg | grep -i usart

  • ls /dev/ttySTM*

  • strings /proc/device-tree/compatible

  • grep -R usart6 arch/arm64/boot/dts/st/

  • dtc -I dts -O dtb -o /dev/null ... (checked syntax)

  • sed -n '837,857p' ... | cat -A to find stray braces and CR characters

  • dos2unix, sed to remove BOM

  • Rebuilt dtbs and copied stm32mp257f-dk.dtb to /boot/ and rebooted

  • Created (but not successfully applied) a small overlay suggestion — looking for guidance on best practice

Specific request to ST staff / community experts

Please explain — in the simplest possible terms for a beginner — the minimal set of changes I must make so that the kernel recognizes USART6 on the DK board and creates /dev/ttySTM6. If possible, please:

  • Confirm whether USART6 is physically available on the DK revision (and confirm the connector/pins),

  • Provide the correct pinctrl and clock symbols and a minimal delta patch or overlay that will definitely work on this board and kernel version,

  • If there is any kernel config, u-boot, or OP-TEE/TFA constraint that may prevent enabling that UART, point it out.


I want to be explicit: I don’t just want theory — I want a tested, minimal patch or overlay and exact commands to deploy it safely (without breaking Ethernet), plus a short checklist to verify that the new DTB is used by the board after reboot.

Thank you. I’m available to attach the two DTBs and the dmesg output. I appreciate concise, explicit instructions — the more stepwise, the better for someone who is still learning.

 

— Jumman

4 replies

jumman_JHINGA
Senior III
November 5, 2025

waiting for suggestions guys....

PatrickF
ST Employee
November 7, 2025

Hi @jumman_JHINGA 

I'm not expert in SW, but did you update both uBoot and Kernel DTS similarly ?
see also https://wiki.st.com/stm32mpu/wiki/How_to_compile_the_device_tree_with_the_Developer_Package 

Regards.

In order to give better visibility on the answered topics, please click on 'Best Answer' on the reply which solved your issue or answered your question.Tip of the day: Try Sidekick STM32 AI agent
jumman_JHINGA
Senior III
November 11, 2025

Thanks @PatrickF  ill go through with that documentation.. and ill let you know..

Duc
Senior
November 7, 2025

Hi @jumman_JHINGA,

Why is it necessary to modify the stm32mp25xxai-pinctrl.dtsi file when the stm32mp25-pinctrl.dtsi file already includes the implementation?

jumman_JHINGA
Senior III
November 11, 2025

i was just doing trial & error.. first i tried changing UART6 status "disabled" to "okay" in the DTS .. it didnt work... so by the help of chatGPT i got to know that i could change this also if usart6 is is getting  show up on the target.

Lead
January 29, 2026

Hi @jumman_JHINGA  and @PatrickF 

Does &usart6 work as early boot debug for you?

For example, if you assign this to your tf-a device tree

	aliases{
		serial0 = &usart6;
	};

	chosen{
		stdout-path = "serial0:115200n8";
	};

 

I'm having the same issue as you do.

STM32MP151AAC3 custom board with STM32-OS as operating system: https://github.com/DanielMartensson/STM32-ComputerSTM32MP257FAK3 custom board with STM64-OS as operating system: https://github.com/DanielMartensson/STM64-Computer
jumman_JHINGA
Senior III
January 30, 2026

Hii @DMårt 

Im was using latest version RIF don't allow to use UART6 at A35 ... because it assigned to M33.. 

 

First issue that's ttySTM* of UART6 was getting shown up..  that i resolved by changing aliase name Serial0 to Serial6 for UART6.

 

After second issue I was facing that ... using directly UART6 interface was causing kernel panic. I resolved that issue by disabling M33 firmware loading. 

Lead
January 30, 2026

Thank you for your reply @jumman_JHINGA 

So to summarize:

  • Change "Serial0" to "Serial6" in alias
  • Disable firmware loading of M33 in Linux 

Some questions:

  • So when you're booting your board, then you could see USART6 as early boot (debug console)? Can you post a dump of your debug console?
  • Do you mind if you could share your device tree of TF-a, u-boot, op-tee and kernel? :)
  • What is TIF? Do you mean TF-A?
STM32MP151AAC3 custom board with STM32-OS as operating system: https://github.com/DanielMartensson/STM32-ComputerSTM32MP257FAK3 custom board with STM64-OS as operating system: https://github.com/DanielMartensson/STM64-Computer
Visitor II
June 10, 2026

Hello, have you solved the problem yet? if not, then I will share how do I fix it because I was facing the same problem here.

My current solution is disabled the M33, activate the USART6 “okay” on device tree on Linux kernel source following the documentation and recompiled it with “make dtbs” then scp to the board (How to cross-compile with the Developer Package). Currently I use the latest version which is
stm32mp-openstlinux-6.6-yocto-scarthgap-mpu-v26.02.18.
------------------------------------------------------------------------------------
Device Tree:
&usart6 {
    pinctrl-names = "default", "idle", "sleep";
    pinctrl-0 = <&usart6_pins_a>;
    pinctrl-1 = <&usart6_idle_pins_a>;
    pinctrl-2 = <&usart6_sleep_pins_a>;
    uart-has-rtscts;
    status = "okay";
};

----------------------------------------------------------------------
this was mentioned by ST employee:

I've seen several posts on the use of the USART6 and after discussion with team members, the USART6 is used by the UCSI firmware running on the cortex M33. Therefore, I think you have concurrent access (A35 + M33) to the same USART + its clock. If you do not need USB type-C on this board, you either try to stop or disable the service that handles the M33 firmware:

systemctl stop st-m33firmware-load.service

or

systemctl disable st-m33firmware-load.service
-------------------------------------------------------------------

after I disabled the M33 I can run:


root@stm32mp2-e3-d0-50:~# stty -F /dev/ttySTM1 ispeed 115200
root@stm32mp2-e3-d0-50:~# stty -F /dev/ttySTM1 speed
115200
 

Hello, I was facing the same problem, my current solution is disabled the M33, activate the USART6 “okay” on device tree on Linux kernel source following the documentation and recompiled it with “make dtbs” then scp to the board (How to cross-compile with the Developer Package). Currently I use the latest version which is
stm32mp-openstlinux-6.6-yocto-scarthgap-mpu-v26.02.18.

Device Tree:
&usart6 {
    pinctrl-names = "default", "idle", "sleep";
    pinctrl-0 = <&usart6_pins_a>;
    pinctrl-1 = <&usart6_idle_pins_a>;
    pinctrl-2 = <&usart6_sleep_pins_a>;
    uart-has-rtscts;
    status = "okay";
};


this was mentioned by ST employee:

I've seen several posts on the use of the USART6 and after discussion with team members, the USART6 is used by the UCSI firmware running on the cortex M33. Therefore, I think you have concurrent access (A35 + M33) to the same USART + its clock. If you do not need USB type-C on this board, you either try to stop or disable the service that handles the M33 firmware:

systemctl stop st-m33firmware-load.service

or

systemctl disable st-m33firmware-load.service


after I disabled the M33 I can run:


root@stm32mp2-e3-d0-50:~# stty -F /dev/ttySTM1 ispeed 115200
root@stm32mp2-e3-d0-50:~# stty -F /dev/ttySTM1 speed
115200
root@stm32mp2-e3-d0-50:~# echo test > /dev/ttySTM1

I can run the echo test as well when I connected my Arduino UNO UART (RX,TX,GND) to the board to test if the message was sent from the board.