# Emulating MPS2 Cortex M3 AN385 on QEMU ## Requirements 1. GNU Arm Embedded Toolchain download [here](https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads) 3. qemu-arm-system download [here](https://www.qemu.org/download) 2. Make (tested on version 3.82) 4. Linux OS (tested on Ubuntu 18.04) ## How to download Navigate to a parent directory of your choice and run the following command ``` $ git clone https://github.com/FreeRTOS/FreeRTOS.git --recurse-submodules --depth 1 ``` The previous command should create a directory named **FreeRTOS** ## Networking Echo client Demo To make networking support possible a few steps needs to be done on the machine lets assume the following interfaces using ubuntu 18.04 or Fedora 30 (the interface names on your machine could be different) ``` l0: loopback in terface enp0s3: ethernet interface virbr0: virtual bridge (to be created) virbr0-nic: veth virtual interface (to be created) ``` ### A few assumptions (your numbers could vary) ``` Local Host IP address: 192.168.1.81 Local FreeRTOS IP address: 192.168.1.80 Local FreeRTOS Subnet mask: 255.255.255.0 Default Gateway IP address: 192.168.1.254 Default DNS IP address: 192.168.1.254 Echo Server IP address: 192.168.1.204 Echo Server Port: 7 Local FreeRTOS Mac address: 52:54:00:12:34:AD ``` ### Building and Running 1. Fill the defines values in FreeRTOSConfig.h with what is equivalent to the above values on your system ```c #define configIP_ADDR0 192 #define configIP_ADDR1 168 #define configIP_ADDR2 1 #define configIP_ADDR3 80 #define configNET_MASK0 255 #define configNET_MASK1 255 #define configNET_MASK2 255 #define configNET_MASK3 0 #define configGATEWAY_ADDR0 192 #define configGATEWAY_ADDR1 168 #define configGATEWAY_ADDR2 1 #define configGATEWAY_ADDR3 254 #define configDNS_SERVER_ADDR0 192 #define configDNS_SERVER_ADDR1 168 #define configDNS_SERVER_ADDR2 1 #define configDNS_SERVER_ADDR3 254 #define configMAC_ADDR0 0x52 #define configMAC_ADDR1 0x54 #define configMAC_ADDR2 0x00 #define configMAC_ADDR3 0x12 #define configMAC_ADDR4 0x34 #define configMAC_ADDR5 0xAD #define configECHO_SERVER_ADDR0 192 #define configECHO_SERVER_ADDR1 168 #define configECHO_SERVER_ADDR2 1 #define configECHO_SERVER_ADDR3 204 ``` 2. Build your software ``` $ make ``` options: DEBUG=1 to build with **-O0** and debugging symbols 3. On the remote machine (ip 192.168.1.204) ``` $ sudo nc -l 7 ``` 4. Turn off the firewall if running On RedHat/Fedora system (tested Fedora 30) run: ``` sudo systemctl status firewalld sudo systemctl stop firewalld ``` On Ubuntu run: ``` $ sudo ufw disable $ sudo ufw status ``` 5. Setup the local machine Run the following commands replacing the values and interface names that conform to your system ``` sudo ip link add virbr0 type bridge sudo ip tuntap add dev virbr0-nic mode tap sudo ip addr add 192.168.1.81/24 dev virbr0 sudo brctl addif virbr0 enp0s3 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 192.168.1.254 dev virbr0 ``` 6. Run the demo ``` $ sudo qemu-system-arm -machine mps2-an385 -cpu cortex-m3 -kernel ./build/RTOSDemo.axf \ -netdev tap,id=mynet0,ifname=virbr0-nic,script=no \ -net nic,macaddr=52:54:00:12:34:AD,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 ``` Replace the value of macaddr=52:54:00:12:34:AD with your own value from ``` configMAC_ADDR0 through configMAC_ADDR5 ``` 7. Expectations On the remote machine you should expect to see something similar to the following: ``` $ sudo nc -l 7 Password: TxRx message number 0FGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~0123456789:;<=> ? @ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~0123456789:;<=>? @ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~0123456789:;<=>? @ABCDEFGHIJKLM ``` ## How to start debugging 1. gdb
Append the -s and -S switches to the previous command (qemu-system-arm)
-s: allow gdb to be attached to the process remotely at port 1234
-S: start the program in the paused state
run: (make sure you build the debug version)
```
$ arm-none-eabi-gdb -q ./build/RTOSDemo.axf
(gdb) target remote :1234
(gdb) break main
(gdb) c
```
2. tcpdump
To monitor packets received to qemu running the qemu command (qemu-system-arm)
shown above will create a network packet dump that you could inspect with
```
$ sudo tcpdump -r /tmp/qemu_tap_dump | less
```