You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
FreeRTOS/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Qemu...
Monika Singh 301ed5881b
Merging IPv6 demo changes to main (#1028)
* Add IPv6 Demo (#937)

* Add demo changes

* Update kernel and library paths

* Update main.c

* Run uncrustify

* Fix spell checker

* CI check file headers update

* Add IPv6/v4 UDP echo server with zero copy/non-zero copy versions

* Add VS proj file changes to include the UDP echo sample code

* readme update

---------

Co-authored-by: Tony Josi <tonyjosi@amazon.com>

* Update Backward Compatibility Flag (#954)

* Update Backward Compatibility Flag

* Update FreeRTOS_GetUDPPayloadBuffer_ByIPType

* Update FreeRTOS_IPStart to FreeRTOS_IPInit_Multi

* Update Application APIs

* Remove ipconfigCOMPATIBLE_WITH_SINGLE

* Update Static Lib files (#956)

* Update Static Lib files

* making vApplicationIPNetworkEventHook backward compatible in demos

* Update CI check file headers

---------

Co-authored-by: Tony Josi <tonyjosi@amazon.com>

* Add WinPCap NetworkInterface Changes (#958)

* Update winpcap network interface

* Run uncrustify

* Update function to include NetworkInterface_t parameters

* Adding compatibility for xApplicationDNSQueryHook with latest dev branch for old demos (#957)

* adding compatibility for xApplicationDNSQueryHook with latest dev branch

* adding tcp echo server source

* removing unused sub demos

* fix build issues (#969)

* Update demo to latest +TCP dev/IPv6_integration (#978)

* remove macro namings

* rename sin_addr to sin_address.ulIP_IPv4 for ipv6 demo

* replace in6addr_any with FreeRTOS_in6addr_any

* replace mainCREATE_UDP_ECHO_SERVER_TASK with mainCREATE_UDP_ECHO_TASKS_SINGLE

* handle removal of sin_addr macro to sin_address.ulIP_IPv4

* updating +TCP repo to latest dev/IPv6_integration

* minor update to more clear code

* more sin_addr to sin_address.ulIP_IPv4 replacements

* fix makefiles for qemu and posix demos

* review feedback changes

* Update FreeRTOS-Plus-TCP for RC2

* Change from PR (#994)

* Update FreeRTOS-Plus-TCP for RC2

* Update copyright

* Ignore WinPCap for files header check failure.

* Update checker

* Update manifest

* Point manifest to latest commit

* Fix Spell-checker

* Update doxygen

* Update xApplicationDHCPHook for backward compatibility  (#999)

* Update xApplicationDHCPHook for backward compatability

* Update IPv6

* Update VisualStudio Static Project files

* Update pxEndPoint error (#1002)

* Update IPv6 demo ReadMe (#1004)

* Update ReadMe

* Update setup requirement

* Update UDP demo info

* Update comment

* TCP demo changes post build separation (#1011)

* adding sin_family to dest adddr for FreeRTOS_sendto

* updating FreeRTOS_bind to input sin_family post build separation changes

* updating FreeRTOS_connect to input sin_family post build separation changes

* minor fix

* updating copyright year

* updating file headers

* updating +TCP submodule

* updating file headers

* updating file headers

* updating manifest file to have latest +TCP submodule hash

* Fix issue with posix demo while running with ipconfigIPv4_BACKWARD_COMPATIBLE enabled for +TCP stack (#1027)

* Update the submodule pointer to IPv6 main

* Update manifest with latest TCP commit

* Update file checker exception

* Ignore Visual studio project file from file header checker

---------

Co-authored-by: Tony Josi <tonyjosi@amazon.com>
2 years ago
..
CMSIS Fix issues in TCP QEMU Demo (#948) 2 years ago
.gitignore FreeRTOS Windows Simulator Build Changes and LTS 2.0 Update (#872) 2 years ago
FreeRTOSConfig.h Update FreeRTOSConfig.h (#1008) 2 years ago
FreeRTOSIPConfig.h [AUTO][RELEASE]: Bump file header version to "202212.00" 2 years ago
Makefile Merging IPv6 demo changes to main (#1028) 2 years ago
Readme.md Update Readme for the FreeRTOS_PLUS_TCP_ECHO_QEMU_msp2 (#939) 2 years ago
TCPEchoClient_SingleTasks.c Merging IPv6 demo changes to main (#1028) 2 years ago
TCPEchoClient_SingleTasks.h [AUTO][RELEASE]: Bump file header version to "202212.00" 2 years ago
main.c [AUTO][RELEASE]: Bump file header version to "202212.00" 2 years ago
main_networking.c Merging IPv6 demo changes to main (#1028) 2 years ago
mps2_m3.ld [AUTO][RELEASE]: Bump file header version to "202212.00" 2 years ago
startup.c [AUTO][RELEASE]: Bump file header version to "202212.00" 2 years ago
syscalls.c [AUTO][RELEASE]: Bump file header version to "202212.00" 2 years ago

Readme.md

TCP Echo Client Demo for MPS2 Cortex-M3 AN385 emulated using QEMU

This FreeRTOS+TCP example demonstrates a TCP Echo Client which sends echo requests to an Echo Server and then receives the echo reply. The Echo Client runs on the MPS2 Cortex-M3 AN385 platform emulated using QEMU.

Setup Description

The demo requires 2 components -

  1. Echo Client - The demo in this repository.
  2. Echo Server - An external echo server.

We need a Virtual Machine (VM) running Linux OS to run this demo. Echo Client runs in the Virtual Machine (VM) and Echo Server runs on the host machine.

+--------------------------------------------------------+
|  Host Machine                                          |
|  OS - Any                                              |
|  Runs - Echo Server                                    |
|                          +--------------------------+  |
|                          | Virtual Machine (VM)     |  |
|                          | OS - Linux               |  |
|                          | Runs - Echo Client       |  |
|                          |                          |  |
|  +----------------+      |    +----------------+    |  |
|  |                |      |    |                |    |  |
|  |                |      |    |                |    |  |
|  |  Echo Server   | <-------> |   Echo Client  |    |  |
|  |                |      |    |                |    |  |
|  |                |      |    |                |    |  |
|  |                |      |    |                |    |  |
|  +----------------+      |    +----------------+    |  |
|                          |                          |  |
|                          +--------------------------+  |
+--------------------------------------------------------+

Setting up VM

  1. Install a Virtual Machine software on your machine. On Windows you can use Oracle VirtualBox and on Mac you can use Parallels.
  2. Launch a Linux VM. We tested using Ubuntu 22.04.
  3. Install the following tools in the VM:
  4. Clone the source code in the VM:
    git clone https://github.com/FreeRTOS/FreeRTOS.git --recurse-submodules --depth 1
    

Launch Echo Server

Launch Echo Server on the host machine.

Host OS is Linux

  • Install netcat:
    sudo apt install netcat
    
  • Start an Echo Server on port 7:
    sudo nc -l 7
    

Host OS is Windows

  • Install Npcap/Nmap.
  • Start an Echo Server on port 7:
    ncat -l 7
    

Host OS is Mac

  • Install netcat:
    brew install netcat
    
  • Start an Echo Server on port 7:
    nc -l -p 7
    

Enable Networking in QEMU

The Echo Client in this demo runs in QEMU inside the VM. We need to enable networking in QEMU to enable the Echo Client to be able to reach the Echo Server. Do the following steps in the VM:

  1. Run the ifconfig command to find the VM's network interface details:
enp0s3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 9001
          inet 192.168.1.81  netmask 255.255.255.0  broadcast 192.168.15.255
          inet6 fe80::89c:55ff:fe3d:18ad  prefixlen 64  scopeid 0x20<link>
          ether 0a:9c:55:3d:18:ad  txqueuelen 1000  (Ethernet)
          RX packets 15001255  bytes 11443805826 (11.4 GB)
          RX errors 0  dropped 0  overruns 0  frame 0
          TX packets 9248218  bytes 2080385000 (2.0 GB)
          TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

  1. Define a shell variable VM_NETWORK_INTERFACE and set its value to the name of the network interface of the VM. For example, in the above output of the ifconfig command, name of the the network interface is enp0s3:
export VM_NETWORK_INTERFACE=enp0s3
  1. Define a shell variable VM_IP_ADDRESS and set its value to the IP address of the VM. For example, in the above output of the ifconfig command, IP address of the VM is 192.168.1.81:
export VM_IP_ADDRESS=192.168.1.81
  1. Define a shell variable VM_NETMASK and set its value to the netmask of the VM. For example, in the above output of the ifconfig command, netmask of the VM is 255.255.255.0:
export VM_NETMASK=255.255.255.0
  1. Calculate the CIDR of the VM from the netmask:
$ ipcalc -b 1.1.1.1 $VM_NETMASK | grep Netmask
Netmask:   255.255.255.0 = 24

CIDR is 24 in the above output.

  1. Define a shell variable VM_CIDR and set its value to the CIDR of the VM found in the above step.
export VM_CIDR=24
  1. Find the Default Gateway for the VM:
$ ip route show
default via 192.168.1.254 dev enp0s3 proto dhcp src 192.168.1.81 metric 100

Default Gateway is 192.168.1.254 in the above output.

  1. Define a shell variable VM_DEFAULT_GATEWAY and set its value to the Default Gateway of the VM found in the above step.
export VM_DEFAULT_GATEWAY=192.168.1.254
  1. Find the DNS Server of the VM:
$ grep "nameserver" /etc/resolv.conf
nameserver 192.168.1.254
  1. Define a shell variable VM_DNS_SERVER and set its value to the DNS Server of the host machine found in the above step.
export VM_DNS_SERVER=192.168.1.254
  1. Pick an IP address for the QEMU which is in the same network as the VM. This IP address must not be in-use by any other machine on the same network. Define a shell variable QEMU_IP_ADDRESS and set its value to the picked IP Address. For example, run the following command if you picked 192.168.1.80:
export QEMU_IP_ADDRESS=192.168.1.80
  1. Pick a MAC address for the QEMU. Define a shell variable QEMU_MAC_ADDRESS and set its value to the picked MAC Address. For example, run the following command if you picked 52:54:00:12:34:AD:
export QEMU_MAC_ADDRESS=52:54:00:12:34:AD
  1. Define a shell variable ECHO_SERVER_IP_ADDRESS and set its value to the IP address of the Echo Server which is running on the host. For example, run the following command if the IP address of the Echo Server is 192.168.1.204:
export ECHO_SERVER_IP_ADDRESS=192.168.1.204
  1. Turn off firewall on the VM. On Ubuntu run:
sudo ufw disable
sudo ufw status

On RedHat/Fedora system run:

sudo systemctl status firewalld
sudo systemctl stop firewalld
  1. Create virtual bridge (virbr0) and virtual NIC (virbr0-nic) to enable networking in QEMU.
sudo ip link add virbr0 type bridge
sudo ip tuntap add dev virbr0-nic mode tap

sudo ip addr add $VM_IP_ADDRESS/$VM_CIDR dev virbr0

sudo brctl addif virbr0 $VM_NETWORK_INTERFACE
sudo brctl addif virbr0 virbr0-nic

sudo ip link set virbr0 up
sudo ip link set virbr0-nic up

sudo ip route add default via $VM_DEFAULT_GATEWAY dev virbr0

The following diagram shows the setup:

+-------------------------------------------------------------------------+
|   Virtual Machine (VM)                                                  |
|                                                                         |
|     +-------------------------+                                         | VM NIC (enp0s3)
|     |                         | Virtual NIC (virbr0-nic)                +--+
|     |  QEMU                   +--+                                      |  |
|     |                         |  |          +--------------+            |  |
|     |                         |  +--------->|    virbr0    | ---------->|  +--------> Internet
|     |                         |  |          +--------------+            |  |
|     |                         +--+           Virtual Bridge             |  |
|     |                         |                                         +--+
|     +-------------------------+                                         |
|                                                                         |
|                                                                         |
+-------------------------------------------------------------------------+

Build and Run

Do the following steps in the VM where you cloned the code:

  1. Set configIP_ADDR0-configIP_ADDR3 in FreeRTOSConfig.h to the value of QEMU_IP_ADDRESS:
echo $QEMU_IP_ADDRESS
#define configIP_ADDR0          192
#define configIP_ADDR1          168
#define configIP_ADDR2          1
#define configIP_ADDR3          80
  1. Set configNET_MASK0-configNET_MASK3 in FreeRTOSConfig.h to the value of VM_NETMASK:
echo $VM_NETMASK
#define configNET_MASK0         255
#define configNET_MASK1         255
#define configNET_MASK2         255
#define configNET_MASK3         0
  1. Set configGATEWAY_ADDR0-configGATEWAY_ADDR3 in FreeRTOSConfig.h to the value of VM_DEFAULT_GATEWAY:
echo $VM_DEFAULT_GATEWAY
#define configGATEWAY_ADDR0     192
#define configGATEWAY_ADDR1     168
#define configGATEWAY_ADDR2     1
#define configGATEWAY_ADDR3     254
  1. Set configDNS_SERVER_ADDR0-configDNS_SERVER_ADDR3 in FreeRTOSConfig.h to the value of VM_DNS_SERVER:
echo $VM_DNS_SERVER
#define configDNS_SERVER_ADDR0  192
#define configDNS_SERVER_ADDR1  168
#define configDNS_SERVER_ADDR2  1
#define configDNS_SERVER_ADDR3  254
  1. Set configMAC_ADDR0-configMAC_ADDR5 in FreeRTOSConfig.h to the value of QEMU_MAC_ADDRESS:
echo $QEMU_MAC_ADDRESS
#define configMAC_ADDR0         0x52
#define configMAC_ADDR1         0x54
#define configMAC_ADDR2         0x00
#define configMAC_ADDR3         0x12
#define configMAC_ADDR4         0x34
#define configMAC_ADDR5         0xAD
  1. Set configECHO_SERVER_ADDR0-configECHO_SERVER_ADDR3 in FreeRTOSConfig.h to the value of ECHO_SERVER_IP_ADDRESS:
echo $ECHO_SERVER_IP_ADDRESS
#define configECHO_SERVER_ADDR0 192
#define configECHO_SERVER_ADDR1 168
#define configECHO_SERVER_ADDR2 1
#define configECHO_SERVER_ADDR3 204
  1. Build:
make
  1. Run:
sudo qemu-system-arm -machine mps2-an385 -cpu cortex-m3 \
          -kernel ./build/freertos_tcp_mps2_demo.axf \
          -netdev tap,id=mynet0,ifname=virbr0-nic,script=no \
          -net nic,macaddr=$QEMU_MAC_ADDRESS,model=lan9118,netdev=mynet0 \
          -object filter-dump,id=tap_dump,netdev=mynet0,file=/tmp/qemu_tap_dump\
          -display gtk -m 16M  -nographic -serial stdio \
          -monitor null -semihosting -semihosting-config enable=on,target=native
  1. You should see that following output on the terminal of the Echo Server (which is running sudo nc -l 7 or netcat -l 7 depending on your OS):
0FGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~0123456789:;<=> ?
@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~0123456789:;<=>?
@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~0123456789:;<=>?
@ABCDEFGHIJKLM

Debug

  1. Build with debugging symbols:
make DEBUG=1
  1. Start QEMU in the paused state waiting for GDB connection:
sudo qemu-system-arm -machine mps2-an385 -cpu cortex-m3 -s -S \
          -kernel ./build/freertos_tcp_mps2_demo.axf \
          -netdev tap,id=mynet0,ifname=virbr0-nic,script=no \
          -net nic,macaddr=$QEMU_MAC_ADDRESS,model=lan9118,netdev=mynet0 \
          -object filter-dump,id=tap_dump,netdev=mynet0,file=/tmp/qemu_tap_dump\
          -display gtk -m 16M  -nographic -serial stdio \
          -monitor null -semihosting -semihosting-config enable=on,target=native
  1. Run GDB:
$ arm-none-eabi-gdb -q ./build/freertos_tcp_mps2_demo.axf

(gdb) target remote :1234
(gdb) break main
(gdb) c
  1. The above QEMU command creates a network packet dump in the file /tmp/qemu_tap_dump which you can examine using tcpdump or WireShark:
sudo tcpdump -r /tmp/qemu_tap_dump  | less