Skip to content
295 changes: 295 additions & 0 deletions ports_smp/cortex_a5_smp/gnu/example_build/build_threadx.sh

Large diffs are not rendered by default.

56 changes: 56 additions & 0 deletions ports_smp/cortex_a5_smp/gnu/example_build/build_threadx_sample.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#!/bin/sh
##############################################################################
# Copyright (c) 2026 Eclipse ThreadX contributors
#
# This program and the accompanying materials are made available under the
# terms of the MIT License which is available at
# https://opensource.org/licenses/MIT.
#
# SPDX-License-Identifier: MIT
##############################################################################

set -e
cd "$(dirname "$0")"

# this script builds the ThreadX sample image for the Cortex-A5 SMP port using
# GNU toolchain or llvm/clang toolchain (defaults to GNU).
: "${TOOLCHAIN:=gnu}"
case "${TOOLCHAIN}" in
gnu)
CC="arm-none-eabi-gcc"
TARGET_FLAGS=""
# GNU and Clang use different driver syntax for selecting the program's
# entry-point symbol.
ENTRY_FLAG="-e Vectors"
# Bare-metal C libraries require syscall support. GNU uses newlib's nosys stubs
# while ATFE requires a semihost library.
SYSCALL_LIB="--specs=nosys.specs"
;;
atfe)
CC="${ATFE_CLANG:-clang}"
TARGET_FLAGS="--target=arm-none-eabi"
ENTRY_FLAG="-Wl,--entry=Vectors"
SYSCALL_LIB="-lsemihost"
;;
*)
echo "Unknown TOOLCHAIN: ${TOOLCHAIN}" >&2
exit 1
;;
esac

"${CC}" ${TARGET_FLAGS} -c -g -I../../../../common_smp/inc -I../inc -mcpu=cortex-a5 sample_threadx.c
"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 startup.S
"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 crt0.S
"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 MP_GIC.S
"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 MP_SCU.S
"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 MP_Mutexes.S
"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 MP_PrivateTimer.S
"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 v7.S
"${CC}" ${TARGET_FLAGS} -g -mcpu=cortex-a5 -nostartfiles \
-T sample_threadx.ld \
${ENTRY_FLAG} \
${SYSCALL_LIB} \
-o sample_threadx.out \
MP_PrivateTimer.o MP_GIC.o MP_Mutexes.o MP_SCU.o \
sample_threadx.o startup.o crt0.o v7.o tx.a \
-Wl,-M > sample_threadx.map
101 changes: 101 additions & 0 deletions ports_smp/cortex_a5_smp/gnu/example_build/crt0.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@

.syntax unified
#if defined(THUMB_MODE)
.thumb
#else
.arm
#endif

/* .text is used instead of .section .text so it works with arm-aout too. */
.text
.align 0

#if defined(THUMB_MODE)
.thumb_func
#endif
.global _mainCRTStartup
_mainCRTStartup:
#if defined(THUMB_MODE)
.thumb_func
#endif
.global _start
_start:
#if defined(THUMB_MODE)
.thumb_func
#endif
.global start
start:

/* Start by setting up a stack */
/* Set up the stack pointer to a fixed value */
ldr r3, .LC0
mov sp, r3
/* Setup a default stack-limit in case the code has been
compiled with "-mapcs-stack-check". Hard-wiring this value
is not ideal, since there is currently no support for
checking that the heap and stack have not collided, or that
this default 64k is enough for the program being executed.
However, it ensures that this simple crt0 world will not
immediately cause an overflow event: */
sub sl, sp, #64 << 10 /* Still assumes 256bytes below sl */
mov a2, #0 /* Second arg: fill value */
mov fp, a2 /* Null frame pointer */
mov r7, a2 /* Null frame pointer for Thumb */

ldr a1, .LC1 /* First arg: start of memory block */
ldr a3, .LC2
sub a3, a3, a1 /* Third arg: length of block */



bl memset
mov r0, #0 /* no arguments */
mov r1, #0 /* no argv either */
#ifdef __USES_INITFINI__
/* Some arm/elf targets use the .init and .fini sections
to create constructors and destructors, and for these
targets we need to call the _init function and arrange
for _fini to be called at program exit. */
mov r4, r0
mov r5, r1
/* ldr r0, .Lfini */
bl atexit
/* bl init */
mov r0, r4
mov r1, r5
#endif
bl main

bl exit /* Should not return. */


/* For Thumb, constants must be after the code since only
positive offsets are supported for PC relative addresses. */

.align 0
.LC0:
.LC1:
.word __bss_start__
.LC2:
.word __bss_end__
/*
#ifdef __USES_INITFINI__
.Lfini:
.word _fini
#endif */
/* Return ... */
bx lr

.global _fini
.type _fini,function
_fini:
BX lr // Return to caller

/* Workspace for Angel calls. */
.data
/* Data returned by monitor SWI. */
.global __stack_base__
HeapBase: .word 0
HeapLimit: .word 0
__stack_base__: .word 0
StackLimit: .word 0
Loading