Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

With uClinux running on the STM32H7, you get the full Linux TCP/IP stack. Userspace POSIX APIs are provided by the uClibc library. Key user-space networking tools and utilities are available from the multi-call busybox. Additional tools and packages, such as for instance the SSH dropbear server, can be built specifically for uClinux. All in all, you have the powerful Linux TCP/IP stack at your disposal.

There is a full-functioning Ethernet device driver available in the kernel tree for the STM32H7 SOM. The device driver is linux/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c configured in the kernel using the CONFIG_DWMAC_STM32 build time option in Device Drivers -> Network device support -> Ethernet driver support -> STMicroelectronics devices -> STM32 DWMAC support.

...

For the run-time configuration of the kernel, Ethernet is enabled in rootfs.dts.STM32H7 in projects/rootfs as follows:

Code Block
 &mac {
        status = "okay";
        pinctrl-0       = <&ethernet_rmii>;
        pinctrl-names   = "default";
        phy-mode        = "rmii";
        phy-handle      = <&phy0>;

        mdio0 {
                #address-cells = <1>;
                #size-cells = <0>;
                compatible = "snps,dwmac-mdio";
                phy0: ethernet-phy@0 {
                        reg = <1>;
                };
        };
};

This will register a platform device for the STM32H7 SOM Ethernet controller with the Ethernet driver.

The Linux project provided by Emcraft in the distribution (refer to projects/rootfs) and installed on each shipping module and kit includes the TCP/IP stack and various network related capabilities. The following snapshot shows the full Linux bootstrap sequence from power-on to the Linux shell:

Code Block
U-Boot SPL 2019.04- (Jul 07 2023 - 11:10:24 +0000)
Hit 's' key to enter spl shell:
Trying to boot from SPI


U-Boot 2019.04- (Jul 07 2023 - 11:10:24 +0000)

Model: STMicroelectronics STM32H7 SOM
DRAM:  64 MiB
SF: Detected n25q512ax3 with page size 256 Bytes, erase size 4 KiB, total 64 MiB
Flash: 128 KiB
MMC:   STM32 SDMMC2: 0
Loading Environment from UBI... ubi0: default fastmap pool size: 256
ubi0: default fastmap WL pool size: 128
ubi0: attaching mtd2
ubi0: scanning is finished
ubi0: attached mtd2 (name "system", size 23 MiB)
ubi0: PEB size: 4096 bytes (4 KiB), LEB size: 3968 bytes
ubi0: min./max. I/O unit sizes: 1/256, sub-page size 1
ubi0: VID header offset: 64 (aligned 64), data offset: 128
ubi0: good PEBs: 5888, bad PEBs: 0, corrupted PEBs: 0
ubi0: user volume: 5, internal volumes: 1, max. volumes count: 23
ubi0: max/mean erase counter: 2/1, WL threshold: 4096, image sequence number: 0
ubi0: available PEBs: 1067, total reserved PEBs: 4821, PEBs reserved for bad 
PEB handling: 0
Read 16384 bytes from volume env1 to d396f620
Read 16384 bytes from volume env2 to d3973640
OK
In:    serial
Out:   serial
Err:   serial
No size specified -> Using max size (2099072)
Read 2099072 bytes from volume splash to d0c00000
Net:   eth0: ethernet@40028000
Hit any key to stop autoboot:  0
Booting Image #1
No size specified -> Using max size (8392320)
Read 8392320 bytes from volume rtos1 to d0c00000
## Booting kernel from Legacy Image at d0c00000 ...
   Image Name:   Linux-5.15.67
   Image Type:   ARM Linux Multi-File Image (uncompressed)
   Data Size:    6447130 Bytes = 6.1 MiB
   Load Address: d0008000
   Entry Point:  d0008001
   Contents:
      Image 0: 6432192 Bytes = 6.1 MiB
      Image 1: 14926 Bytes = 14.6 KiB
   Verifying Checksum ... OK
## Loading init Ramdisk from multi component Legacy Image at d0c00000 ...
## Flattened Device Tree from multi component Image at D0C00000
   Booting using the fdt at 0xd122260c
   Loading Multi-File Image ... OK
   Loading Ramdisk to d3972000, end d3975a4e ... OK
   Loading Device Tree to d396b000, end d3971a4d ... OK

Starting kernel ...

[    0.000000] Booting Linux on physical CPU 0x0
[    0.000000] Linux version 5.15.67 (sasha@workbench.emcraft.com) 
(arm-none-eabi-gcc (GNU Arm Embedded Toolchain 
10.3-2021.10) 10.3.1 20210824 (release), GNU ld (GNU Arm Embedded Toolchain 
10.3-2021.10) 2.36.1.20210621) 
#2 PREEMPT Fri Jul 7 11:02:11 UTC 2023
[    0.000000] CPU: ARMv7-M [411fc271] revision 1 (ARMv7M), cr=00000000
[    0.000000] CPU: PIPT / VIPT nonaliasing data cache, PIPT instruction cache
[    0.000000] OF: fdt: Machine model: STM32H7 SOM Starter Kit
[    0.000000] printk: bootconsole [earlycon0] enabled
[    0.000000] printk: debug: ignoring loglevel setting.
[    0.000000] Reserved memory: created DMA memory pool at 0xd3f00000, size 1 MiB
[    0.000000] OF: reserved mem: initialized node dmapool, compatible id 
shared-dma-pool
[    0.000000] Zone ranges:
[    0.000000]   Normal   [mem 0x00000000d0000000-0x00000000d3ffffff]
[    0.000000] Movable zone start for each node
[    0.000000] Early memory node ranges
[    0.000000]   node   0: [mem 0x00000000d0000000-0x00000000d3bfffff]
[    0.000000]   node   0: [mem 0x00000000d3c00000-0x00000000d3ffffff]
[    0.000000] Initmem setup node 0 [mem 0x00000000d0000000-0x00000000d3ffffff]
[    0.000000] pcpu-alloc: s0 r0 d32768 u32768 alloc=1*32768
[    0.000000] pcpu-alloc: [0] 0
[    0.000000] Built 1 zonelists, mobility grouping on.  Total pages: 16256
[    0.000000] Kernel command line: console=ttySTM0,115200 earlyprintk 
consoleblank=0 panic=3 ignore_loglevel 
ip=172.17.0.66:172.17.0.1::::eth0:off
[    0.000000] Unknown kernel command line parameters "consoleblank=0 
ip=172.17.0.66:172.17.0.1::::eth0:off", 
will be passed to user space.
[    0.000000] Dentry cache hash table entries: 8192 (order: 3, 32768 bytes, 
linear)
[    0.000000] Inode-cache hash table entries: 4096 (order: 2, 16384 bytes, 
linear)
[    0.000000] mem auto-init: stack:off, heap alloc:off, heap free:off
[    0.000000] Memory: 54356K/65536K available (2472K kernel code, 313K rwdata, 
1100K rodata, 2240K init, 122K bss, 
11180K reserved, 0K cma-reserved)
[    0.000000] SLUB: HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
[    0.000000] rcu: Preemptible hierarchical RCU implementation.
[    0.000000] rcu:     RCU event tracing is enabled.
[    0.000000]  Trampoline variant of Tasks RCU enabled.
[    0.000000] rcu: RCU calculated value of scheduler-enlistment delay is 10 
jiffies.
[    0.000000] NR_IRQS: 16, nr_irqs: 16, preallocated irqs: 16
[    0.000000] /soc/interrupt-controller@58000000: bank0
[    0.000000] /soc/interrupt-controller@58000000: bank1
[    0.000000] /soc/interrupt-controller@58000000: bank2
[    0.000000] clocksource: arm_system_timer: mask: 0xffffff max_cycles: 
0xffffff, max_idle_ns: 29863442 ns
[    0.000000] ARM System timer initialized as clocksource
[    0.000012] sched_clock: 32 bits at 200MHz, resolution 5ns, wraps every 
10737418237ns
[    0.007939] timer@40000c00: STM32 sched_clock registered
[    0.013294] Switching to timer-based delay loop, resolution 5ns
[    0.019243] timer@40000c00: STM32 delay timer registered
[    0.024598] clocksource: timer@40000c00: mask: 0xffffffff max_cycles: 
0xffffffff, max_idle_ns: 9556302233 ns
[    0.034508] /soc/timer@40000c00: STM32 clockevent driver initialized (32 bits)
[    0.042665] Calibrating delay loop (skipped), value calculated using timer 
frequency.. 400.00 
BogoMIPS (lpj=2000000)
[    0.053397] pid_max: default: 4096 minimum: 301
[    0.058758] Mount-cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
[    0.066352] Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes, 
linear)
[    0.082295] rcu: Hierarchical SRCU implementation.
[    0.089681] devtmpfs: initialized
[    0.118466] DMA: default coherent area is set
[    0.122921] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff,
 max_idle_ns: 19112604462750000 ns
[    0.133076] pinctrl core: initialized pinctrl subsystem
[    0.143231] NET: Registered PF_NETLINK/PF_ROUTE protocol family
[    0.180330] stm32h743-pinctrl soc:pin-controller@58020000: GPIOA bank added
[    0.189425] stm32h743-pinctrl soc:pin-controller@58020000: GPIOB bank added
[    0.198466] stm32h743-pinctrl soc:pin-controller@58020000: GPIOC bank added
[    0.207591] stm32h743-pinctrl soc:pin-controller@58020000: GPIOD bank added
[    0.216689] stm32h743-pinctrl soc:pin-controller@58020000: GPIOE bank added
[    0.225964] stm32h743-pinctrl soc:pin-controller@58020000: GPIOF bank added
[    0.235219] stm32h743-pinctrl soc:pin-controller@58020000: GPIOG bank added
[    0.244763] stm32h743-pinctrl soc:pin-controller@58020000: GPIOH bank added
[    0.254189] stm32h743-pinctrl soc:pin-controller@58020000: GPIOI bank added
[    0.263413] stm32h743-pinctrl soc:pin-controller@58020000: GPIOJ bank added
[    0.272836] stm32h743-pinctrl soc:pin-controller@58020000: GPIOK bank added
[    0.279930] stm32h743-pinctrl soc:pin-controller@58020000: Pinctrl 
STM32 initialized
[    0.322332] stm32-mdma 52000000.dma-controller: STM32 MDMA driver registered
[    0.332046] pps_core: LinuxPPS API ver. 1 registered
[    0.337097] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo 
Giometti <
 giometti@linux.it>
[    0.346595] PTP clock support registered
[    0.355718] clocksource: Switched to clocksource timer@40000c00
[    0.370121] NET: Registered PF_INET protocol family
[    0.375946] IP idents hash table entries: 2048 (order: 2, 16384 bytes, linear)
[    0.386209] tcp_listen_portaddr_hash hash table entries: 512 (order: 0, 
4096 bytes, linear)
[    0.394752] Table-perturb hash table entries: 65536 (order: 6, 262144 bytes, 
linear)
[    0.403085] TCP established hash table entries: 1024 (order: 0, 4096 bytes, 
linear)
[    0.411156] TCP bind hash table entries: 1024 (order: 0, 4096 bytes, linear)
[    0.418582] TCP: Hash tables configured (established 1024 bind 1024)
[    0.425522] UDP hash table entries: 256 (order: 0, 4096 bytes, linear)
[    0.432493] UDP-Lite hash table entries: 256 (order: 0, 4096 bytes, linear)
[    0.440671] NET: Registered PF_UNIX/PF_LOCAL protocol family
[    0.456203] workingset: timestamp_bits=30 max_order=14 bucket_order=0
[    0.523138] io scheduler mq-deadline registered
[    0.535965] io scheduler kyber registered
[    0.557198] STM32 USART driver initialized
[    0.562753] stm32-usart 40011000.serial: interrupt mode for rx (no dma)
[    0.576839] stm32-usart 40011000.serial: interrupt mode for tx (no dma)
[    0.583632] 40011000.serial: ttySTM0 at MMIO 0x40011000 (irq = 30, base_baud = 
12500000) is a stm32-usart
[    0.609685] printk: console [ttySTM0] enabled
[    0.609685] printk: console [ttySTM0] enabled
[    0.638237] printk: bootconsole [earlycon0] disabled
[    0.638237] printk: bootconsole [earlycon0] disabled
[    0.667402] stm32-dwmac 40028000.ethernet: IRQ eth_wake_irq not found
[    0.672549] stm32-dwmac 40028000.ethernet: IRQ eth_lpi not found
[    0.696974] stm32-dwmac 40028000.ethernet: PTP uses main clock
[    0.706411] stm32-dwmac 40028000.ethernet: User ID: 0x31, Synopsys ID: 0x42
[    0.712088] stm32-dwmac 40028000.ethernet:   DWMAC4/5
[    0.737006] stm32-dwmac 40028000.ethernet: DMA HW capability register 
supported
[    0.742966] stm32-dwmac 40028000.ethernet: RX Checksum Offload Engine 
supported
[    0.766116] stm32-dwmac 40028000.ethernet: TX Checksum insertion supported
[    0.771656] stm32-dwmac 40028000.ethernet: Wake-Up On Lan supported
[    0.786546] stm32-dwmac 40028000.ethernet: TSO supported
[    0.790569] stm32-dwmac 40028000.ethernet: Enable RX Mitigation via 
HW Watchdog Timer
[    0.818708] stm32-dwmac 40028000.ethernet: device MAC address b6:9c:51:c9:a2:
3f
[    0.824692] stm32-dwmac 40028000.ethernet: Enabled L3L4 Flow TC (entries=2)
[    0.846095] stm32-dwmac 40028000.ethernet: Enabled RFS Flow TC (entries=8)
[    0.851667] stm32-dwmac 40028000.ethernet: Using 32 bits DMA width
[    1.153156] Unpacking initramfs...
[    1.155275] Initramfs unpacking failed: invalid magic at start of compressed 
archive
[    1.163609] Freeing initrd memory: 16K
[    1.176665] i2c_dev: i2c /dev entries driver
[    1.182850] mmci-pl18x 52007000.mmc: failed to get pinctrl
[    2.207936] NET: Registered PF_INET6 protocol family
[    2.217643] Segment Routing with IPv6
[    2.220347] In-situ OAM (IOAM) with IPv6
[    2.224219] sit: IPv6, IPv4 and MPLS over IPv4 tunneling driver
[    2.233229] NET: Registered PF_PACKET protocol family
[    2.251070] Freeing unused kernel image (initmem) memory: 2240K
[    2.255676] This architecture does not have kernel memory protection.
[    2.262220] Run /init as init process
[    2.265995]   with arguments:
[    2.268703]     /init
[    2.270976]   with environment:
[    2.274056]     HOME=/
[    2.276533]     TERM=linux
[    2.279125]     consoleblank=0
[    2.282109]     ip=172.17.0.66:172.17.0.1::::eth0:off
init started: BusyBox v1.24.2 (2023-07-07 11:01:57 UTC)
[38] Jan 01 00:00:02 Running in background
/ # [    2.527312] stm32-dwmac 40028000.ethernet eth0: PHY [stmmac-0:01] driver 
[SMSC LAN8710/LAN8720] (irq=POLL)
[    2.536356] stm32-dwmac 40028000.ethernet eth0: Register MEM_TYPE_PAGE_POOL 
RxQ-0
[    2.545894] stm32-dwmac 40028000.ethernet eth0: No Safety Features support 
found
[    2.551950] stm32-dwmac 40028000.ethernet eth0: IEEE 1588-2008 Advanced 
Timestamp supported
[    2.561350] stm32-dwmac 40028000.ethernet eth0: registered PTP clock
[    2.568913] stm32-dwmac 40028000.ethernet eth0: configuring for phy/rmii 
link mode
[    4.649596] stm32-dwmac 40028000.ethernet eth0: Link is Up - 100Mbps/Full 
- flow control rx/tx
[    4.657026] IPv6: ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready
/ #

Let's test the TCP/IP stack on the STM32H7-SOM.

From the development host validate that the STM32H7-SOM is visible using ping:

Code Block
$ ping -c 5 172.17.0.66
PING 172.17.0.66 (172.17.0.66) 56(84) bytes of data.
64 bytes from 172.17.0.66: icmp_seq=1 ttl=64 time=1.37 ms
64 bytes from 172.17.0.66: icmp_seq=2 ttl=64 time=0.750 ms
64 bytes from 172.17.0.66: icmp_seq=3 ttl=64 time=0.747 ms
64 bytes from 172.17.0.66: icmp_seq=4 ttl=64 time=0.734 ms
64 bytes from 172.17.0.66: icmp_seq=5 ttl=64 time=0.734 ms

--- 172.17.0.66 ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 4054ms
rtt min/avg/max/mdev = 0.734/0.866/1.369/0.251 ms$

ping the development host from the STM32H7 SOM:

Code Block
/ # ping -c 5 172.17.0.1
PING 172.17.0.1 (172.17.0.1): 56 data bytes
64 bytes from 172.17.0.1: seq=0 ttl=64 time=1.650 ms
64 bytes from 172.17.0.1: seq=1 ttl=64 time=0.884 ms
64 bytes from 172.17.0.1: seq=2 ttl=64 time=0.900 ms
64 bytes from 172.17.0.1: seq=3 ttl=64 time=0.911 ms
64 bytes from 172.17.0.1: seq=4 ttl=64 time=0.909 ms

--- 172.17.0.1 ping statistics ---
5 packets transmitted, 5 packets received, 0% packet loss
round-trip min/avg/max = 0.884/1.050/1.650 ms
/ #

On the target, start the telnetd daemon to allow connections to the STM32H7:

Code Block
 / # ps | grep telnetd
   96 root       388 S    {busybox} telnetd
  101 root       388 S    grep telnetd
/ #

Connect to the target from the development host using telnet. The target is configured to accept the 123 password for root:

Code Block
$ telnet 192.168.88.89
Trying 192.168.88.89...
Connected to 192.168.88.89.
Escape character is '^]'.

(none) login: root
Password:
/ # ls
bin       etc       httpd     lib       proc      sbin tmp       var
dev       hello.ko  init      mnt       root      sys       usr
/ # exit
Connection closed by foreign host.
$ 

The dropbear SSH daemon starts automatically on the target. Verify that dropbear allows secure connections to the target:

Code Block
/ # ps | grep dropbear
   70 root       416 S    dropbear -R
   98 root       388 S    grep dropbear

Connect to the target from the development host using ssh. The first connection takes several seconds to establish as the STM32H7 runs computation-extensive key calculations. Again, enter 123 on the password prompt:

Code Block
$ ssh 
 root@172.17.0.66

 root@172.17.0.66's password:
/ # ls
bin       etc       httpd     lib       proc      sbin      tmp       var
dev       hello.ko  init      mnt       root      sys       usr
/ # # exit
Connection to 172.17.0.66 closed. $

On the target, enable access to the Internet by configuring a default gateway. Note also that the system makes use of the public name server provided by Google:

Code Block
/ # route add default gw 172.17.0.1
/ # cat /etc/resolv.conf
# This configuration makes use of the Google public DNS server.
# If you would like to use something else, replace with the IP
# of your DNS server

nameserver 8.8.8.8
/ #

Use ntpd to synchronize the time on the target with the time provided by a public server:

Code Block
/ # date
Thu Jan  1 00:32:53 UTC 1970
/ # ntpd -p 0.fedora.pool.ntp.org
/ # sleep 5
/ # date
Tue Jul 11 07:03:45 UTC 2023

Use wget to download a file from a remote server:

Code Block
/ # wget ftp://ftp.gnu.org/README
Connecting to ftp.gnu.org (209.51.188.20:21)
README               100% |*******************************|  2748   0:00:00 ETA
/ # 
/ # cat README
This is ftp.gnu.org, the FTP server of the the GNU project.
...

Mount a directory exported by a development host over NFS:

Code Block
/ # mount -o nolock 172.17.0.1:/home/work /mnt/nfs/
/ # ls /mnt/nfs/
arm-v7-linux-uclibceabi-pthreads-20181123.tar.bz2
 .....

Start the HTTP daemon:

Code Block
/ # httpd -h /httpd/html/

From a local host, open a Web browser to the STM32H7-SOM and watch the demo web page provided by the target. The STM32H7-SOM shows the current time and date as well as the list of the currently running processes:

...