Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions .github/workflows/stm32h563-m33mu-freertos.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
name: STM32H563 m33mu FreeRTOS

on:
push:
pull_request:
workflow_dispatch:

jobs:
stm32h563_m33mu_echo_freertos:
runs-on: ubuntu-latest
container:
image: ghcr.io/danielinux/m33mu-ci:1.8
options: --privileged
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Run m33mu + DHCP + TCP echo FreeRTOS test
run: /bin/bash tools/scripts/run-m33mu-ci-in-container.sh stm32h563-m33mu-freertos stm32h563_m33mu_echo_freertos
129 changes: 129 additions & 0 deletions .github/workflows/stm32h563-m33mu-ssh-tzen.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
name: STM32H563 m33mu (SSH + TZEN)

on:
push:
branches: [ 'master', 'main', 'release/**' ]
pull_request:
branches: [ '*' ]

jobs:
stm32h563_m33mu_ssh_tzen:
runs-on: ubuntu-latest
timeout-minutes: 25
container:
image: ghcr.io/danielinux/m33mu-ci:1.8
options: --privileged

steps:
- uses: actions/checkout@v4

- name: Install host tools
run: |
set -euo pipefail
apt-get update
apt-get install -y sudo dnsmasq iproute2 netcat-openbsd git \
openssh-client sshpass

- name: Fetch wolfSSL/wolfSSH
run: |
set -euo pipefail
if [ ! -d ../wolfssl ]; then
git clone --depth 1 --branch master https://github.com/wolfSSL/wolfssl.git ../wolfssl
fi
if [ ! -d ../wolfssh ]; then
git clone --depth 1 --branch master https://github.com/wolfSSL/wolfssh.git ../wolfssh
fi

- name: Build STM32H563 SSH (TZEN on)
run: |
set -euo pipefail
make -C src/port/stm32h563 clean TZEN=1 ENABLE_SSH=1
make -C src/port/stm32h563 TZEN=1 ENABLE_SSH=1 \
CC=arm-none-eabi-gcc OBJCOPY=arm-none-eabi-objcopy
strings src/port/stm32h563/app.bin > /tmp/wolfip-app.strings
grep -Fq "Initializing SSH server" /tmp/wolfip-app.strings

- name: Run m33mu + DHCP + SSH test
timeout-minutes: 15
run: |
set -euo pipefail

cleanup() {
set +e
if [ -f /tmp/m33mu.pid ]; then
sudo kill "$(cat /tmp/m33mu.pid)" 2>/dev/null || true
fi
sudo pkill -x m33mu 2>/dev/null || true
if [ -f /tmp/dnsmasq.pid ]; then
sudo kill "$(cat /tmp/dnsmasq.pid)" 2>/dev/null || true
fi
sudo ip link del tap0 2>/dev/null || true
}
trap cleanup EXIT

sudo ip tuntap add dev tap0 mode tap
sudo ip addr add 192.168.12.1/24 dev tap0
sudo ip link set tap0 up

cat > /tmp/dnsmasq.conf <<'CONF'
interface=tap0
bind-interfaces
dhcp-range=192.168.12.50,192.168.12.100,255.255.255.0,12h
dhcp-leasefile=/tmp/dnsmasq.leases
log-dhcp
CONF
sudo dnsmasq --conf-file=/tmp/dnsmasq.conf --pid-file=/tmp/dnsmasq.pid

sudo m33mu src/port/stm32h563/app.bin \
--cpu stm32h563 --tap:tap0 --uart-stdout --timeout 180 --quit-on-faults \
2>&1 | tee /tmp/m33mu.log &
sleep 1
m33mu_pid="$(pgrep -n -x m33mu || true)"
if [ -n "${m33mu_pid}" ]; then
echo "${m33mu_pid}" > /tmp/m33mu.pid
fi

ip=""
for _ in $(seq 1 90); do
if [ -s /tmp/dnsmasq.leases ]; then
ip="$(tail -n1 /tmp/dnsmasq.leases | cut -d' ' -f3)"
fi
if [ -n "${ip}" ]; then
break
fi
sleep 1
done
if [ -z "${ip}" ]; then
echo "No DHCP lease acquired."
echo "m33mu log:"
tail -n 200 /tmp/m33mu.log || true
exit 1
fi
echo "Leased IP: ${ip}"

ok=0
for _ in $(seq 1 60); do
if ! pgrep -x m33mu >/dev/null 2>&1; then
echo "m33mu exited before SSH check."
tail -n 200 /tmp/m33mu.log || true
exit 1
fi
if timeout 10s bash -lc "printf '' | nc -w 5 '${ip}' 22" \
| tee /tmp/ssh.log | grep -q "^SSH-2.0-"; then
ok=1
break
fi
sleep 0.5
done
if [ "${ok}" -ne 1 ]; then
echo "SSH test failed."
echo "m33mu log:"
tail -n 200 /tmp/m33mu.log || true
echo "ssh log:"
tail -n 200 /tmp/ssh.log || true
exit 1
fi
echo "SSH test succeeded."
if [ -f /tmp/m33mu.pid ]; then
sudo kill "$(cat /tmp/m33mu.pid)" 2>/dev/null || true
fi
77 changes: 77 additions & 0 deletions src/port/freeRTOS/bsd_socket.c
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,27 @@ static int wolfip_bsd_wait_unlocked(wolfip_bsd_fd_entry *entry)
return 0;
}

/* Some TCP core calls surface a temporary "not established yet" as -1 on a
* freshly accepted stream socket before the final ACK promotes it to
* ESTABLISHED. Allow a single wait/retry for that case without turning all
* bare -1 returns into infinite retry loops. */
static int wolfip_bsd_tcp_stream_retryable_once(int internal_fd, int ret, int *used)
{
if (ret != -1 || used == NULL || *used || !IS_SOCKET_TCP(internal_fd)) {
return 0;
}
*used = 1;
return 1;
}

static int wolfip_bsd_tcp_recv_should_wait_locked(int internal_fd, int ret)
{
if (ret != -1 || !IS_SOCKET_TCP(internal_fd)) {
return 0;
}
return wolfIP_sock_can_read(g_ipstack, internal_fd) == 0;
}

int wolfip_freertos_socket_init(struct wolfIP *ipstack,
UBaseType_t poll_task_priority,
uint16_t poll_task_stack_words)
Expand Down Expand Up @@ -292,6 +313,7 @@ int accept(int sockfd, struct wolfIP_sockaddr *addr, socklen_t *addrlen)
{
int ret;
int public_fd;
int retried_minus_one = 0;
wolfip_bsd_fd_entry *entry;

if (!wolfip_bsd_fd_valid(sockfd)) {
Expand All @@ -314,6 +336,17 @@ int accept(int sockfd, struct wolfIP_sockaddr *addr, socklen_t *addrlen)
}
return public_fd;
}
if (wolfip_bsd_tcp_stream_retryable_once(entry->internal_fd, ret,
&retried_minus_one)) {
wolfip_bsd_prepare_wait_locked(entry,
(uint16_t)(CB_EVENT_READABLE | CB_EVENT_CLOSED));
xSemaphoreGive(g_lock);
if (wolfip_bsd_wait_unlocked(entry) < 0) {
wolfip_bsd_set_error(WOLFIP_EAGAIN);
return -1;
}
continue;
}
if (ret != -WOLFIP_EAGAIN) {
xSemaphoreGive(g_lock);
wolfip_bsd_set_error(ret);
Expand Down Expand Up @@ -364,6 +397,7 @@ int connect(int sockfd, const struct wolfIP_sockaddr *addr, socklen_t addrlen)
int send(int sockfd, const void *buf, size_t len, int flags)
{
int ret;
int retried_minus_one = 0;
wolfip_bsd_fd_entry *entry;

if (!wolfip_bsd_fd_valid(sockfd)) {
Expand All @@ -378,6 +412,17 @@ int send(int sockfd, const void *buf, size_t len, int flags)
xSemaphoreGive(g_lock);
return ret;
}
if (wolfip_bsd_tcp_stream_retryable_once(entry->internal_fd, ret,
&retried_minus_one)) {
wolfip_bsd_prepare_wait_locked(entry,
(uint16_t)(CB_EVENT_WRITABLE | CB_EVENT_READABLE | CB_EVENT_CLOSED));
xSemaphoreGive(g_lock);
if (wolfip_bsd_wait_unlocked(entry) < 0) {
wolfip_bsd_set_error(WOLFIP_EAGAIN);
return -1;
}
continue;
}
if (ret != -WOLFIP_EAGAIN) {
xSemaphoreGive(g_lock);
wolfip_bsd_set_error(ret);
Expand All @@ -397,6 +442,7 @@ int sendto(int sockfd, const void *buf, size_t len, int flags,
const struct wolfIP_sockaddr *dest_addr, socklen_t addrlen)
{
int ret;
int retried_minus_one = 0;
wolfip_bsd_fd_entry *entry;

if (!wolfip_bsd_fd_valid(sockfd)) {
Expand All @@ -411,6 +457,17 @@ int sendto(int sockfd, const void *buf, size_t len, int flags,
xSemaphoreGive(g_lock);
return ret;
}
if (wolfip_bsd_tcp_stream_retryable_once(entry->internal_fd, ret,
&retried_minus_one)) {
wolfip_bsd_prepare_wait_locked(entry,
(uint16_t)(CB_EVENT_WRITABLE | CB_EVENT_READABLE | CB_EVENT_CLOSED));
xSemaphoreGive(g_lock);
if (wolfip_bsd_wait_unlocked(entry) < 0) {
wolfip_bsd_set_error(WOLFIP_EAGAIN);
return -1;
}
continue;
}
if (ret != -WOLFIP_EAGAIN) {
xSemaphoreGive(g_lock);
wolfip_bsd_set_error(ret);
Expand Down Expand Up @@ -443,6 +500,16 @@ int recv(int sockfd, void *buf, size_t len, int flags)
xSemaphoreGive(g_lock);
return ret;
}
if (wolfip_bsd_tcp_recv_should_wait_locked(entry->internal_fd, ret)) {
wolfip_bsd_prepare_wait_locked(entry,
(uint16_t)(CB_EVENT_READABLE | CB_EVENT_WRITABLE | CB_EVENT_CLOSED));
xSemaphoreGive(g_lock);
if (wolfip_bsd_wait_unlocked(entry) < 0) {
wolfip_bsd_set_error(WOLFIP_EAGAIN);
return -1;
}
continue;
}
if (ret != -WOLFIP_EAGAIN) {
xSemaphoreGive(g_lock);
wolfip_bsd_set_error(ret);
Expand Down Expand Up @@ -476,6 +543,16 @@ int recvfrom(int sockfd, void *buf, size_t len, int flags,
xSemaphoreGive(g_lock);
return ret;
}
if (wolfip_bsd_tcp_recv_should_wait_locked(entry->internal_fd, ret)) {
wolfip_bsd_prepare_wait_locked(entry,
(uint16_t)(CB_EVENT_READABLE | CB_EVENT_WRITABLE | CB_EVENT_CLOSED));
xSemaphoreGive(g_lock);
if (wolfip_bsd_wait_unlocked(entry) < 0) {
wolfip_bsd_set_error(WOLFIP_EAGAIN);
return -1;
}
continue;
}
if (ret != -WOLFIP_EAGAIN) {
xSemaphoreGive(g_lock);
wolfip_bsd_set_error(ret);
Expand Down
66 changes: 66 additions & 0 deletions src/port/stm32h563/FreeRTOSConfig.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H

#include <stdint.h>

extern uint32_t SystemCoreClock;

#define configUSE_PREEMPTION 1
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
#define configUSE_IDLE_HOOK 0
#define configUSE_TICK_HOOK 0
#define configCPU_CLOCK_HZ ( ( uint32_t ) 64000000 )
#define configTICK_RATE_HZ ( ( TickType_t ) 1000 )
#define configMAX_PRIORITIES 6
#define configMINIMAL_STACK_SIZE ( ( uint16_t ) 256 )
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 128 * 1024 ) )
#define configMAX_TASK_NAME_LEN 16
#define configUSE_TRACE_FACILITY 0
#define configUSE_16_BIT_TICKS 0
#define configIDLE_SHOULD_YIELD 1
#define configUSE_MUTEXES 1
#define configQUEUE_REGISTRY_SIZE 0
#define configCHECK_FOR_STACK_OVERFLOW 2
#define configUSE_RECURSIVE_MUTEXES 0
#define configUSE_MALLOC_FAILED_HOOK 1
#define configUSE_APPLICATION_TASK_TAG 0
#define configUSE_COUNTING_SEMAPHORES 1
#define configGENERATE_RUN_TIME_STATS 0
#define configSUPPORT_DYNAMIC_ALLOCATION 1
#define configSUPPORT_STATIC_ALLOCATION 0
#define configUSE_TIMERS 1
#define configTIMER_TASK_PRIORITY 2
#define configTIMER_QUEUE_LENGTH 4
#define configTIMER_TASK_STACK_DEPTH 256

#define configPRIO_BITS 4
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 15
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5
#define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << ( 8 - configPRIO_BITS ) )
#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << ( 8 - configPRIO_BITS ) )

#define configENABLE_FPU 0
#define configENABLE_MVE 0
#define configENABLE_MPU 0
#define configENABLE_TRUSTZONE 0
#define configRUN_FREERTOS_SECURE_ONLY 0

#define INCLUDE_vTaskPrioritySet 0
#define INCLUDE_uxTaskPriorityGet 0
#define INCLUDE_vTaskDelete 1
#define INCLUDE_vTaskSuspend 0
#define INCLUDE_xResumeFromISR 0
#define INCLUDE_vTaskDelayUntil 0
#define INCLUDE_vTaskDelay 1
#define INCLUDE_xTaskGetSchedulerState 1
#define INCLUDE_xTaskGetCurrentTaskHandle 1
#define INCLUDE_xTaskGetTickCount 1
#define INCLUDE_uxTaskGetStackHighWaterMark 1

#define xPortPendSVHandler PendSV_Handler
#define vPortSVCHandler SVC_Handler
#define xPortSysTickHandler SysTick_Handler

#define configASSERT( x ) do { if ( ( x ) == 0 ) { for ( ;; ) { } } } while (0)

#endif
Loading
Loading