Running TCP/IP Stack in Linux Print

 

With uClinux running on the STM32F4, you get the full Linux TCP/IP stack (kernel version 4.2.0). 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 STM32F4. The device driver is linux/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c configured in the kernel using the СONFIG_DWMAC_STM32 build time option in Device Drivers -> Network device support -> Ethernet driver support -> STMicroelectronics devices -> STMicroelectronics 10/100/1000 Ethernet driver -> STMMAC Platform bus support.

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

/*
* Ethernet controller
*/
&mac {
status = "okay";
phy-mode = "rmii";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_mac_rmii>;
};

This will register a platform device for the STM32F4 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 spapshot shows the full Linux boosrap sequence from power-on to the Linux shell:

U-Boot 2010.03-cortexm-2.0.0 (May 12 2016 - 14:15:19)

CPU : STM32F4 (Cortex-M4)
Freqs: SYSCLK=180MHz,HCLK=180MHz,PCLK1=45MHz,PCLK2=90MHz
Board: STM-SOM Rev 2.A, www.emcraft.com
DRAM: 32 MB
Flash: 16 MB
In: serial
Out: serial
Err: serial
Net: STM32_MAC
Hit any key to stop autoboot: 0
## Booting kernel from Legacy Image at c0007fb4 ...
Image Name:   Linux-4.2.0-cortexm-2.0.0
Image Type:   ARM Linux Multi-File Image (uncompressed)
Data Size:    5735620 Bytes =  5.5 MB
Load Address: c0008000
Entry Point:  c0008001
Contents:
Image 0: 5718576 Bytes =  5.5 MB
Image 1: 17032 Bytes = 16.6 kB
Verifying Checksum ... OK
## Flattened Device Tree from multi component Image at C0007FB4
Booting using the fdt at 0xc057c230
Loading Multi-File Image ... OK
OK
Loading Device Tree to c1ff8000, end c1fff287 ... OK

Starting kernel ...

Booting Linux on physical CPU 0x0
Linux version 4.2.0-cortexm-2.0.0 (psl‌@skywanderer.emcraft.com) (gcc version 4.4.1 (Sourcery G++ Lite 2010q1-189) ) #1 Thu May 12 14:57:40 +0400 2016
CPU: ARMv7-M [410fc241] revision 1 (ARMv7M), cr=00000000
CPU: unknown data cache, unknown instruction cache
Machine model: EmCraft Systems STM32F4x9-SOM board
Built 1 zonelists in Zone order, mobility grouping off. Total pages: 8128
Kernel command line: stm32_platform=stm32f4x9-som console=ttyS0,115200 panic=10
ip=172.17.4.206:172.17.0.1:::stm32f4x9-som:eth0:off
PID hash table entries: 128 (order: -3, 512 bytes)
Dentry cache hash table entries: 4096 (order: 2, 16384 bytes)
Inode-cache hash table entries: 2048 (order: 1, 8192 bytes)
Memory: 26684K/32768K available (2271K kernel code, 164K rwdata, 492K rodata, 2652K init, 96K bss, 6084K reserved, 0K cma-reserved)
Virtual kernel memory layout:
vector : 0x00000000 - 0x00001000 ( 4 kB)
fixmap : 0xffc00000 - 0xfff00000 (3072 kB)
vmalloc : 0x00000000 - 0xffffffff (4095 MB)
lowmem : 0xc0000000 - 0xc2000000 ( 32 MB)
.text : 0xc0008000 - 0xc02bb000 (2764 kB)
.init : 0xc02bb000 - 0xc0552000 (2652 kB)
.data : 0xc0552000 - 0xc057b2a0 ( 165 kB)
.bss : 0xc057c230 - 0xc05944a4 ( 97 kB)
NR_IRQS:16 nr_irqs:16 16
clocksource: arm_system_timer: mask: 0xffffff max_cycles: 0xffffff, max_idle_ns: 331816030 ns
ARM System timer initialized as clocksource
/soc/timer@40000000: STM32 clockevent driver initialized (32 bits)
sched_clock: 32 bits at 100 Hz, resolution 10000000ns, wraps every 21474836475000000ns
Calibrating delay loop... 36.86 BogoMIPS (lpj=184320)
pid_max: default: 4096 minimum: 301
Mount-cache hash table entries: 1024 (order: 0, 4096 bytes)
Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes)
devtmpfs: initialized
clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns
pinctrl core: initialized pinctrl subsystem
NET: Registered protocol family 16
stm32-pinctrl pin-controller: nbanks = 11
stm32-pinctrl pin-controller: nfunctions = 13
stm32-pinctrl pin-controller: ngroups = 15
stm32-pinctrl pin-controller: GPIOA bank added.
stm32-pinctrl pin-controller: GPIOB bank added.
stm32-pinctrl pin-controller: GPIOC bank added.
stm32-pinctrl pin-controller: GPIOD bank added.
stm32-pinctrl pin-controller: GPIOE bank added.
stm32-pinctrl pin-controller: GPIOF bank added.
stm32-pinctrl pin-controller: GPIOG bank added.
stm32-pinctrl pin-controller: GPIOH bank added.
stm32-pinctrl pin-controller: GPIOI bank added.
stm32-pinctrl pin-controller: GPIOJ bank added.
stm32-pinctrl pin-controller: GPIOK bank added.
stm32-pinctrl pin-controller: Function[0    name:i2c_1,             groups:1]
stm32-pinctrl pin-controller: Function[1    name:i2c_2,             groups:1]
stm32-pinctrl pin-controller: Function[2    name:i2c_3,             groups:1]
stm32-pinctrl pin-controller: Function[3    name:mac,               groups:2]
stm32-pinctrl pin-controller: Function[4    name:sdio,              groups:1]
stm32-pinctrl pin-controller: Function[5    name:spi_2,             groups:1]
stm32-pinctrl pin-controller: Function[6    name:spi_4,             groups:1]
stm32-pinctrl pin-controller: Function[7    name:spi_5,             groups:1]
stm32-pinctrl pin-controller: Function[8    name:usart1,            groups:1]
stm32-pinctrl pin-controller: Function[9    name:usart7,            groups:1]
stm32-pinctrl pin-controller: Function[10   name:usb_fs,            groups:1]
stm32-pinctrl pin-controller: Function[11   name:usb_hs,            groups:1]
stm32-pinctrl pin-controller: Function[12   name:gpio,              groups:2]
stm32_dma 40026000.dma: STM32 DMA Controller ( slave ), 8 channels
stm32_dma 40026400.dma: STM32 DMA Controller ( slave ), 8 channels
SCSI subsystem initialized
usbcore: registered new interface driver usbfs
usbcore: registered new interface driver hub
usbcore: registered new device driver usb
soc:phy_hs supply vcc not found, using dummy regulator
soc:phy_fs supply vcc not found, using dummy regulator
pps_core: LinuxPPS API ver. 1 registered
pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti

<giometti@linux.it>
PTP clock support registered
Bluetooth: Core ver 2.20
NET: Registered protocol family 31
Bluetooth: HCI device and connection manager initialized
Bluetooth: HCI socket layer initialized
Bluetooth: L2CAP socket layer initialized
Bluetooth: SCO socket layer initialized
clocksource: Switched to clocksource arm_system_timer
NET: Registered protocol family 2
TCP established hash table entries: 1024 (order: 0, 4096 bytes)
TCP bind hash table entries: 1024 (order: 0, 4096 bytes)
TCP: Hash tables configured (established 1024 bind 1024)
UDP hash table entries: 256 (order: 0, 4096 bytes)
UDP-Lite hash table entries: 256 (order: 0, 4096 bytes)
NET: Registered protocol family 1
RPC: Registered named UNIX socket transport module.
RPC: Registered udp transport module.
RPC: Registered tcp transport module.
RPC: Registered tcp NFSv4.1 backchannel transport module.
futex hash table entries: 16 (order: -5, 192 bytes)
jffs2: version 2.2. (NAND) © 2001-2006 Red Hat, Inc.
fuse init (API version 7.23)
Block layer SCSI generic (bsg) driver version 0.4 loaded (major 251)
io scheduler noop registered
io scheduler cfq registered (default)
STM32 USART driver initialized
stm32-pinctrl pin-controller: maps: function usart7 group usart7-0 num 3
40007800.serial: ttyS6 at MMIO 0x40007800 (irq = 22, base_baud = 2812500) is a stm32-usart
stm32-pinctrl pin-controller: maps: function usart1 group usart1-0 num 3
40011000.serial: ttyS0 at MMIO 0x40011000 (irq = 23, base_baud = 5625000) is a stm32-usart
console [ttyS0] enabled
Initializing STM32F4 mapper, copying code from c057c000 to 200001a8, size 560
Using SRAM as buffer with start 20000400 and size 400
physmap-flash.0: Found 1 x16 devices at 0x0 in 16-bit bank. Manufacturer ID 0x000001 Chip ID 0x002101 Amd/Fujitsu Extended Query Table at 0x0040
Amd/Fujitsu Extended Query version 1.5.
number of CFI chips: 1
3 ofpart partitions found on MTD device physmap-flash.0
Creating 3 MTD partitions on "physmap-flash.0":
0x000000000000-0x000000020000 : "flash_uboot_env"
0x000000020000-0x000000a20000 : "flash_linux_image"
0x000000a20000-0x000001000000 : "flash_jffs2"
stm32-pinctrl pin-controller: maps: function spi_2 group spi_2-0 num 4
stm32-spi 40003800.spi: SPI Controller 1 at 40003800,irq=19,hz=45000000
stm32-pinctrl pin-controller: maps: function mac group mac_rmii num 10
stmmac - user ID: 0x10, Synopsys ID: 0x35
Ring mode enabled
DMA HW capability register supported
Enhanced/Alternate descriptors
Enabled extended descriptors
RX Checksum Offload Engine supported (type 2)
TX Checksum insertion supported
Wake-Up On Lan supported
Enable RX Mitigation via HW Watchdog Timer
libphy: stmmac: probed
eth0: PHY ID 00221560 at 0 IRQ POLL (stmmac-0:00) active
eth0: PHY ID 00221560 at 1 IRQ POLL (stmmac-0:01)
PPP generic driver version 2.4.2
PPP BSD Compression module registered
PPP Deflate Compression module registered
usbcore: registered new interface driver rt2800usb
stm32-pinctrl pin-controller: maps: function usb_hs group usb_hs-0 num 13
dwc2 40040000.usb: DWC OTG Controller
dwc2 40040000.usb: new USB bus registered, assigned bus number 1
dwc2 40040000.usb: irq 41, io mem 0x00000000
hub 1-0:1.0: USB hub found
hub 1-0:1.0: 1 port detected
usbcore: registered new interface driver cdc_acm
cdc_acm: USB Abstract Control Model driver for USB modems and ISDN adapters
usbcore: registered new interface driver usb-storage
stm32-pinctrl pin-controller: maps: function gpio group ins num 3
input: inputs as /devices/platform/inputs/input/input0
stm32-rtc 40002800.rtc: rtc core: registered 40002800.rtc as rtc0
i2c /dev entries driver
stm32-pinctrl pin-controller: maps: function i2c_1 group i2c_1-0 num 3
stm32-i2c 40005400.i2c: I2C Controller i2c-0 at 40005400,irq=20
usbcore: registered new interface driver btusb
stm32-pinctrl pin-controller: maps: function gpio group outs num 3
usbcore: registered new interface driver usbhid
usbhid: USB HID core driver
NET: Registered protocol family 17
Bluetooth: RFCOMM TTY layer initialized
Bluetooth: RFCOMM socket layer initialized
Bluetooth: RFCOMM ver 1.11
stm32-rtc 40002800.rtc: setting system clock to 2000-01-01 06:04:13 UTC (946706653)
IP-Config: Guessing netmask 255.255.0.0
IP-Config: Complete:
device=eth0, hwaddr=c0:b1:3c:88:88:85, ipaddr=172.17.4.206, mask=255.255.0.0,       gw=255.255.255.255
host=stm32f4x9-som, domain=, nis-domain=(none)
bootserver=172.17.0.1, rootserver=172.17.0.1, rootpath=
vmmc: disabling
Freeing unused kernel memory: 2652K (c02bb000 - c0552000)
init started: BusyBox v1.17.0 (2016-05-12 14:56:35 +0400)
stm32-dwmac 40028000.ethernet eth0: Link is Up - 100Mbps/Full - flow control rx/tx
/ #

Let's test the TCP/IP stack on the STM32F4.

From the development host validate that the STM32F4 is visible using ping:

-bash-3.2$ ping 172.17.4.206
PING 172.17.4.206 (172.17.4.206) 56(84) bytes of data.
64 bytes from 172.17.4.206: icmp_seq=1 ttl=64 time=2.48 ms
64 bytes from 172.17.4.206: icmp_seq=2 ttl=64 time=1.29 ms
64 bytes from 172.17.4.206: icmp_seq=3 ttl=64 time=1.18 ms
64 bytes from 172.17.4.206: icmp_seq=4 ttl=64 time=1.16 ms
^C
--- 172.17.4.206 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3004ms
rtt min/avg/max/mdev = 1.164/1.531/2.481/0.551 ms
-bash3.2$

Ping the development host from the STM32F4:

/ # ping 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=4.595 ms
64 bytes from 172.17.0.1: seq=1 ttl=64 time=1.532 ms
64 bytes from 172.17.0.1: seq=2 ttl=64 time=1.561 ms
64 bytes from 172.17.0.1: seq=3 ttl=64 time=1.560 ms
64 bytes from 172.17.0.1: seq=4 ttl=64 time=1.537 ms
^C
--- 172.17.0.1 ping statistics ---
5 packets transmitted, 5 packets received, 0% packet loss
round-trip min/avg/max = 1.532/2.157/4.595 ms
/ #

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

/ # telnetd
/ # ps
PID USER       VSZ STAT COMMAND
1 root       360 S    init
2 root         0 SW   [kthreadd]
3 root         0 SW   [ksoftirqd/0]
4 root         0 SW   [kworker/0:0]
5 root         0 SW<  [kworker/0:0H]
6 root         0 SW   [kworker/u2:0]
7 root         0 SW<  [khelper]
8 root         0 SW   [kdevtmpfs]
9 root         0 SW<  [writeback]
10 root        0 SW<  [crypto]
11 root        0 SW<  [bioset]
12 root        0 SW<  [kblockd]
13 root        0 SW<  [cfg80211]
14 root        0 SW   [kworker/0:1]
15 root        0 SW<  [rpciod]
16 root        0 SW   [kswapd0]
17 root        0 SW   [fsnotify_mark]
18 root        0 SW<  [nfsiod]
40 root        0 SW   [spi1]
41 root        0 SW<  [dwc2]
42 root        0 SW<  [krfcommd]
43 root        0 SW<  [deferwq]
44 root        0 SW   [kworker/u2:1]
50 root      396 S    -/bin/hush
53 root      352 S    telnetd
54 root      368 R    ps
/#

Connect to the target from the development host using telnet. The target is configured to accept an empty password for root so just hit Enter when asked for password:

-bash-3.2$ telnet 172.17.4.206
Trying 172.17.4.206...
Connected to 172.17.4.206.
Escape character is '^]'.

stm32f4x9-som login: root
Password:
/ # ls
bin etc init mnt mnt2 mnt4 root sys usr
dev httpd lib mnt1 mnt3 proc sbin tmp var
/ # exit
Connection closed by foreign host.
-bash-3.2$

Start the dropbear SSH daemon to allow secure connections to the target:

/ # dropbear
/ # ps
PID USER       VSZ STAT COMMAND
1 root       360 S    init
2 root         0 SW   [kthreadd]
3 root         0 SW   [ksoftirqd/0]
4 root         0 SW   [kworker/0:0]
5 root         0 SW<  [kworker/0:0H]
6 root         0 SW   [kworker/u2:0]
7 root         0 SW<  [khelper]
8 root         0 SW   [kdevtmpfs]
9 root         0 SW<  [writeback]
10 root        0 SW<  [crypto]
11 root        0 SW<  [bioset]
12 root        0 SW<  [kblockd]
13 root        0 SW<  [cfg80211]
14 root        0 SW   [kworker/0:1]
15 root        0 SW<  [rpciod]
16 root        0 SW   [kswapd0]
17 root        0 SW   [fsnotify_mark]
18 root        0 SW<  [nfsiod]
40 root        0 SW   [spi1]
41 root        0 SW<  [dwc2]
42 root        0 SW<  [krfcommd]
43 root        0 SW<  [deferwq]
44 root        0 SW   [kworker/u2:1]
50 root      396 S    -/bin/hush
53 root      360 S    telnetd
59 root      316 S    dropbear
60 root      368 R
ps
/ #

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

-bash-3.2$ ssh root‌@172.17.4.206
The authenticity of host '172.17.4.206 (172.17.4.206)' can't be established.
DSA key fingerprint is d2:d1:5f:dd:84:65:1d:2f:ee:69:0c:85:d0:22:0c:87.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '172.17.4.206' (DSA) to the list of known hosts.
root‌@172.17.4.206's password:
/ # ps
PID USER       VSZ STAT COMMAND
1 root       360 S    init
2 root         0 SW   [kthreadd]
3 root         0 SW   [ksoftirqd/0]
4 root         0 SW   [kworker/0:0]
5 root         0 SW<  [kworker/0:0H]
6 root         0 SW   [kworker/u2:0]
7 root         0 SW<  [khelper]
8 root         0 SW   [kdevtmpfs]
9 root         0 SW<  [writeback]
10 root        0 SW<  [crypto]
11 root        0 SW<  [bioset]
12 root        0 SW<  [kblockd]
13 root        0 SW<  [cfg80211]
14 root        0 SW   [kworker/0:1]
15 root        0 SW<  [rpciod]
16 root        0 SW   [kswapd0]
17 root        0 SW   [fsnotify_mark]
18 root        0 SW<  [nfsiod]
40 root        0 SW   [spi1]
41 root        0 SW<  [dwc2]
42 root        0 SW<  [krfcommd]
43 root        0 SW<  [deferwq]
44 root        0 SW   [kworker/u2:1]
50 root       396 S    -/bin/hush
53 root       360 S    telnetd
59 root       396 D    dropbear
64 root       396 R    dropbear
65 root       388 S    -sh
66 root       368 R    ps
/ #
~ # exit
Connection to 172.17.4.206 closed.
>-bash-3.2$

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:

/ # 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:

/ # date
Thu Jan 1 00:40:53 UTC 1970
/ # ntpd -p 0.fedora.pool.ntp.org
/ # sleep 5
/ # date
Fri May 13 19:46:18 UTC 2016
/ #

Use wget to download a file from a remote server:

/ # wget ftp://ftp.gnu.org/README
Connecting to ftp.gnu.org (208.118.235.20:21)
README 100% |*******************************| 1962 --:--:-- 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:

/ # mount -o nolock,rsize=1024 172.17.0.1:/home/vlad/test/ /mnt
/ # ls
bin    dev    etc    httpd  init   mnt    proc   root   sys    usr    var
/ # ls /mnt
linux-STMDISCO-1.12.1.tar.bz2
linux-cortexm-1.12.0
linux-cortexm-1.12.1
linux-cortexm-1.12.1.tar.bz2
linux-cortexm-1.12.2
...
/ #

Start the HTTP daemon:

/ # httpd -h /httpd/html/
/ #

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