Skip to content

Commit 930034f

Browse files
authored
Added FreeRTOS example + test for STM32H5 (#79)
* Added FreeRTOS example + test for STM32H5 + added ssh test * Fixed freeRTOS dependency in new test * Addressed copilot's comments * Fix for FreeRTOS echo test * Addressed some copilot's comments, removed xor RNG (replaced xorshift-based unsecure RNG in STM32H5 demo with TRNG)
1 parent d655692 commit 930034f

16 files changed

Lines changed: 1263 additions & 50 deletions
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
name: STM32H563 m33mu FreeRTOS
2+
3+
on:
4+
push:
5+
pull_request:
6+
workflow_dispatch:
7+
8+
jobs:
9+
stm32h563_m33mu_echo_freertos:
10+
runs-on: ubuntu-latest
11+
container:
12+
image: ghcr.io/danielinux/m33mu-ci:1.8
13+
options: --privileged
14+
steps:
15+
- name: Checkout
16+
uses: actions/checkout@v4
17+
18+
- name: Run m33mu + DHCP + TCP echo FreeRTOS test
19+
run: /bin/bash tools/scripts/run-m33mu-ci-in-container.sh stm32h563-m33mu-freertos stm32h563_m33mu_echo_freertos
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
name: STM32H563 m33mu (SSH + TZEN)
2+
3+
on:
4+
push:
5+
branches: [ 'master', 'main', 'release/**' ]
6+
pull_request:
7+
branches: [ '*' ]
8+
9+
jobs:
10+
stm32h563_m33mu_ssh_tzen:
11+
runs-on: ubuntu-latest
12+
timeout-minutes: 25
13+
container:
14+
image: ghcr.io/danielinux/m33mu-ci:1.8
15+
options: --privileged
16+
17+
steps:
18+
- uses: actions/checkout@v4
19+
20+
- name: Install host tools
21+
run: |
22+
set -euo pipefail
23+
apt-get update
24+
apt-get install -y sudo dnsmasq iproute2 netcat-openbsd git \
25+
openssh-client sshpass
26+
27+
- name: Fetch wolfSSL/wolfSSH
28+
run: |
29+
set -euo pipefail
30+
if [ ! -d ../wolfssl ]; then
31+
git clone --depth 1 --branch master https://github.com/wolfSSL/wolfssl.git ../wolfssl
32+
fi
33+
if [ ! -d ../wolfssh ]; then
34+
git clone --depth 1 --branch master https://github.com/wolfSSL/wolfssh.git ../wolfssh
35+
fi
36+
37+
- name: Build STM32H563 SSH (TZEN on)
38+
run: |
39+
set -euo pipefail
40+
make -C src/port/stm32h563 clean TZEN=1 ENABLE_SSH=1
41+
make -C src/port/stm32h563 TZEN=1 ENABLE_SSH=1 \
42+
CC=arm-none-eabi-gcc OBJCOPY=arm-none-eabi-objcopy
43+
strings src/port/stm32h563/app.bin > /tmp/wolfip-app.strings
44+
grep -Fq "Initializing SSH server" /tmp/wolfip-app.strings
45+
46+
- name: Run m33mu + DHCP + SSH test
47+
timeout-minutes: 15
48+
run: |
49+
set -euo pipefail
50+
51+
cleanup() {
52+
set +e
53+
if [ -f /tmp/m33mu.pid ]; then
54+
sudo kill "$(cat /tmp/m33mu.pid)" 2>/dev/null || true
55+
fi
56+
sudo pkill -x m33mu 2>/dev/null || true
57+
if [ -f /tmp/dnsmasq.pid ]; then
58+
sudo kill "$(cat /tmp/dnsmasq.pid)" 2>/dev/null || true
59+
fi
60+
sudo ip link del tap0 2>/dev/null || true
61+
}
62+
trap cleanup EXIT
63+
64+
sudo ip tuntap add dev tap0 mode tap
65+
sudo ip addr add 192.168.12.1/24 dev tap0
66+
sudo ip link set tap0 up
67+
68+
cat > /tmp/dnsmasq.conf <<'CONF'
69+
interface=tap0
70+
bind-interfaces
71+
dhcp-range=192.168.12.50,192.168.12.100,255.255.255.0,12h
72+
dhcp-leasefile=/tmp/dnsmasq.leases
73+
log-dhcp
74+
CONF
75+
sudo dnsmasq --conf-file=/tmp/dnsmasq.conf --pid-file=/tmp/dnsmasq.pid
76+
77+
sudo m33mu src/port/stm32h563/app.bin \
78+
--cpu stm32h563 --tap:tap0 --uart-stdout --timeout 180 --quit-on-faults \
79+
2>&1 | tee /tmp/m33mu.log &
80+
sleep 1
81+
m33mu_pid="$(pgrep -n -x m33mu || true)"
82+
if [ -n "${m33mu_pid}" ]; then
83+
echo "${m33mu_pid}" > /tmp/m33mu.pid
84+
fi
85+
86+
ip=""
87+
for _ in $(seq 1 90); do
88+
if [ -s /tmp/dnsmasq.leases ]; then
89+
ip="$(tail -n1 /tmp/dnsmasq.leases | cut -d' ' -f3)"
90+
fi
91+
if [ -n "${ip}" ]; then
92+
break
93+
fi
94+
sleep 1
95+
done
96+
if [ -z "${ip}" ]; then
97+
echo "No DHCP lease acquired."
98+
echo "m33mu log:"
99+
tail -n 200 /tmp/m33mu.log || true
100+
exit 1
101+
fi
102+
echo "Leased IP: ${ip}"
103+
104+
ok=0
105+
for _ in $(seq 1 60); do
106+
if ! pgrep -x m33mu >/dev/null 2>&1; then
107+
echo "m33mu exited before SSH check."
108+
tail -n 200 /tmp/m33mu.log || true
109+
exit 1
110+
fi
111+
if timeout 10s bash -lc "printf '' | nc -w 5 '${ip}' 22" \
112+
| tee /tmp/ssh.log | grep -q "^SSH-2.0-"; then
113+
ok=1
114+
break
115+
fi
116+
sleep 0.5
117+
done
118+
if [ "${ok}" -ne 1 ]; then
119+
echo "SSH test failed."
120+
echo "m33mu log:"
121+
tail -n 200 /tmp/m33mu.log || true
122+
echo "ssh log:"
123+
tail -n 200 /tmp/ssh.log || true
124+
exit 1
125+
fi
126+
echo "SSH test succeeded."
127+
if [ -f /tmp/m33mu.pid ]; then
128+
sudo kill "$(cat /tmp/m33mu.pid)" 2>/dev/null || true
129+
fi

src/port/freeRTOS/bsd_socket.c

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,27 @@ static int wolfip_bsd_wait_unlocked(wolfip_bsd_fd_entry *entry)
187187
return 0;
188188
}
189189

190+
/* Some TCP core calls surface a temporary "not established yet" as -1 on a
191+
* freshly accepted stream socket before the final ACK promotes it to
192+
* ESTABLISHED. Allow a single wait/retry for that case without turning all
193+
* bare -1 returns into infinite retry loops. */
194+
static int wolfip_bsd_tcp_stream_retryable_once(int internal_fd, int ret, int *used)
195+
{
196+
if (ret != -1 || used == NULL || *used || !IS_SOCKET_TCP(internal_fd)) {
197+
return 0;
198+
}
199+
*used = 1;
200+
return 1;
201+
}
202+
203+
static int wolfip_bsd_tcp_recv_should_wait_locked(int internal_fd, int ret)
204+
{
205+
if (ret != -1 || !IS_SOCKET_TCP(internal_fd)) {
206+
return 0;
207+
}
208+
return wolfIP_sock_can_read(g_ipstack, internal_fd) == 0;
209+
}
210+
190211
int wolfip_freertos_socket_init(struct wolfIP *ipstack,
191212
UBaseType_t poll_task_priority,
192213
uint16_t poll_task_stack_words)
@@ -292,6 +313,7 @@ int accept(int sockfd, struct wolfIP_sockaddr *addr, socklen_t *addrlen)
292313
{
293314
int ret;
294315
int public_fd;
316+
int retried_minus_one = 0;
295317
wolfip_bsd_fd_entry *entry;
296318

297319
if (!wolfip_bsd_fd_valid(sockfd)) {
@@ -314,6 +336,17 @@ int accept(int sockfd, struct wolfIP_sockaddr *addr, socklen_t *addrlen)
314336
}
315337
return public_fd;
316338
}
339+
if (wolfip_bsd_tcp_stream_retryable_once(entry->internal_fd, ret,
340+
&retried_minus_one)) {
341+
wolfip_bsd_prepare_wait_locked(entry,
342+
(uint16_t)(CB_EVENT_READABLE | CB_EVENT_CLOSED));
343+
xSemaphoreGive(g_lock);
344+
if (wolfip_bsd_wait_unlocked(entry) < 0) {
345+
wolfip_bsd_set_error(WOLFIP_EAGAIN);
346+
return -1;
347+
}
348+
continue;
349+
}
317350
if (ret != -WOLFIP_EAGAIN) {
318351
xSemaphoreGive(g_lock);
319352
wolfip_bsd_set_error(ret);
@@ -364,6 +397,7 @@ int connect(int sockfd, const struct wolfIP_sockaddr *addr, socklen_t addrlen)
364397
int send(int sockfd, const void *buf, size_t len, int flags)
365398
{
366399
int ret;
400+
int retried_minus_one = 0;
367401
wolfip_bsd_fd_entry *entry;
368402

369403
if (!wolfip_bsd_fd_valid(sockfd)) {
@@ -378,6 +412,17 @@ int send(int sockfd, const void *buf, size_t len, int flags)
378412
xSemaphoreGive(g_lock);
379413
return ret;
380414
}
415+
if (wolfip_bsd_tcp_stream_retryable_once(entry->internal_fd, ret,
416+
&retried_minus_one)) {
417+
wolfip_bsd_prepare_wait_locked(entry,
418+
(uint16_t)(CB_EVENT_WRITABLE | CB_EVENT_READABLE | CB_EVENT_CLOSED));
419+
xSemaphoreGive(g_lock);
420+
if (wolfip_bsd_wait_unlocked(entry) < 0) {
421+
wolfip_bsd_set_error(WOLFIP_EAGAIN);
422+
return -1;
423+
}
424+
continue;
425+
}
381426
if (ret != -WOLFIP_EAGAIN) {
382427
xSemaphoreGive(g_lock);
383428
wolfip_bsd_set_error(ret);
@@ -397,6 +442,7 @@ int sendto(int sockfd, const void *buf, size_t len, int flags,
397442
const struct wolfIP_sockaddr *dest_addr, socklen_t addrlen)
398443
{
399444
int ret;
445+
int retried_minus_one = 0;
400446
wolfip_bsd_fd_entry *entry;
401447

402448
if (!wolfip_bsd_fd_valid(sockfd)) {
@@ -411,6 +457,17 @@ int sendto(int sockfd, const void *buf, size_t len, int flags,
411457
xSemaphoreGive(g_lock);
412458
return ret;
413459
}
460+
if (wolfip_bsd_tcp_stream_retryable_once(entry->internal_fd, ret,
461+
&retried_minus_one)) {
462+
wolfip_bsd_prepare_wait_locked(entry,
463+
(uint16_t)(CB_EVENT_WRITABLE | CB_EVENT_READABLE | CB_EVENT_CLOSED));
464+
xSemaphoreGive(g_lock);
465+
if (wolfip_bsd_wait_unlocked(entry) < 0) {
466+
wolfip_bsd_set_error(WOLFIP_EAGAIN);
467+
return -1;
468+
}
469+
continue;
470+
}
414471
if (ret != -WOLFIP_EAGAIN) {
415472
xSemaphoreGive(g_lock);
416473
wolfip_bsd_set_error(ret);
@@ -443,6 +500,16 @@ int recv(int sockfd, void *buf, size_t len, int flags)
443500
xSemaphoreGive(g_lock);
444501
return ret;
445502
}
503+
if (wolfip_bsd_tcp_recv_should_wait_locked(entry->internal_fd, ret)) {
504+
wolfip_bsd_prepare_wait_locked(entry,
505+
(uint16_t)(CB_EVENT_READABLE | CB_EVENT_WRITABLE | CB_EVENT_CLOSED));
506+
xSemaphoreGive(g_lock);
507+
if (wolfip_bsd_wait_unlocked(entry) < 0) {
508+
wolfip_bsd_set_error(WOLFIP_EAGAIN);
509+
return -1;
510+
}
511+
continue;
512+
}
446513
if (ret != -WOLFIP_EAGAIN) {
447514
xSemaphoreGive(g_lock);
448515
wolfip_bsd_set_error(ret);
@@ -476,6 +543,16 @@ int recvfrom(int sockfd, void *buf, size_t len, int flags,
476543
xSemaphoreGive(g_lock);
477544
return ret;
478545
}
546+
if (wolfip_bsd_tcp_recv_should_wait_locked(entry->internal_fd, ret)) {
547+
wolfip_bsd_prepare_wait_locked(entry,
548+
(uint16_t)(CB_EVENT_READABLE | CB_EVENT_WRITABLE | CB_EVENT_CLOSED));
549+
xSemaphoreGive(g_lock);
550+
if (wolfip_bsd_wait_unlocked(entry) < 0) {
551+
wolfip_bsd_set_error(WOLFIP_EAGAIN);
552+
return -1;
553+
}
554+
continue;
555+
}
479556
if (ret != -WOLFIP_EAGAIN) {
480557
xSemaphoreGive(g_lock);
481558
wolfip_bsd_set_error(ret);
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
#ifndef FREERTOS_CONFIG_H
2+
#define FREERTOS_CONFIG_H
3+
4+
#include <stdint.h>
5+
6+
extern uint32_t SystemCoreClock;
7+
8+
#define configUSE_PREEMPTION 1
9+
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
10+
#define configUSE_IDLE_HOOK 0
11+
#define configUSE_TICK_HOOK 0
12+
#define configCPU_CLOCK_HZ ( ( uint32_t ) 64000000 )
13+
#define configTICK_RATE_HZ ( ( TickType_t ) 1000 )
14+
#define configMAX_PRIORITIES 6
15+
#define configMINIMAL_STACK_SIZE ( ( uint16_t ) 256 )
16+
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 128 * 1024 ) )
17+
#define configMAX_TASK_NAME_LEN 16
18+
#define configUSE_TRACE_FACILITY 0
19+
#define configUSE_16_BIT_TICKS 0
20+
#define configIDLE_SHOULD_YIELD 1
21+
#define configUSE_MUTEXES 1
22+
#define configQUEUE_REGISTRY_SIZE 0
23+
#define configCHECK_FOR_STACK_OVERFLOW 2
24+
#define configUSE_RECURSIVE_MUTEXES 0
25+
#define configUSE_MALLOC_FAILED_HOOK 1
26+
#define configUSE_APPLICATION_TASK_TAG 0
27+
#define configUSE_COUNTING_SEMAPHORES 1
28+
#define configGENERATE_RUN_TIME_STATS 0
29+
#define configSUPPORT_DYNAMIC_ALLOCATION 1
30+
#define configSUPPORT_STATIC_ALLOCATION 0
31+
#define configUSE_TIMERS 1
32+
#define configTIMER_TASK_PRIORITY 2
33+
#define configTIMER_QUEUE_LENGTH 4
34+
#define configTIMER_TASK_STACK_DEPTH 256
35+
36+
#define configPRIO_BITS 4
37+
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 15
38+
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5
39+
#define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << ( 8 - configPRIO_BITS ) )
40+
#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << ( 8 - configPRIO_BITS ) )
41+
42+
#define configENABLE_FPU 0
43+
#define configENABLE_MVE 0
44+
#define configENABLE_MPU 0
45+
#define configENABLE_TRUSTZONE 0
46+
#define configRUN_FREERTOS_SECURE_ONLY 0
47+
48+
#define INCLUDE_vTaskPrioritySet 0
49+
#define INCLUDE_uxTaskPriorityGet 0
50+
#define INCLUDE_vTaskDelete 1
51+
#define INCLUDE_vTaskSuspend 0
52+
#define INCLUDE_xResumeFromISR 0
53+
#define INCLUDE_vTaskDelayUntil 0
54+
#define INCLUDE_vTaskDelay 1
55+
#define INCLUDE_xTaskGetSchedulerState 1
56+
#define INCLUDE_xTaskGetCurrentTaskHandle 1
57+
#define INCLUDE_xTaskGetTickCount 1
58+
#define INCLUDE_uxTaskGetStackHighWaterMark 1
59+
60+
#define xPortPendSVHandler PendSV_Handler
61+
#define vPortSVCHandler SVC_Handler
62+
#define xPortSysTickHandler SysTick_Handler
63+
64+
#define configASSERT( x ) do { if ( ( x ) == 0 ) { for ( ;; ) { } } } while (0)
65+
66+
#endif

0 commit comments

Comments
 (0)