Skip to content
Open
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
37 changes: 37 additions & 0 deletions cmake/xtensa.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_SYSTEM_PROCESSOR xtensa)

set(CMAKE_C_COMPILER xt-clang)
set(CMAKE_CXX_COMPILER xt-clang++)
set(AS xt-clang)
set(AR xt-ar)
set(OBJCOPY xt-objcopy)
set(OBJDUMP xt-objdump)
set(SIZE xt-size)

set(THREADX_ARCH "xtensa")
set(THREADX_TOOLCHAIN "xcc")

if (DEFINED ENV{XCC_OPTS})
set(XCC_OPTS $ENV{XCC_OPTS})
else()
set(XCC_OPTS "")
endif()

set(XCC_FLAGS "${XCC_OPTS} -mlongcalls -mno-l32r-flix -mno-coproc -Wall -Wextra -Werror")

set(CMAKE_C_FLAGS "${XCC_FLAGS} -Os -g" CACHE INTERNAL "c compiler flags")
set(CMAKE_CXX_FLAGS "${XCC_FLAGS} -Os -g -fno-rtti -fno-exceptions" CACHE INTERNAL "cxx compiler flags")
set(CMAKE_ASM_FLAGS "${XCC_FLAGS} -Os -g" CACHE INTERNAL "asm compiler flags")
set(CMAKE_EXE_LINKER_FLAGS "${XCC_FLAGS} ${LD_FLAGS} -Wl,--gc-sections" CACHE INTERNAL "exe link flags")

SET(CMAKE_C_FLAGS_DEBUG "-O0 -g" CACHE INTERNAL "c debug compiler flags")
SET(CMAKE_CXX_FLAGS_DEBUG "-O0 -g" CACHE INTERNAL "cxx debug compiler flags")
SET(CMAKE_ASM_FLAGS_DEBUG "-O0 -g" CACHE INTERNAL "asm debug compiler flags")

SET(CMAKE_C_FLAGS_RELEASE "-Os -g" CACHE INTERNAL "c release compiler flags")
SET(CMAKE_CXX_FLAGS_RELEASE "-Os -g" CACHE INTERNAL "cxx release compiler flags")
SET(CMAKE_ASM_FLAGS_RELEASE "-Os -g" CACHE INTERNAL "asm release compiler flags")

# this makes the test compiles use static library option so that we don't need to pre-set linker flags and scripts
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
5 changes: 4 additions & 1 deletion ports/xtensa/xcc/inc/tx_port.h
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,10 @@ typedef unsigned short USHORT;
#define TX_THREAD_EXTENSION_2

/* Execution profile related */
#define TX_THREAD_EXTENSION_3
#define TX_THREAD_EXTENSION_3 \
unsigned long long tx_thread_execution_time_total; \
unsigned long tx_thread_execution_time_last_start;


/* Define the port extensions of the remaining ThreadX objects. */

Expand Down
20 changes: 6 additions & 14 deletions ports/xtensa/xcc/inc/xtensa_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -373,19 +373,8 @@ XSTRUCT_END(XtExcFrame)
#endif
#endif


/*
-------------------------------------------------------------------------------
This flag is meant for internal use. Have all interrupts be dispatched via a
common wrapper, which takes care of doing some OS-specific stuff common to
all interrupt handlers. Said stuff cannot safely be handled in the RTOS_ENTER
and RTOS_EXIT macros.
-------------------------------------------------------------------------------
*/
#if (defined TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || (defined XT_INTEXC_HOOKS)
#define XT_USE_INT_WRAPPER 1
#else
#define XT_USE_INT_WRAPPER 0
#if XCHAL_HAVE_XEA2 && (XCHAL_NUM_INTERRUPTS > 32) && (defined XT_USE_SWPRI)
#error "Software prioritization of interrupts (XT_USE_SWPRI) not supported for XEA2 with > 32 interrupts."
#endif

#if XCHAL_HAVE_XEA3
Expand Down Expand Up @@ -500,12 +489,15 @@ XSTRUCT_END(XtExcFrame)

#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
// Call the thread entry function to indicate the thread is executing.
// SP should be pointing to a safe region at this point.
// SP should be pointing to a safe region at this point. Note that a9
// may be trashed by this call, must be reloaded.
#ifdef __XTENSA_CALL0_ABI__
call0 _tx_execution_thread_enter
#else
call8 _tx_execution_thread_enter
#endif
movi a9, _tx_thread_current_ptr // a9 <- &_tx_thread_current_ptr
l32i a9, a9, 0 // a9 <- _tx_thread_current_ptr
#endif

l32i a2, a9, tx_thread_solicited // a2 = solicited flag
Expand Down
4 changes: 4 additions & 0 deletions ports/xtensa/xcc/inc/xtensa_rtos.h
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,11 @@ To enable interrupt/exception hooks, compile the RTOS with '-DXT_INTEXC_HOOKS'.
#define XT_INTEXC_HOOK_NUM (1 + XCHAL_NUM_INTLEVELS + XCHAL_HAVE_NMI)

#ifndef __ASSEMBLER__
#if XCHAL_HAVE_XEA2 && (XCHAL_NUM_INTERRUPTS > 32)
typedef uint32_t (*XT_INTEXC_HOOK)(uint32_t cause, uint32_t block);
#else
typedef uint32_t (*XT_INTEXC_HOOK)(uint32_t cause);
#endif
extern volatile XT_INTEXC_HOOK _xt_intexc_hooks[XT_INTEXC_HOOK_NUM];
#endif

Expand Down
14 changes: 13 additions & 1 deletion ports/xtensa/xcc/inc/xtensa_timer.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,19 @@ Otherwise select the first low or medium priority interrupt timer available.
#define XT_TIMER_INTPRI XCHAL_INT_LEVEL(XT_TIMER_INTNUM)

#if XCHAL_HAVE_XEA2
#define XT_TIMER_INTEN (1 << XT_TIMER_INTNUM)
/*
* Xtensa LX8 supports up to 128 interrupts whereas LX7 supports up to 32.
*
* Redefine the legacy XT_TIMER_INTEN (which limited the interrupt number to
* be in the lower 32 or lower 64 bits depending on data type) as two defines
* describing the INTEN bit within a 32-bit component and a 4-block component,
* where each block contains a group of 32 interrupt bits.
*
* Name changes are intentional such that any dependencies are caught at
* compile-time and are found regardless of timer configuration.
*/
#define XT_TIMER_INTEN_BIT (1 << (XT_TIMER_INTNUM & 31U))
#define XT_TIMER_INTEN_BLK (XT_TIMER_INTNUM >> 5)
#endif

#if XT_TIMER_INDEX == 0
Expand Down
182 changes: 47 additions & 135 deletions ports/xtensa/xcc/readme_threadx.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ processor configuration options:
- Timer interrupt option with at least one interruptible timer for ThreadX.
- Interrupt option (implied by the timer interrupt option).
- Xtensa Exception Architecture 2 (XEA2) or Exception Architecture 3 (XEA3).
Please note that XEA1 is NOT supported.

Minimal support for certain evaluation boards is provided via a board
independent "XTBSP" API implemented by a board specific library. This
Expand All @@ -35,157 +34,75 @@ this board support (a "raw" platform), but you will have to provide the
clock frequency and drivers for any on-board devices you want to use.


2. Building the ThreadX run-time Library
2. Building the ThreadX Library and the Xtensa Example

By default, you will build for the Xtensa instruction set simulator. If
you have a supported emulation board, you can build to run on that. You
can also build to run on a raw Xtensa core with no "board support", a
good starting point for supporting your own target platform. Cadence Design Systems
recommends doing functional development on the simulator because it
is easier to debug with, then move to a board if/when you need to test
hardware drivers or real-time performance.
will have to provide the XTBSP functions for any other board you want to
run on. We recommend you start by running on the simulator, then moving
to your hardware target or emulation platform.

ThreadX/Xtensa comes with a Makefile as well as DOS .bat file, taking
advantage of xt-make, a version of GNU make that comes with Xtensa Tools
(you can just as well use generic GNU make if you have it installed).
The Makefile works on any host platform and provides for incremental builds.
The .bat file works on DOS/Windows only and always cleans before building.
The build for each target platform is placed in a sub-directory so several
platform builds can coexist even with incremental rebuilds.
ThreadX/Xtensa is built using the ThreadX Cmake infrastructure. See the
standard ThreadX documentation for details of the build process. In the
cmake/ directory there is a file named xtensa.cmake which defines the
Cmake configuration for the Xtensa target. Both Cmake and the Ninja tool
need to be installed to build ThreadX.

First, make sure you have installed Xtensa Tools and your processor
configuration, and be sure that Xtensa Tools are in your search path.
You will also need to ensure that the Xtensa SDK tools have been installed
and are on the path, and XTENSA_SYSTEM and XTENSA_CORE are set appropriately
in the environment. Refer to the SDK documentation for details.

If you wish to build for an evaluation board that is supported by an
external package, be sure the appropriate package is installed. See the
introduction (section 0) to determine if you need an external package.
If you are using an external board package, set the environment variable
XTENSA_BOARDS to the absolute path of the root of the installed support
package (or you can pass this to xt-make commands on the command line).
eg. XTENSA_BOARDS = C:\usr\xtensa\RB-2007.1-xtav60 for Avnet LX60 board.
You do not need to set XTENSA_BOARDS if using a Cadence Design Systems supported
board with Xtensa Tools RB-2007.2 and up (support is bundled with the tools).
The following commands will build the ThreadX library (some changes may be
required based on your setup) -

Next, change directories to the ThreadX installation directory, as follows:
cmake -S $(TX_SRCDIR) -B $(TX_BLDDIR) -DCMAKE_TOOLCHAIN_FILE=$(TX_SRCDIR)/cmake/xtensa.cmake -GNinja $(TX_SRCDIR)
cmake --build $(TX_BLDDIR)

> cd c:\threadx\xtensa\gnu
where TX_SRCDIR is the root of the ThreadX source tree, and TX_BLDDIR is
the location where you want the build output to go.

Now build the ThreadX library (tx.a) by executing the build_threadx.bat
batch file (or using the Makefile directly) while inside the threadx
directory, as follows:
Once the library is built, the Xtensa example can be built by going into
the directory ports/xtensa/xcc/example_build and running this command -

> build_threadx.bat
xt-clang -mlongcalls -Os -g -I../../../../common/inc -I../../../../common_smp/inc
-I../../../../ports/xtensa/xcc/inc -o demo_threadx.exe demo_threadx.c
../../../../build/libthreadx.a -lxtutil

which always builds for the simulator (but you can edit it), or

> xt-make

which by default builds for the simulator (PLATFORM=sim), or either of

> xt-make PLATFORM=board BOARD=<board>
or
> xt-make BOARD=<board>

which builds for a specified supported board (note PLATFORM=board is
default when BOARD is defined). eg. BOARD=xtav60 for the Avnet LX60
(XT-AV60) board.

> xt-make PLATFORM=raw

which builds for a raw Xtensa core with no "board support".

> xt-make PLATFORM=gdbio

Provides some very slow I/O support through the xt-gdb debugger.
For GDBIO to work, xt-gdb must remain connected to the target.

If you are building for an Xtensa processor configuration that is not the
default you selected when you installed Xtensa Tools, you need to define the
environment variable XTENSA_CORE. If your configuration is not in the
default registry you selected when you installed Xtensa Tools, you also
need to define the environment variable XTENSA_SYSTEM. See tools manuals.
You can avoid defining these in your environment if you pass the variables
you need to redefine into xt-make as follows:

> xt-make XTENSA_CORE=<your_config_name> XTENSA_SYSTEM=<your_registry> ...

There are more details about build options in the comment in the Makefile.

At this point, all the ThreadX objects are located in a library file: tx.a .
This file must be linked with your application in order to use ThreadX.
This library and all the intermediate object files are placed in a platform
specific sub-directory named the same as BOARD or PLATFORM (if BOARD is not
defined), for example "sim", "xtkc705".

To build ThreadX with thread-safe C library support, define TX_THREAD_SAFE_CLIB
in your build, as described in section 5 and in the Makefile. Please note
that the C library is only safe for use in threads, not in interrupt handlers.
It may also safely be used in tx_application_define (after tx_kernel_enter,
before threads are running).

to 1 (this is set by default in tx_port.h). Note that the C library is only
safe for use in threads, not in interrupt handlers. It may also safely be used
in tx_application_define (after tx_kernel_enter, before threads are running).

3. Demonstration System

The ThreadX demonstration is designed to execute under Xtensa instruction set
simulator (ISS) or on a supported evaluation board programmed with your Xtensa
processor configuration.
3. Running the Example

Building the demonstration is easy, simply execute the build_threadx_demo.bat
batch file while inside threadx directory, as follows:
The ThreadX Xtensa example is designed to be run on the Xtensa simulator (ISS)
or a hardware target. By default the example is built for the simulator target.
To run it,

> build_threadx_demo.bat
xt-run demo_threadx.exe

or

> xt-make demo
xt-gdb demo_threadx.exe (if you want to run it under the debugger)

Be sure to set or pass into xt-make the variables described in section 2 above
for building the ThreadX library, including the PLATFORM or BOARD you want to
run on.

This compiles demo_threadx.c (which is the demonstration application) and links
it with the ThreadX objects in tx.a. The resulting file demo_threadx.out is a
ELF binary file that can be downloaded and executed on the target.

The demo binary appears in the platform specific sub-directory described earlier.
For the following commands, change to that directory or prepend it as the path
of demo_threadx.out.


To execute on the simulator:

> xt-run [--turbo] demo_threadx.out

The option --turbo provides much faster, but non-cycle-accurate simulation.
Refer to the Xtensa simulator user manual for further simulator options.


To execute on the simulator using the Xplorer GUI based debugger:

> xplorer --debug demo_threadx.out


To execute on a supported evaluation board, download demo_threadx.out per
instructions in the tools manuals. Be sure the board has been programmed
with the correct configuration and is set up to boot from RAM and debug
a downloaded program! Optionally you may connect a terminal or terminal
emulator to the serial port on the board with settings as described in
the board user manual, and see the output of printf on the terminal (if
the demo was compiled with DEMO_USE_PRINTF or DEMO_USE_XTUTIL).
To execute on a supported hardware target, download the example to the board
following instructions in the SDK manuals. Make sure the board has been set
up with the correct configuration (if emulation board) and is set up to boot
from RAM and debug a downloaded program. Optionally you may connect a terminal
or terminal emulator to the serial port on the board with settings as described
in the board user manual, and see the output of printf on the terminal (if
the board support package supports directing standard output to the port).

To obtain I/O on a "raw" platform such as an unsupported board, you need
to provide low level I/O drivers (eg. inbyte() and outbyte() for character
I/O if you want to use printf etc.). You can run "raw" executables on
any Xtensa platform, including simulator and any board, but you will not
see any behavior specific to the platform (eg. display, printed output,
stopping simulation at end of program). You can, while debugging, use a
debugger mechanism called GDBIO to obtain basic I/O. Use PLATFORM=GDBIO
on your xt-make command line - this is the same as "raw" except it links
some stubs that communicate through the debugger. It is very slow!

WARNING: It is tempting to add printf calls to other threads in the demo.
If you modify the code in any way, you may need adjust affected threads'
stack sizes. This is especially true if you add a printf call. See 4.5.
debugger mechanism called GDBIO to obtain basic I/O. This requires linking
with the gdbio support library. See the SDK documentation for details.


4. System Initialization
Expand Down Expand Up @@ -272,16 +189,14 @@ are provided in tx_port.h assuming no optimization (default, -O0).
Threads that call C library functions may need larger stacks than those
that don't. In particular, use of printf requires a very large stack and
will usually cause a stack overflow if inserted in a thread without
enlarging its stack size. See DEMO_STACK_SIZE_PRINTF in demo_threadx.c
for a guideline. Use printf with care!
enlarging its stack size.


5. Assembler / Compiler Switches

The following are compiler switches used in building the ThreadX library
and demonstration system. These can be supplied by editing the Makefile
or by overriding the COPT or CFLAGS variables in the make command line
(eg. make COPT="-O2 -DTX_THREAD_SAFE_CLIB"). More details in Makefile.
and demonstration system. These can be supplied by editing the xtensa.cmake
file or by overriding from the environment or command line.

Compiler Switch Meaning

Expand All @@ -291,7 +206,6 @@ Compiler Switch Meaning
-mlongcalls Allows assembler and linker to convert call
instructions to longer indirect call sequences
when target is out of range.
-x assembler-with-cpp Passes .s and .S files through C preprocessor.
-Dmacro Define a preprocessor macro with no value.
-Dmacro=value Define a preprocessor macro with a value.

Expand All @@ -306,9 +220,6 @@ Application Defines (preprocessor macros definable with the -D option):
can be customized in tx_application_define.
Default off.

NOTE: Thread safe support for Xtensa C library requires Xtensa Tools
version RF-2015.2 or later.

TX_ENABLE_STACK_CHECKING Enable generic ThreadX support for stack
overflow checking. This can help avoid long
debugging sessions or customer support calls
Expand Down Expand Up @@ -382,7 +293,8 @@ Application Defines (preprocessor macros definable with the -D option):
higher bit numbers over those with lower bit
numbers at the same level. This works only for
low and medium priority interrupts that can be
dispatched to C handlers.
dispatched to C handlers on either NX cores or
on LX cores with 32 or fewer interrupts.

TX_SYSTEM_STACK_SIZE=n Specify the size of the interrupt stack, which
is the stack that all interrupt handlers switch
Expand Down Expand Up @@ -455,7 +367,7 @@ If multiple threads use a register, the caller must save and restore it.

The saved context stack frames for context switches that occur as a result
of interrupt handling (interrupt frame) or from thread-level API calls
(solicited frame) are described in human readable form in xtensa_context.h .
(solicited frame) are described in human readable form in xtensa_context.h.
All suspended threads have one of these two types of stack frames. The top
of the suspended thread's stack is pointed to by tx_thread_stack_ptr in the
associated thread control block TX_THREAD. An Xtensa architecture port-specific
Expand Down
Loading