Skip to content

Commit 7707e84

Browse files
authored
Merge pull request #60 from zevorn/feat/zynq-a9
platform: add Zynq-A9 QEMU target with standalone FreeRTOS
2 parents 937dc4b + d47aa81 commit 7707e84

63 files changed

Lines changed: 15979 additions & 5 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Makefile

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ help:
3434
@echo " make vexpress-a9-qemu Build QEMU vexpress-a9"
3535
@echo " make run-vexpress-a9-qemu Build + launch vexpress-a9"
3636
@echo ""
37+
@echo "Zynq-A9 (FreeRTOS):"
38+
@echo " make build-zynq-a9-qemu Build QEMU Zynq-A9"
39+
@echo " make run-zynq-a9-qemu Build + launch Zynq-A9"
40+
@echo ""
3741
@echo "Options:"
3842
@echo " GDB=1 Debug mode (GDB port 1234)"
3943
@echo " GRAPHICS=1 LCD display window (QEMU only)"
@@ -43,6 +47,7 @@ help:
4347
@echo ""
4448
@echo "Tests (unit — cross-compiled, QEMU semihosting):"
4549
@echo " make test-unit Build + run unit tests (vexpress-a9)"
50+
@echo " make test-unit-zynq Build + run unit tests (zynq-a9)"
4651
@echo ""
4752
@echo "Tests (functional — requires pre-built firmware):"
4853
@echo " make test-functional Run all functional tests"
@@ -55,6 +60,7 @@ help:
5560
@echo " make test-smoke-esp32c3 Smoke tests (ESP32-C3)"
5661
@echo " make test-smoke-esp32s3 Smoke tests (ESP32-S3)"
5762
@echo " make test-smoke-vexpress Smoke tests (vexpress-a9)"
63+
@echo " make test-smoke-zynq Smoke tests (zynq-a9)"
5864
@echo " make test-online-esp32c3 AI online tests (ESP32-C3)"
5965
@echo " make test-online-esp32s3 AI online tests (ESP32-S3)"
6066
@echo ""
@@ -102,6 +108,42 @@ run-vexpress-a9-qemu: vexpress-a9-qemu
102108
-nic user,model=lan9118 \
103109
$(if $(filter 1,$(GDB)),-S -s)
104110

111+
# --- Zynq-A9 QEMU (FreeRTOS) ---
112+
MESON_BUILDDIR_ZYNQ := $(BUILD_DIR)/zynq-a9-qemu
113+
CROSS_FILE_ZYNQ := platform/zynq-a9/cross.ini
114+
115+
.PHONY: build-zynq-a9-qemu
116+
build-zynq-a9-qemu:
117+
@if [ ! -f $(MESON_BUILDDIR_ZYNQ)/build.ninja ]; then \
118+
meson setup $(MESON_BUILDDIR_ZYNQ) --cross-file $(CROSS_FILE_ZYNQ); \
119+
fi
120+
meson compile -C $(MESON_BUILDDIR_ZYNQ)
121+
@echo "Output: $(MESON_BUILDDIR_ZYNQ)/platform/zynq-a9/rtclaw.elf"
122+
123+
.PHONY: run-zynq-a9-qemu
124+
run-zynq-a9-qemu: build-zynq-a9-qemu
125+
@if [ "$(GDB)" = "1" ]; then \
126+
echo "Starting QEMU in debug mode (GDB port 1234)..."; \
127+
echo "Connect: arm-none-eabi-gdb $(MESON_BUILDDIR_ZYNQ)/platform/zynq-a9/rtclaw.elf -ex 'target remote :1234'"; \
128+
fi
129+
qemu-system-arm \
130+
-M xilinx-zynq-a9 \
131+
-smp 1 \
132+
-nographic \
133+
-kernel $(MESON_BUILDDIR_ZYNQ)/platform/zynq-a9/rtclaw.elf \
134+
-nic user,model=cadence_gem \
135+
$(if $(filter 1,$(GDB)),-S -s)
136+
137+
138+
.PHONY: test-unit-zynq
139+
test-unit-zynq:
140+
python3 tests/unit/run_zynq.py
141+
142+
.PHONY: test-smoke-zynq
143+
test-smoke-zynq: build-zynq-a9-qemu
144+
RTCLAW_TEST_PLATFORM=zynq-a9-qemu python3 -m unittest discover \
145+
-s tests/functional -p 'test_boot.py' -v
146+
105147
# --- ESP32-C3 unified targets ---
106148
# Prerequisite: source $$HOME/esp/esp-idf/export.sh
107149
#

meson.build

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,23 @@ if osal_backend == 'rtthread'
4242
is_system: true,
4343
)
4444
elif osal_backend == 'freertos'
45-
# ESP-IDF defines and include paths are provided by the auto-generated
46-
# cross.ini (scripts/gen-esp32c3-cross.py). No platform_incs needed.
47-
platform_defs += ['-DCLAW_PLATFORM_ESP_IDF']
45+
_plat = get_option('platform')
46+
if _plat == 'zynq-a9'
47+
platform_defs += ['-DCLAW_PLATFORM_FREERTOS']
48+
platform_incs += include_directories(
49+
'vendor/os/freertos/include',
50+
'vendor/os/freertos/portable/GCC/ARM_CA9',
51+
'vendor/bsp/xilinx',
52+
'vendor/bsp/xilinx/standalone/common',
53+
'vendor/bsp/xilinx/standalone/cortexa9',
54+
'vendor/bsp/xilinx/drivers/scugic',
55+
'vendor/bsp/xilinx/drivers/scutimer',
56+
'platform/zynq-a9',
57+
is_system: true,
58+
)
59+
else
60+
platform_defs += ['-DCLAW_PLATFORM_ESP_IDF']
61+
endif
4862
endif
4963

5064
# ---- Unified configuration via claw_config_generated.h ----
@@ -127,3 +141,8 @@ subdir('vendor/lib/cjson')
127141
subdir('osal')
128142
subdir('claw')
129143
subdir('tests/unit')
144+
145+
_fw_plat = get_option('platform')
146+
if _fw_plat == 'zynq-a9'
147+
subdir('platform/zynq-a9')
148+
endif

meson_options.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ option('osal', type: 'combo',
22
choices: ['rtthread', 'freertos', 'none'],
33
value: 'none',
44
description: 'OSAL backend (none = library only, no OSAL compiled)')
5+
option('platform', type: 'string', value: '',
6+
description: 'Target platform for full firmware build (zynq-a9)')
57
option('rtthread_bsp', type: 'string', value: 'platform/vexpress-a9',
68
description: 'RT-Thread BSP directory for rtconfig.h/lwipopts.h')
79
option('rtthread_cpuport', type: 'string',

osal/freertos/claw_net_freertos.c

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,21 @@
22
* Copyright (c) 2026, Chao Liu <chao.liu.zevorn@gmail.com>
33
* SPDX-License-Identifier: MIT
44
*
5-
* OSAL network — ESP-IDF implementation using esp_http_client.
5+
* OSAL network — FreeRTOS implementation.
6+
* ESP-IDF: uses esp_http_client (full HTTPS)
7+
* Standalone: stub (network added in later phase)
68
*/
79

810
#include "osal/claw_os.h"
911
#include "osal/claw_net.h"
1012

13+
#include <string.h>
14+
15+
#ifdef CLAW_PLATFORM_ESP_IDF
16+
1117
#include "esp_http_client.h"
1218
#include "esp_crt_bundle.h"
1319

14-
#include <string.h>
1520

1621
#define TAG "net_http"
1722
#define HTTP_TIMEOUT_MS 60000
@@ -126,8 +131,45 @@ int claw_net_get(const char *url,
126131
return CLAW_ERROR;
127132
}
128133

134+
if (resp_len) {
135+
*resp_len = ctx.len;
136+
}
129137
if (resp_len) {
130138
*resp_len = ctx.len;
131139
}
132140
return status;
133141
}
142+
143+
#else /* Standalone FreeRTOS stub */
144+
145+
#define TAG "net_stub"
146+
147+
int claw_net_post(const char *url,
148+
const claw_net_header_t *headers, int header_count,
149+
const char *body, size_t body_len,
150+
char *resp, size_t resp_size, size_t *resp_len)
151+
{
152+
(void)url; (void)headers; (void)header_count;
153+
(void)body; (void)body_len;
154+
(void)resp; (void)resp_size;
155+
if (resp_len) {
156+
*resp_len = 0;
157+
}
158+
CLAW_LOGW(TAG, "net_post: not implemented (standalone FreeRTOS)");
159+
return CLAW_ERROR;
160+
}
161+
162+
int claw_net_get(const char *url,
163+
const claw_net_header_t *headers, int header_count,
164+
char *resp, size_t resp_size, size_t *resp_len)
165+
{
166+
(void)url; (void)headers; (void)header_count;
167+
(void)resp; (void)resp_size;
168+
if (resp_len) {
169+
*resp_len = 0;
170+
}
171+
CLAW_LOGW(TAG, "net_get: not implemented (standalone FreeRTOS)");
172+
return CLAW_ERROR;
173+
}
174+
175+
#endif /* CLAW_PLATFORM_ESP_IDF */

platform/zynq-a9/FreeRTOSConfig.h

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
/* SPDX-License-Identifier: MIT */
2+
/*
3+
* FreeRTOS configuration for QEMU Xilinx Zynq-7000 (Cortex-A9)
4+
*
5+
* Based on the FreeRTOS official Zynq QEMU Demo configuration,
6+
* adapted for rt-claw embedded AI assistant platform.
7+
*/
8+
9+
#ifndef FREERTOS_CONFIG_H
10+
#define FREERTOS_CONFIG_H
11+
12+
#include "xparameters.h"
13+
14+
/*-----------------------------------------------------------
15+
* Application-specific definitions
16+
*----------------------------------------------------------*/
17+
18+
/* Scheduling */
19+
#define configUSE_PREEMPTION 1
20+
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
21+
#define configUSE_TICKLESS_IDLE 0
22+
#define configCPU_CLOCK_HZ 100000000UL
23+
#define configTICK_RATE_HZ 1000
24+
#define configMAX_PRIORITIES 8
25+
#define configMINIMAL_STACK_SIZE 256
26+
#define configMAX_TASK_NAME_LEN 16
27+
#define configIDLE_SHOULD_YIELD 1
28+
29+
/* Memory */
30+
#define configTOTAL_HEAP_SIZE (512 * 1024)
31+
#define configSUPPORT_STATIC_ALLOCATION 0
32+
#define configSUPPORT_DYNAMIC_ALLOCATION 1
33+
34+
/* Data types */
35+
#define configUSE_16_BIT_TICKS 0
36+
#define configTASK_RETURN_ADDRESS NULL
37+
38+
/* Hooks */
39+
#define configUSE_IDLE_HOOK 0
40+
#define configUSE_TICK_HOOK 0
41+
#define configCHECK_FOR_STACK_OVERFLOW 2
42+
#define configUSE_MALLOC_FAILED_HOOK 1
43+
44+
/* Synchronization */
45+
#define configUSE_MUTEXES 1
46+
#define configUSE_RECURSIVE_MUTEXES 1
47+
#define configUSE_COUNTING_SEMAPHORES 1
48+
#define configQUEUE_REGISTRY_SIZE 8
49+
50+
/* Software timers */
51+
#define configUSE_TIMERS 1
52+
#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES - 1)
53+
#define configTIMER_QUEUE_LENGTH 10
54+
#define configTIMER_TASK_STACK_DEPTH (configMINIMAL_STACK_SIZE * 2)
55+
56+
/* Trace and stats */
57+
#define configUSE_TRACE_FACILITY 1
58+
#define configGENERATE_RUN_TIME_STATS 0
59+
#define configUSE_STATS_FORMATTING_FUNCTIONS 0
60+
61+
/* Co-routines (unused) */
62+
#define configUSE_CO_ROUTINES 0
63+
#define configMAX_CO_ROUTINE_PRIORITIES 2
64+
65+
/* FPU support: all tasks save/restore FPU context */
66+
#define configUSE_TASK_FPU_SUPPORT 2
67+
68+
/* QEMU marker */
69+
#define configUSING_QEMU 1
70+
71+
/*-----------------------------------------------------------
72+
* Optional function inclusion
73+
*----------------------------------------------------------*/
74+
75+
#define INCLUDE_vTaskPrioritySet 1
76+
#define INCLUDE_uxTaskPriorityGet 1
77+
#define INCLUDE_vTaskDelete 1
78+
#define INCLUDE_vTaskCleanUpResources 1
79+
#define INCLUDE_vTaskSuspend 1
80+
#define INCLUDE_vTaskDelayUntil 1
81+
#define INCLUDE_vTaskDelay 1
82+
#define INCLUDE_xTimerPendFunctionCall 1
83+
#define INCLUDE_eTaskGetState 1
84+
85+
/*-----------------------------------------------------------
86+
* Zynq-7000 GIC (Generic Interrupt Controller) configuration
87+
*----------------------------------------------------------*/
88+
89+
#define configINTERRUPT_CONTROLLER_BASE_ADDRESS XPAR_PS7_SCUGIC_0_DIST_BASEADDR
90+
#define configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET (-0xf00)
91+
#define configUNIQUE_INTERRUPT_PRIORITIES 32
92+
#define configMAX_API_CALL_INTERRUPT_PRIORITY 18
93+
94+
/*-----------------------------------------------------------
95+
* Tick interrupt setup (provided by platform port)
96+
*----------------------------------------------------------*/
97+
98+
void vConfigureTickInterrupt(void);
99+
#define configSETUP_TICK_INTERRUPT() vConfigureTickInterrupt()
100+
101+
void vClearTickInterrupt(void);
102+
#define configCLEAR_TICK_INTERRUPT() vClearTickInterrupt()
103+
104+
/*-----------------------------------------------------------
105+
* Assert and debug
106+
*----------------------------------------------------------*/
107+
108+
void vAssertCalled(const char *pcFile, unsigned long ulLine);
109+
#define configASSERT(x) \
110+
do { \
111+
if ((x) == 0) { \
112+
vAssertCalled(__FILE__, __LINE__); \
113+
} \
114+
} while (0)
115+
116+
#endif /* FREERTOS_CONFIG_H */

0 commit comments

Comments
 (0)