Skip to content

Commit c8642d7

Browse files
authored
Merge pull request #11 from LinuxJedi/freertos
Add FreeRTOS echo-server example
2 parents aeb3f98 + 4d3f36c commit c8642d7

21 files changed

Lines changed: 1791 additions & 10 deletions

.github/workflows/echo-server.yml

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
name: echo-server
2+
3+
on:
4+
push:
5+
branches: [ 'main' ]
6+
pull_request:
7+
branches: [ '*' ]
8+
9+
jobs:
10+
build-and-test:
11+
runs-on: ubuntu-latest
12+
steps:
13+
- uses: actions/checkout@v4
14+
with:
15+
submodules: recursive
16+
17+
- name: Install dependencies
18+
run: sudo apt-get update && sudo apt-get install -y libpcap-dev iproute2 ethtool tcpdump sshpass
19+
20+
- name: Setup network and detect pcap index
21+
id: pcap
22+
run: |
23+
# Clean up any stale veth pair
24+
sudo ip link del veth0 2>/dev/null || true
25+
26+
# Create the veth pair
27+
sudo ip link add veth0 type veth peer name veth1
28+
sudo ip link set veth0 up
29+
sudo ip link set veth1 up
30+
sudo ip addr add 10.0.0.1/24 dev veth0
31+
sudo ethtool -K veth0 tx off
32+
33+
# Find veth1's pcap index (1-based, as reported by tcpdump)
34+
INDEX=$(tcpdump --list-interfaces 2>/dev/null | grep -m1 'veth1' | cut -d. -f1)
35+
echo "veth1 is pcap interface $INDEX"
36+
echo "index=$INDEX" >> "$GITHUB_OUTPUT"
37+
38+
- name: Build
39+
working-directory: echo-server
40+
run: make EXTRA_CPPFLAGS=-DipconfigNETWORK_INTERFACE_TO_USE=${{ steps.pcap.outputs.index }}
41+
42+
- name: Build debug
43+
working-directory: echo-server
44+
run: make clean && make BUILD=debug EXTRA_CPPFLAGS=-DipconfigNETWORK_INTERFACE_TO_USE=${{ steps.pcap.outputs.index }}
45+
46+
- name: Functional test
47+
working-directory: echo-server
48+
run: |
49+
set +e
50+
51+
# Start the server in the background with a 60s timeout
52+
sudo timeout 60s ./echo-server > /tmp/echo-server.log 2>&1 &
53+
SERVER_PID=$!
54+
55+
# Wait for the server to be ready
56+
READY=0
57+
for i in $(seq 1 30); do
58+
if grep -q "Listening on port 22222" /tmp/echo-server.log 2>/dev/null; then
59+
echo "Server is listening"
60+
READY=1
61+
break
62+
fi
63+
sleep 1
64+
done
65+
if [ "$READY" -ne 1 ]; then
66+
echo "FAIL: server did not start in time"
67+
cat /tmp/echo-server.log
68+
sudo kill $SERVER_PID 2>/dev/null || true
69+
sudo ip link del veth0 2>/dev/null || true
70+
exit 1
71+
fi
72+
73+
# Connect and authenticate via SSH. The wolfSSH echo server
74+
# does not provide a shell, so the client will disconnect after
75+
# the channel opens. We just need to verify the SSH handshake
76+
# and authentication succeed.
77+
sshpass -p upthehill ssh -T -p 22222 \
78+
-o StrictHostKeyChecking=no \
79+
-o UserKnownHostsFile=/dev/null \
80+
-o ConnectTimeout=10 \
81+
jill@10.0.0.2 < /dev/null 2>/dev/null
82+
# ssh exit code is not reliable here since the server
83+
# closes the channel — check the server log instead
84+
sleep 1
85+
86+
# Cleanup
87+
sudo kill $SERVER_PID 2>/dev/null || true
88+
sudo ip link del veth0 2>/dev/null || true
89+
90+
# Verify the server accepted the SSH connection
91+
if grep -q "SSH connection accepted" /tmp/echo-server.log; then
92+
echo "PASS: server started, client authenticated, SSH session established"
93+
else
94+
echo "FAIL: SSH connection was not accepted"
95+
cat /tmp/echo-server.log
96+
exit 1
97+
fi

.gitmodules

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
1-
[submodule "make-testsuite/wolfssl"]
2-
path = make-testsuite/wolfssl
1+
[submodule "echo-server/FreeRTOS-Kernel"]
2+
path = echo-server/FreeRTOS-Kernel
3+
url = https://github.com/FreeRTOS/FreeRTOS-Kernel.git
4+
[submodule "echo-server/FreeRTOS-Plus-TCP"]
5+
path = echo-server/FreeRTOS-Plus-TCP
6+
url = https://github.com/FreeRTOS/FreeRTOS-Plus-TCP.git
7+
[submodule "wolfssl"]
8+
path = wolfssl
39
url = https://github.com/wolfSSL/wolfssl.git
4-
[submodule "make-testsuite/wolfssh"]
5-
path = make-testsuite/wolfssh
10+
[submodule "wolfssh"]
11+
path = wolfssh
612
url = https://github.com/wolfSSL/wolfssh.git

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,13 @@ The following examples are available for Espressif devices:
2323
* [ESP32-SSH-Server](./Espressif/ESP8266/ESP8266-SSH-Server/README.md)
2424
SSH-to-UART.
2525

26+
## echo-server
27+
28+
A minimal SSH echo server running on FreeRTOS with FreeRTOS-Plus-TCP networking.
29+
Targets PIC32MZ with Microchip Harmony but runnable on Linux using the FreeRTOS
30+
POSIX simulator and a libpcap-based network interface. Uses a Makefile and has a
31+
preconfigured user_settings.h file.
32+
2633
## make-testsuite
2734

2835
This example isn't manufacturer specific, but it has only been tested on

echo-server/.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
*.o
2+
*.a
3+
obj/
4+
keys/
5+
echo-server

echo-server/FreeRTOS-Kernel

Submodule FreeRTOS-Kernel added at 2624889

echo-server/FreeRTOS-Plus-TCP

Submodule FreeRTOS-Plus-TCP added at af6b379

echo-server/FreeRTOSConfig.h

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
/* FreeRTOSConfig.h
2+
*
3+
* Copyright (C) 2026 wolfSSL Inc.
4+
*
5+
* wolfSSH is free software; you can redistribute it and/or modify
6+
* it under the terms of the GNU General Public License as published by
7+
* the Free Software Foundation; either version 3 of the License, or
8+
* (at your option) any later version.
9+
*
10+
* wolfSSH is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
* GNU General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU General Public License
16+
* along with wolfSSH. If not, see <http://www.gnu.org/licenses/>.
17+
*/
18+
19+
#ifndef FREERTOS_CONFIG_H
20+
#define FREERTOS_CONFIG_H
21+
22+
/* Scheduler */
23+
#define configUSE_PREEMPTION 1
24+
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
25+
#define configUSE_TICKLESS_IDLE 0
26+
#define configCPU_CLOCK_HZ ( ( unsigned long ) 60000000 )
27+
#define configTICK_RATE_HZ ( ( TickType_t ) 1000 )
28+
#define configMAX_PRIORITIES 5
29+
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 8192 )
30+
#define configMAX_TASK_NAME_LEN 16
31+
#define configUSE_16_BIT_TICKS 0
32+
#define configIDLE_SHOULD_YIELD 1
33+
#define configUSE_TASK_NOTIFICATIONS 1
34+
#define configTASK_NOTIFICATION_ARRAY_ENTRIES 3
35+
#define configUSE_MUTEXES 1
36+
#define configUSE_RECURSIVE_MUTEXES 1
37+
#define configUSE_COUNTING_SEMAPHORES 1
38+
#define configQUEUE_REGISTRY_SIZE 10
39+
#define configUSE_QUEUE_SETS 0
40+
#define configUSE_TIME_SLICING 1
41+
#define configUSE_NEWLIB_REENTRANT 0
42+
#define configENABLE_BACKWARD_COMPATIBILITY 1
43+
#define configNUM_THREAD_LOCAL_STORAGE_POINTERS 5
44+
#define configUSE_MINI_LIST_ITEM 1
45+
46+
/* Memory */
47+
#define configSUPPORT_STATIC_ALLOCATION 0
48+
#define configSUPPORT_DYNAMIC_ALLOCATION 1
49+
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 256 * 1024 ) )
50+
#define configAPPLICATION_ALLOCATED_HEAP 0
51+
52+
/* Hook functions */
53+
#define configUSE_IDLE_HOOK 1
54+
#define configUSE_TICK_HOOK 0
55+
#define configCHECK_FOR_STACK_OVERFLOW 0
56+
#define configUSE_MALLOC_FAILED_HOOK 0
57+
#define configUSE_DAEMON_TASK_STARTUP_HOOK 0
58+
59+
/* Stats */
60+
#define configGENERATE_RUN_TIME_STATS 0
61+
#define configUSE_TRACE_FACILITY 0
62+
#define configUSE_STATS_FORMATTING_FUNCTIONS 0
63+
64+
/* Co-routines */
65+
#define configUSE_CO_ROUTINES 0
66+
#define configMAX_CO_ROUTINE_PRIORITIES 1
67+
68+
/* Software timers */
69+
#define configUSE_TIMERS 1
70+
#define configTIMER_TASK_PRIORITY ( configMAX_PRIORITIES - 1 )
71+
#define configTIMER_QUEUE_LENGTH 10
72+
#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE
73+
74+
/* Logging — used by FreeRTOS-Plus-TCP's FreeRTOS_printf / FreeRTOS_debug_printf */
75+
#define configPRINTF( X ) printf X
76+
77+
/* Assert is a no-op; define to assert() or abort() for debugging */
78+
#define configASSERT( x )
79+
80+
/* Optional functions */
81+
#define INCLUDE_vTaskPrioritySet 1
82+
#define INCLUDE_uxTaskPriorityGet 1
83+
#define INCLUDE_vTaskDelete 1
84+
#define INCLUDE_vTaskSuspend 1
85+
#define INCLUDE_xResumeFromISR 1
86+
#define INCLUDE_vTaskDelayUntil 1
87+
#define INCLUDE_vTaskDelay 1
88+
#define INCLUDE_xTaskGetSchedulerState 1
89+
#define INCLUDE_xTaskGetCurrentTaskHandle 1
90+
#define INCLUDE_uxTaskGetStackHighWaterMark 0
91+
#define INCLUDE_xTaskGetIdleTaskHandle 0
92+
#define INCLUDE_eTaskGetState 0
93+
#define INCLUDE_xEventGroupSetBitFromISR 1
94+
#define INCLUDE_xTimerPendFunctionCall 0
95+
#define INCLUDE_xTaskAbortDelay 0
96+
#define INCLUDE_xTaskGetHandle 0
97+
#define INCLUDE_xTaskResumeFromISR 1
98+
99+
/* POSIX port */
100+
#define configPOSIX_STACK_SIZE ( ( unsigned short ) 65536 )
101+
102+
#endif /* FREERTOS_CONFIG_H */

echo-server/FreeRTOSIPConfig.h

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
/* FreeRTOSIPConfig.h
2+
*
3+
* Copyright (C) 2026 wolfSSL Inc.
4+
*
5+
* wolfSSH is free software; you can redistribute it and/or modify
6+
* it under the terms of the GNU General Public License as published by
7+
* the Free Software Foundation; either version 3 of the License, or
8+
* (at your option) any later version.
9+
*
10+
* wolfSSH is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
* GNU General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU General Public License
16+
* along with wolfSSH. If not, see <http://www.gnu.org/licenses/>.
17+
*/
18+
19+
#ifndef FREERTOS_IP_CONFIG_H
20+
#define FREERTOS_IP_CONFIG_H
21+
22+
/* Use the backward-compatible single-interface FreeRTOS_IPInit() API */
23+
#define ipconfigIPv4_BACKWARD_COMPATIBLE 1
24+
#define ipconfigUSE_IPv6 0
25+
26+
/* TCP/IP task */
27+
#define ipconfigIP_TASK_PRIORITY ( configMAX_PRIORITIES - 2 )
28+
#define ipconfigIP_TASK_STACK_SIZE_WORDS ( configMINIMAL_STACK_SIZE * 4 )
29+
30+
/* Protocol support */
31+
#define ipconfigUSE_TCP 1
32+
#define ipconfigUSE_DNS 0
33+
#define ipconfigUSE_DHCP 0
34+
35+
/* Network tuning */
36+
#define ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS 60
37+
#define ipconfigNETWORK_MTU 1500
38+
#define ipconfigTCP_MSS ( ipconfigNETWORK_MTU - 40 )
39+
#define ipconfigTCP_RX_BUFFER_LENGTH ( 16 * 1024 )
40+
#define ipconfigTCP_TX_BUFFER_LENGTH ( 16 * 1024 )
41+
#define ipconfigTCP_WIN_SEG_COUNT 64
42+
43+
/* Event processing */
44+
#define ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES 1
45+
#define ipconfigETHERNET_MINIMUM_PACKET_BYTES 0
46+
#define ipconfigBUFFER_PADDING 0
47+
#define ipconfigPACKET_FILLER_SIZE 2
48+
#define ipconfigEVENT_QUEUE_LENGTH ( ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS + 5 )
49+
50+
/* ARP */
51+
#define ipconfigUSE_ARP_REMOVE_ENTRY 1
52+
#define ipconfigUSE_ARP_REVERSED_LOOKUP 1
53+
#define ipconfigARP_CACHE_ENTRIES 6
54+
#define ipconfigMAX_ARP_RETRANSMISSIONS 5
55+
#define ipconfigMAX_ARP_AGE 150
56+
57+
/* TCP parameters */
58+
#define ipconfigTCP_HANG_PROTECTION 1
59+
#define ipconfigTCP_HANG_PROTECTION_TIME 30
60+
#define ipconfigTCP_KEEP_ALIVE 1
61+
#define ipconfigTCP_KEEP_ALIVE_INTERVAL 20
62+
63+
/* Misc */
64+
#define ipconfigZERO_COPY_TX_DRIVER 0
65+
#define ipconfigZERO_COPY_RX_DRIVER 0
66+
#define ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM 0
67+
#define ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM 0
68+
#define ipconfigSUPPORT_OUTGOING_PINGS 1
69+
#define ipconfigREPLY_TO_INCOMING_PINGS 1
70+
#define ipconfigSUPPORT_SELECT_FUNCTION 0
71+
#define ipconfigFILTER_OUT_NON_ETHERNET_II_FRAMES 1
72+
#define ipconfigBYTE_ORDER pdFREERTOS_LITTLE_ENDIAN
73+
#define ipconfigHAS_DEBUG_PRINTF 0
74+
#define ipconfigHAS_PRINTF 1
75+
76+
/* Linux pcap network interface.
77+
* Override at compile time with -DipconfigNETWORK_INTERFACE_TO_USE=N */
78+
#ifndef ipconfigNETWORK_INTERFACE_TO_USE
79+
#define ipconfigNETWORK_INTERFACE_TO_USE 2
80+
#endif
81+
82+
/* Linux NetworkInterface.c requires these defines */
83+
#define configNETWORK_INTERFACE_TO_USE ipconfigNETWORK_INTERFACE_TO_USE
84+
#define configMAC_ISR_SIMULATOR_PRIORITY ( configMAX_PRIORITIES - 1 )
85+
#define configWINDOWS_MAC_INTERRUPT_SIMULATOR_DELAY ( 2 / portTICK_PERIOD_MS )
86+
#define configNET_MASK0 255
87+
#define configNET_MASK1 255
88+
#define configNET_MASK2 255
89+
#define configNET_MASK3 0
90+
91+
#endif /* FREERTOS_IP_CONFIG_H */

0 commit comments

Comments
 (0)