• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..--

example_build/11-Mar-2024-378181

inc/11-Mar-2024-1,864688

src/11-Mar-2024-5,9482,708

CMakeLists.txtD11-Mar-20241.4 KiB3731

readme_threadx.txtD11-Mar-202439.8 KiB786617

readme_threadx.txt

1           Microsoft's ThreadX for Xtensa Configurable Processors
2
3                            Using the Xtensa Tools
4
51.  Xtensa Configuration Requirements and Restrictions
6
7The Xtensa configurable architecture supports a vast space of processor
8features. This port of ThreadX to the Xtensa architecture is based on
9a Cadence Design Systems RTOS porting layer that takes care of Xtensa specifics
10that are common to most embedded real-time operating systems. It supports all
11Xtensa features (including context-switching custom processor extensions
12defined in the TIE language) with certain minimum requirements. You
13must use Xtensa Tools to compile and link ThreadX for your particular
14configuration. ThreadX uses the Xtensa Hardware Abstraction Layer (HAL)
15to adapt your ThreadX compilation to your particular Xtensa processor
16configuration. ThreadX also provides optional thread-safe support for
17the Xtensa C library and the newlib C library distributed with Xtensa Tools
18(for use in threads only, not in interrupt handlers).
19
20ThreadX for Xtensa configurable processors requires the following minimum
21processor configuration options:
22- Timer interrupt option with at least one interruptible timer for ThreadX.
23- Interrupt option (implied by the timer interrupt option).
24- Xtensa Exception Architecture 2 (XEA2) or Exception Architecture 3 (XEA3).
25  Please note that XEA1 is NOT supported.
26
27Minimal support for certain evaluation boards is provided via a board
28independent "XTBSP" API implemented by a board specific library. This
29provides the board clock frequency and basic polled drivers for the display
30and console I/O device (usually a UART), and ThreadX can be built to
31take advantage of these (note: it is not specific to ThreadX and is not a
32traditional RTOS "board support package" with RTOS specific interrupt-driven
33drivers). Note that ThreadX can run on any Xtensa board without
34this board support (a "raw" platform), but you will have to provide the
35clock frequency and drivers for any on-board devices you want to use.
36
37
382.  Building the ThreadX run-time Library
39
40By default, you will build for the Xtensa instruction set simulator. If
41you have a supported emulation board, you can build to run on that. You
42can also build to run on a raw Xtensa core with no "board support", a
43good starting point for supporting your own target platform. Cadence Design Systems
44recommends doing functional development on the simulator because it
45is easier to debug with, then move to a board if/when you need to test
46hardware drivers or real-time performance.
47
48ThreadX/Xtensa comes with a Makefile as well as DOS .bat file, taking
49advantage of xt-make, a version of GNU make that comes with Xtensa Tools
50(you can just as well use generic GNU make if you have it installed).
51The Makefile works on any host platform and provides for incremental builds.
52The .bat file works on DOS/Windows only and always cleans before building.
53The build for each target platform is placed in a sub-directory so several
54platform builds can coexist even with incremental rebuilds.
55
56First, make sure you have installed Xtensa Tools and your processor
57configuration, and be sure that Xtensa Tools are in your search path.
58
59If you wish to build for an evaluation board that is supported by an
60external package, be sure the appropriate package is installed. See the
61introduction (section 0) to determine if you need an external package.
62If you are using an external board package, set the environment variable
63XTENSA_BOARDS to the absolute path of the root of the installed support
64package (or you can pass this to xt-make commands on the command line).
65eg. XTENSA_BOARDS = C:\usr\xtensa\RB-2007.1-xtav60 for Avnet LX60 board.
66You do not need to set XTENSA_BOARDS if using a Cadence Design Systems supported
67board with Xtensa Tools RB-2007.2 and up (support is bundled with the tools).
68
69Next, change directories to the ThreadX installation directory, as follows:
70
71> cd c:\threadx\xtensa\gnu
72
73Now build the ThreadX library (tx.a) by executing the build_threadx.bat
74batch file (or using the Makefile directly) while inside the threadx
75directory, as follows:
76
77> build_threadx.bat
78
79which always builds for the simulator (but you can edit it), or
80
81> xt-make
82
83which by default builds for the simulator (PLATFORM=sim), or either of
84
85> xt-make PLATFORM=board BOARD=<board>
86or
87> xt-make BOARD=<board>
88
89which builds for a specified supported board (note PLATFORM=board is
90default when BOARD is defined). eg. BOARD=xtav60 for the Avnet LX60
91(XT-AV60) board.
92
93> xt-make PLATFORM=raw
94
95which builds for a raw Xtensa core with no "board support".
96
97> xt-make PLATFORM=gdbio
98
99Provides some very slow I/O support through the xt-gdb debugger.
100For GDBIO to work, xt-gdb must remain connected to the target.
101
102If you are building for an Xtensa processor configuration that is not the
103default you selected when you installed Xtensa Tools, you need to define the
104environment variable XTENSA_CORE. If your configuration is not in the
105default registry you selected when you installed Xtensa Tools, you also
106need to define the environment variable XTENSA_SYSTEM. See tools manuals.
107You can avoid defining these in your environment if you pass the variables
108you need to redefine into xt-make as follows:
109
110> xt-make XTENSA_CORE=<your_config_name> XTENSA_SYSTEM=<your_registry> ...
111
112There are more details about build options in the comment in the Makefile.
113
114At this point, all the ThreadX objects are located in a library file: tx.a .
115This file must be linked with your application in order to use ThreadX.
116This library and all the intermediate object files are placed in a platform
117specific sub-directory named the same as BOARD or PLATFORM (if BOARD is not
118defined), for example "sim", "xtkc705".
119
120To build ThreadX with thread-safe C library support, define TX_THREAD_SAFE_CLIB
121in your build, as described in section 5 and in the Makefile. Please note
122that the C library is only safe for use in threads, not in interrupt handlers.
123It may also safely be used in tx_application_define (after tx_kernel_enter,
124before threads are running).
125
126
1273.  Demonstration System
128
129The ThreadX demonstration is designed to execute under Xtensa instruction set
130simulator (ISS) or on a supported evaluation board programmed with your Xtensa
131processor configuration.
132
133Building the demonstration is easy, simply execute the build_threadx_demo.bat
134batch file while inside threadx directory, as follows:
135
136> build_threadx_demo.bat
137
138or
139
140> xt-make demo
141
142Be sure to set or pass into xt-make the variables described in section 2 above
143for building the ThreadX library, including the PLATFORM or BOARD you want to
144run on.
145
146This compiles demo_threadx.c (which is the demonstration application) and links
147it with the ThreadX objects in tx.a. The resulting file demo_threadx.out is a
148ELF binary file that can be downloaded and executed on the target.
149
150The demo binary appears in the platform specific sub-directory described earlier.
151For the following commands, change to that directory or prepend it as the path
152of demo_threadx.out.
153
154
155To execute on the simulator:
156
157> xt-run [--turbo] demo_threadx.out
158
159The option --turbo provides much faster, but non-cycle-accurate simulation.
160Refer to the Xtensa simulator user manual for further simulator options.
161
162
163To execute on the simulator using the Xplorer GUI based debugger:
164
165> xplorer --debug demo_threadx.out
166
167
168To execute on a supported evaluation board, download demo_threadx.out per
169instructions in the tools manuals. Be sure the board has been programmed
170with the correct configuration and is set up to boot from RAM and debug
171a downloaded program!  Optionally you may connect a terminal or terminal
172emulator to the serial port on the board with settings as described in
173the board user manual, and see the output of printf on the terminal (if
174the demo was compiled with DEMO_USE_PRINTF or DEMO_USE_XTUTIL).
175
176To obtain I/O on a "raw" platform such as an unsupported board, you need
177to provide low level I/O drivers (eg. inbyte() and outbyte() for character
178I/O if you want to use printf etc.).  You can run "raw" executables on
179any Xtensa platform, including simulator and any board, but you will not
180see any behavior specific to the platform (eg. display, printed output,
181stopping simulation at end of program). You can, while debugging, use a
182debugger mechanism called GDBIO to obtain basic I/O. Use PLATFORM=GDBIO
183on your xt-make command line - this is the same as "raw" except it links
184some stubs that communicate through the debugger. It is very slow!
185
186WARNING: It is tempting to add printf calls to other threads in the demo.
187If you modify the code in any way, you may need adjust affected threads'
188stack sizes. This is especially true if you add a printf call. See 4.5.
189
190
1914.  System Initialization
192
1934.1 ThreadX Kernel
194
195ThreadX uses the reset vector and low level initialization from the Xtensa
196libraries provided by the linker support package (LSP). It does not provide
197its own reset vector (which would have to be maintained with tools upgrades).
198
199ThreadX is initialized by tx_kernel_enter which is usually called from
200main. The primary initialization function is _tx_initialize_low_level
201and is located in the file tx_initialize_low_level.c. This function is
202responsible for setting up various system data structures. Interrupt and
203exception vectors are linked into your program and installed at load time
204(they are not dynamically installed). The interrupt and exception vectors
205for the ThreadX Xtensa port are defined in xtensa_vectors.S (for XEA2) and
206xtensa_vectors_xea3.S (for XEA3).
207
2084.2 Memory Allocation
209
210In addition, _tx_initialize_low_level also determines the first available
211address for use by the application. By default, the first available address
212is assumed to be above all linker-allocated sections at symbol _end. This
213is passed to the application definition function, tx_application_define.
214This is a convenience to the application developer. Ultimately the developer
215has full control over memory allocation and can choose to use this or not.
216The top of available memory is not provided and should be obtained from the
217tools if needed.
218
2194.3 Location and Extent of System (Interrupt) Stack
220
221ThreadX/Xtensa supports a user-definable system stack. By default, the
222top of the system stack is defined by the symbol _xt_interrupt_stack_top.
223See the file xtensa_intr_asm.S for the default system stack definition.
224This stack may be resized and/or relocated according to the application
225needs. The application developer must ensure that the system stack is
226sized appropriately for the application. All interrupts handled by
227ThreadX will use the system stack. Handlers written in assembly must
228not switch to the system stack, since it will not be possible to detect
229whether the stack is currently in use.
230
231The macro TX_SYSTEM_STACK_SIZE defines the size of the system stack.
232As a convenience, a macro TX_MINIMUM_STACK_SYSTEM is provided with the
233minimum size required for the system stack. This is based on the maximum
234possible interrupt nesting level per the Xtensa processor configuration,
235assuming very simple C handlers that do not call deeper than one or two
236levels.  If the application uses more complex handlers, it will be
237necessary to add to this value (accounting for nesting) to determine
238the space required for the system stack.
239
2404.4 Location and Extent of C Library Heap
241
242If the optional thread-safe support for the C library is used, memory
243for the heap is allocated like this: by default, half the space between
244the first available memory address and the end of system memory is
245made available to the heap.
246
247The heap location and limit are available in two global variables, and
248can be fully customized in tx_application_define by assigning to them:
249
250    _tx_clib_heap_start     Base address of heap.
251    _tx_clib_heap_end       Upper limit address to which heap can grow.
252
253This must be done BEFORE any C library calls. It is advised that it be
254done at the beginning of tx_application_define.
255
256Please note that when the thread-safe C library support is used, the heap
257is not initialized before tx_kernel_enter has been called, so malloc will
258fail. It is recommended to avoid C library calls that use the heap (such
259as printf) outside of ThreadX (eg. in main). The C library is NOT safe
260for use in interrupt or exception handlers, so this should be avoided.
261
2624.5 Thread Stack Sizes
263
264The application must ensure that every thread has enough space for its
265stack. This must account for the deepest call depth and allow for one
266interrupt stack frame as defined in xtensa_context.h . Several factors
267influence the size of the stack required, including compiler optimization
268level (-O0 is worst), use of TX_ENABLE_STACK_CHECKING option, and of
269course your Xtensa configuration. Some stack size guidelines and macros
270are provided in tx_port.h assuming no optimization (default, -O0).
271
272Threads that call C library functions may need larger stacks than those
273that don't. In particular, use of printf requires a very large stack and
274will usually cause a stack overflow if inserted in a thread without
275enlarging its stack size. See DEMO_STACK_SIZE_PRINTF in demo_threadx.c
276for a guideline. Use printf with care!
277
278
2795.  Assembler / Compiler Switches
280
281The following are compiler switches used in building the ThreadX library
282and demonstration system. These can be supplied by editing the Makefile
283or by overriding the COPT or CFLAGS variables in the make command line
284(eg. make COPT="-O2 -DTX_THREAD_SAFE_CLIB"). More details in Makefile.
285
286Compiler Switch                 Meaning
287
288    -g                      Specifies debug information.
289    -c                      Specifies object code generation.
290    -On                     Sets compiler optimization level n (default -O0).
291    -mlongcalls             Allows assembler and linker to convert call
292                            instructions to longer indirect call sequences
293                            when target is out of range.
294    -x assembler-with-cpp   Passes .s and .S files through C preprocessor.
295    -Dmacro                 Define a preprocessor macro with no value.
296    -Dmacro=value           Define a preprocessor macro with a value.
297
298Application Defines (preprocessor macros definable with the -D option):
299
300    TX_THREAD_SAFE_CLIB     Enable support for thread-safe C library.
301                            Only the Xtensa C library and the newlib library
302                            are supported for thread-safe operation.
303                            When this is enabled, half the available memory
304                            space is allocated by default, below the system
305                            stack, for the heap. The heap size and location
306                            can be customized in tx_application_define.
307                            Default off.
308
309    NOTE: Thread safe support for Xtensa C library requires Xtensa Tools
310          version RF-2015.2 or later.
311
312    TX_ENABLE_STACK_CHECKING Enable generic ThreadX support for stack
313                            overflow checking. This can help avoid long
314                            debugging sessions or customer support calls
315                            by identifying many crashes caused by stack
316                            overflow. Use of this option adds a small
317                            premium to the required thread stack sizes
318                            (the premium is included by the stack size
319                            convenience macros defined in tx_port.h).
320
321    TX_NO_TIMER             Enable generic ThreadX footprint reduction when
322                            no periodic tick is needed. The Xtensa port also
323                            reduces footprint by removing all code related
324                            to timer interrupts. Related XT_* options below
325                            (XT_CLOCK_FREQ, XT_TICK_PER_SEC, XT_TIMER_INDEX)
326                            have no effect under TX_NO_TIMER.
327
328    All generic ThreadX options in tx_user.h may also be defined with -D.
329
330    Note, the above defines are not specific to Xtensa processors, so
331    their names begin with "TX_". Defines below are unique to the Xtensa
332    port so have names beginning with "XT_".
333
334    XT_SIMULATOR            Set this if building to run on the simulator.
335                            Takes advantage of certain simulator control
336                            and reporting facilities, and adjusts timing
337                            of periodic tick to provide a more acceptable
338                            performance in simulation (see XT_CLOCK_FREQ).
339                            Set by default unless PLATFORM is overridden.
340
341    XT_BOARD=board          Set this if building for a supported board.
342                            The value should be the identifier of a board
343                            supported in the Xtensa Tools or an external
344                            package (eg. XT_BOARD=xtkc705 for the Xilinx
345                            KC705 board). If the board is supported by an
346                            external package, the variable XTENSA_BOARDS
347                            should point to the root of the package. Set by
348                            provided Makefile when PLATFORM=board and BOARD
349                            is defined (eg. PLATFORM=board BOARD=xtkc705).
350
351    XT_CLOCK_FREQ=freq      Specifies the target processor's clock
352                            frequency in Hz. Used primarily to set the
353                            timer that generates the periodic interrupt.
354                            Defaults are provided and may be edited in
355                            xtensa_timer.h (see comments there also).
356                            Default for simulator provides more acceptable
357                            performance, but cannot provide real-time
358                            performance due to variation in simulation
359                            speed per host platform and insufficient
360                            cycles between interrupts to process them.
361                            Supported board platforms by default leave
362                            this undefined and compute the clock frequency
363                            at initialization unless this is explicitly
364                            defined.
365
366    XT_TICK_PER_SEC=n       Specifies the frequency of the periodic tick.
367
368    XT_TIMER_INDEX=n        Specifies which timer to use for ThreadX.
369                            Set this if your Xtensa processor configuration
370                            provides more than one suitable timer and you
371                            want to override the default. See xtensa_timer.h.
372
373    XT_INTEXC_HOOKS         Enables hooks in interrupt vector handlers
374                            to support dynamic installation of exception
375                            and interrupt handlers. Used by automatic
376                            regression test programs. Disabled by default.
377
378    XT_USE_OVLY             Enable code overlay support.
379
380    XT_USE_SWPRI            Enable software prioritization of interrupts.
381                            Enabling this will prioritize interrupts with
382                            higher bit numbers over those with lower bit
383                            numbers at the same level. This works only for
384                            low and medium priority interrupts that can be
385                            dispatched to C handlers.
386
387    TX_SYSTEM_STACK_SIZE=n  Specify the size of the interrupt stack, which
388                            is the stack that all interrupt handlers switch
389                            to while handling interrupts. See the section
390                            describing the interrupt stack for more details.
391
392
3936.  Register Usage and Stack Frames
394
395The Xtensa architecture specifies two ABIs that determine how the general
396purpose registers a0-a15 are used: the windowed ABI, and the Call0 ABI.
397The choice of ABI is made when configuring the processor or its associated
398software. Xtensa processors may have other special registers (including
399coprocessor registers and other TIE "states") that are independent of this
400choice of ABI. See Xtensa documentation for more details.
401
402In the windowed ABI the registers of the current window are used as follows:
403    a0      = return address
404    a1      = stack pointer (alias sp)
405    a2      = first argument and result of call (in simple cases)
406    a3-7    = second through sixth arguments of call (in simple cases).
407              Note that complex or large arguments are passed on the
408              stack. Details are in the Xtensa Tools manuals.
409    a8-a15  = available for use as temporaries.
410
411There are no callee-save registers. The windowed hardware automatically
412saves registers a0-a3 on a call4, a0-a8 on a call8, a0-a12 on a call12,
413by rotating the register window. Hardware triggers window overflow and
414underflow exceptions as necessary when registers outside the current
415window need to be spilled to preallocated space in the stack frame, or
416restored. Complete details are in the Xtensa manuals. The entire windowed
417register file is saved and restored on interrupt or thread context switch.
418Note that only call0 and call8 are available in XEA3 Windowed ABI.
419
420The Call0 ABI does not make use of register windows, relying instead
421on a fixed set of 16 registers without window rotation.
422The Call0 ABI is more conventional and uses registers as follows:
423    a0      = return address
424    a1      = stack pointer (alias sp)
425    a2      = first argument and result of call (in simple cases)
426    a3-7    = second through sixth arguments of call (in simple cases).
427              Note that complex or large arguments are passed on the
428              stack. Details are in the Xtensa Tools manuals.
429    a8-a11  = scratch.
430    a12-a15 = callee-save (a function must preserve these for its caller).
431
432On a ThreadX API call, callee-save registers are saved only when a thread
433context switch occurs, and other registers are not saved at all (the caller
434does not expect them to be preserved). On an interrupt, callee-saved
435registers might only be saved and restored when a thread context-switch
436occurs, but all other registers are always saved and restored.
437
438An Xtensa processor has other special registers independent of the ABI,
439depending on the configuration (including coprocessor registers and other
440TIE state) that are part of the thread context. ThreadX preserves all such
441registers over an unsolicited context-switch triggered by an interrupt
442(including time-slice expiry). However it does NOT preserve these over
443a solicited context-switch during a ThreadX API call. This bears some
444explanation. These special registers are either ignored by the compiler
445or treated as caller-saved, meaning that if kept "live" over a function
446call (ie. need to be preserved) they must be saved and restored by the
447caller. Since solicited entry to ThreadX is always made by a function
448call, ThreadX assumes the caller has saved any of these registers that are
449"live". ThreadX avoids a lot of overhead by not having to save and restore
450every special register (there can be many) on every solicited context switch.
451
452As a consequence, the application developer should NOT assume that special
453registers are preserved over a ThreadX API call such as tx_thread_sleep.
454If multiple threads use a register, the caller must save and restore it.
455
456The saved context stack frames for context switches that occur as a result
457of interrupt handling (interrupt frame) or from thread-level API calls
458(solicited frame) are described in human readable form in xtensa_context.h .
459All suspended threads have one of these two types of stack frames. The top
460of the suspended thread's stack is pointed to by tx_thread_stack_ptr in the
461associated thread control block TX_THREAD. An Xtensa architecture port-specific
462extension to the thread control block tx_thread_solicited contains 1 for a
463thread that is currently suspended from an API call, otherwise contains 0.
464
465
4667.  Improving Performance, Footprint, or Ease of Debugging
467
468The distribution version of ThreadX is built with debug (-g) and without
469compiler optimizations (-O0). This makes debugging easier inside ThreadX
470itself. Of course, -O0 costs some performance. To make ThreadX run faster,
471you can change the Makefile to enable the desired optimizations or set
472a predefined optimization level (-O<level>) .
473
474Maximum performance is achieved with -O3, but that might increase footprint
475substantially. A good compromise is -O2. If code size is a concern, -Os may
476yield better results. See the compiler manual for details.
477
478You can eliminate the ThreadX basic API error checking by compiling your
479application code with the symbol TX_DISABLE_ERROR_CHECKING defined before
480tx_api.h is included.
481
482The Xtensa architecture port-specific assembly files are coded with no
483file-scope labels inside functions (all labels inside functions begin with
484".L"). This allows a profiler to accurately associate an address with a
485function, and also allows the debugger's stack trace to show the correct
486function wherever the program counter is within that function. However
487there are some tradeoffs in debugging. Local (".L") labels are not
488visible to the debugger, so the following limitations may be observed
489during debugging:
490- You cannot set a breakpoint on a local label inside a function.
491- Disassembly will show the entire function, but will get out of sync and
492  show incorrect opcodes if it crosses any padding before an aligned local
493  branch target (".L" label, not ".Ln"). Restart disassembly specifying an
494  address range explicitly between points where there is padding.
495Since ThreadX is provided in source form, it is not difficult to remove
496the ".L" and ".Ln" prefixes from local labels if you want them visible.
497They can also be made visible by passing the '-L' option to the assembler
498and linker (see the assembler and linker manuals for details).
499
500
5018.  Interrupt and Exception Handling
502
503NOTE: The material in this section is mostly an overview. For a more
504detailed explanation please refer to the Xtensa ISA manual and the System
505Software manual.
506
507ThreadX provides a complete set of efficient exception and first-level
508interrupt handlers installed at the appropriate exception and interrupt
509vector locations. The XEA2 architecture supports several different
510classes of exceptions and interrupts. Being a configurable architecture,
511many of these are optional, and the vector locations are determined by
512your processor configuration. The handlers provided use conditional
513compilation to adapt to your processor configuration and include only
514the code that is needed.
515
516Xtensa vector locations may reside almost anywhere, including in ROM.
517And the amount of code space available at each of these locations is
518often very small (e.g. due to following vectors). A small stub of code
519installed at the vector jumps to the corresponding handler, usually in RAM.
520The exception and interrupt handlers are defined in xtensa_vectors.S .
521They are not specific to ThreadX, but call into ThreadX where appropriate
522via macros defined in xtensa_rtos.h .
523
524Interrupt/Exception Handling in XEA2
525------------------------------------
526
527The handlers provided for low and medium priority interrupts are just
528dispatchers that save relevant state and call user-definable handlers.
529See the files xtensa_vectors.S and xtensa_api.h for more details of how
530to create and install application-specific user interrupt handlers.
531Similarly, user-defined handlers can be installed for exceptions (other
532than a few which are always handled by the OS).
533
534The high priority interrupt handlers provided may be considered templates
535into which the application adds code to service specific interrupts.
536The places where application handlers should be inserted are tagged with
537the comment "USER_EDIT" in xtensa_vectors.S.
538
539This ThreadX port supports strict priority-based nesting of interrupts.
540An interrupt may only nest on top of one of strictly lower priority.
541Equal priority interrupts concurrently pending are handled in an
542application-defined sequence before any lower priority interrupts
543are handled. During interrupt and exception handling, the processor's
544interrupt level (PS.INTLEVEL) is used to control the interrupt priority
545level that can be accepted; interrupt sources are not controlled
546individually by ThreadX (the application is free to access the INTENABLE
547register directly to enable/disable individual interrupts, e.g. using
548Xtensa HAL services). This approach provides the most deterministic
549bounds on interrupt latency (for a given priority) and system stack depth.
550
551Software prioritization of interrupts at the same priority is controlled
552by the definition of XT_USE_SWPRI. See above for a description of this
553parameter.
554
555Interrupt and Exception Handling in XEA3
556----------------------------------------
557
558In XEA3 no distinction is made between low, medium and high priority interrupt
559levels. Interrupts at all levels up to the highest (NMI) level can be dispatched
560to handlers written in C. Interrupts are dispatched by the XEA3 dispatcher and
561the handlers are found from a handler table. Handlers are installed into the
562handler table by calling xt_set_interrupt_handler. As there is no concept of
563a high priority interrupt any longer, handlers can only be specified per
564interrupt, not per level. Since all levels can be handled in C, the value of
565EXCM_LEVEL is set to the highest possible level (NMI level).
566Software prioritization is not available for XEA3.
567
568
569The following subsections describe the handling of each class of exception
570and interrupt in more detail. Many have nothing to do with ThreadX but are
571mentioned because there is code to handle them in xtensa_vectors.S.
572
5738.1 User Exception and Interrupt Handler (Low/Medium Priority)
574
575    All Xtensa 'general exceptions' come to the user, kernel, or double
576    exception vector.  The exception type is identified by the EXCCAUSE
577    special register (level 1 interrupts are one particular cause of a
578    general exception). This port sets up PS to direct all such exceptions
579    to the user vector. Exceptions taken at the other two vectors usually
580    indicate a kernel or application bug.
581
582    In XEA3, everything except a double exception will come to a common
583    vector. This vector saves the requisite processor state and then checks
584    for the highest priority interrupt to dispatch. If no interrupts are
585    pending then a check is made for exceptions.
586
587    Level 1 interrupts are identified at the beginning of the handler
588    and are dispatched to a dedicated handler. Then, syscall and alloca
589    exceptions are identified and dispatched to special handlers described
590    below. After this, coprocessor exceptions are identified and dispatched
591    to the coprocessor handler.
592
593    Any remaining exceptions are processed as follows:
594
595    Having allocated the exception stack frame, the user exception handler
596    calls _tx_thread_context_save, which saves the rest of the interrupt
597    context. After this the handler sets up a C environment and enables
598    the high-priority class of interrupts (which do not interact with
599    ThreadX), then reads EXCCAUSE and uses the cause (number) to index
600    into a table of user-specified handlers. The correct handler is then
601    called. If the handler returns, the context is restored and control
602    is returned to the code that caused the exception. The user-defined
603    handler may alter the saved context, or any other system state, that
604    allows the faulting instruction to be retried.
605
606    If the cause is a level 1 (low-priority) or medium-priority interrupt,
607    the handler enables all interrupts above that priority level after
608    saving the thread context and switching to the interrupt stack if it
609    is not a nested interrupt. It then sets up the environment for C code
610    and then calls the handler (found in the handler table) for the
611    interrupt number. If the user has not specified a handler, then the
612    default handler will be called, which will terminate the program.
613
614    If the interrupt is for the system timer, it calls a special interrupt
615    handler for the system timer tick, which calls _tx_timer_interrupt then
616    clears its bit from the mask. This interrupt cannot be hooked by the
617    user-defined handler.
618
619    Finally, the handler calls _tx_thread_context_restore to allow ThreadX
620    to perform any scheduling necessary and return either to the interrupted
621    thread or another.
622
623    If software prioritization is enabled, the handler will re-enable all
624    interrupts at the same level that are numerically higher than the current
625    one, before calling the user handler. This allows a higher priority
626    interrupt to pre-empt the lower priority handler.
627
6288.2 Medium Priority Interrupt Handlers (XEA2)
629
630    Medium priority interrupts are those at levels 2 up to XCHAL_EXCM_LEVEL,
631    a configuration-specific maximum interrupt level affected by the global
632    'exception mode' bit in the processor status word (PS.EXCM).
633    Interrupt levels above XCHAL_EXCM_LEVEL are of the high-priority class.
634    The Xtensa hardware documentation considers medium priority interrupts
635    to be a special case of high-priority interrupts, but from a software
636    perspective they are very different.
637
638    Dispatch of medium-priority interrupts is discussed in the section
639    above.
640
6418.3 High Priority Interrupt Handlers (XEA2)
642
643    High priority interrupts are those strictly above XCHAL_EXCM_LEVEL,
644    a configuration-specific maximum interrupt level affected by the
645    global 'exception mode' bit in the processor status word (PS.EXCM).
646    High priority handlers may not directly interact with ThreadX at all,
647    and are described here only for the sake of completeness. They must
648    be coded in assembler (may not be coded in C) and are intended to be
649    used for handling extremely high frequency hardware events that need
650    to be handled in only a few cycles. A high priority interrupt handler
651    may trigger a software interrupt at a medium or low priority level to
652    occasionally signal ThreadX. Please see Xtensa documentation.
653
654    There is a separate vector and a few special registers for each high
655    priority interrupt, providing for fast dispatch and efficient nesting
656    on top of lower priority interrupts. Handlers are templates included
657    only for the vectors that exist in your Xtensa processor configuration.
658    These templates are written for only one interrupt per high priority
659    level to minimize latency servicing very fast time-critical interrupts.
660    The vector code jumps to the corresponding first-level interrupt handler,
661    which then executes application-provided assembler code before returning
662    quickly to the interrupted thread or lower priority handler.
663
6648.4 Kernel Exception Handler (XEA2)
665
666    Kernel mode is not used in this port of ThreadX, and therefore kernel
667    exceptions should not happen. A stub is provided for the vector that
668    triggers the debugger (if connected) or calls _xt_panic to freeze the
669    processor should a kernel exception occur.
670
6718.5 Alloca Exception Handler
672
673    Alloca exceptions are generated by the 'movsp' instruction, which
674    is used only in the windowed ABI. Its purpose is to allocate some
675    space on top of the stack. Because the window hardware may have
676    spilled some registers to the 16 byte "base save" area below the
677    stack pointer, it is necessary to protect those values. The alloca
678    handler accomplishes this quickly without setting up an interrupt
679    frame or entering ThreadX, by emulating a register underflow and
680    re-executing 'movsp'.
681
6828.6 Syscall Exception Handler
683
684    Syscall exceptions are generated by a 'syscall' instruction.
685    The windowed ABI specifies that executing this instruction with
686    a value of zero in register a2 must spill any unsaved registers
687    in the windowed register file to their pre-determined locations
688    on the caller's stack. The handler does exactly that, and skips
689    over the 'syscall' instruction before returning to the caller.
690    If a2 is non-zero, the handler returns a2 == -1 to the caller.
691
6928.7 Co-Processor Exception Handler
693
694    A coprocessor exception is generated when a thread accesses a
695    coprocessor that it does not "own". Ownership represents which
696    thread's state is currently in the coprocessor. Co-processors are
697    context-switched "lazily" (on demand) only when a non-owning thread
698    uses a coprocessor instruction, otherwise a thread retains ownership
699    even when it is preempted from the main processor. The coprocessor
700    exception handler performs the context-switch and manages ownership.
701
702    Co-processors may not be used by any code outside the context of a
703    thread. A coprocessor exception triggered by code that is not part
704    of a running thread is a fatal error and ThreadX/Xtensa will panic.
705    This restriction is intended to reduce the overhead of saving and
706    restoring coprocessor state (which can be quite large) and in
707    particular remove that overhead from interrupt handlers. It also
708    reduces the thread stack size requirement by allowing coprocessor
709    state to be saved in the thread control block rather than the stack.
710
7118.8 Debug Exception Handler
712
713    A debug exception is caused as a result of running code, such as by
714    a 'break' instruction or hardware breakpoints and watchpoints, or
715    as a result of an external debug interrupt, such as from an OCD based
716    debugger or multiprocessor debug events ("breakin/breakout"). If the
717    processor is running in OCD mode under control of an OCD-based debugger,
718    the trigger event immediately halts the processor and gives control to
719    the OCD debugger. Otherwise control is transferred to the debug vector.
720    The debug vector handler calls the simulator if running on the ISS,
721    which then takes control and interacts with any attached debugger.
722    If running on hardware and not in OCD mode, debug exceptions are not
723    expected, so the debug handler calls _xt_panic to freeze the processor.
724
7258.9 Double Exception Handler
726
727    A double exception is a general exception that happens while the
728    processor is in exception mode (PS.EXCM set), and thus indicates a
729    bug in kernel code. The double exception vector handler triggers
730    the debugger (if connected) or calls _xt_panic to freeze the
731    processor.
732
7338.10 Window Overflow and Underflow Exception Handlers
734
735    Window overflow and underflow handlers are required for use of the
736    windowed ABI. Each has its own dedicated vector and highly optimized
737    code that is independent of OS. See Xtensa documentation for details.
738
7398.11 Hooks for Dynamic Installation of Handlers
740
741    Optional hooks are provided in the user exception and low level
742    interrupt handler and all medium and high priority interrupt handlers,
743    to dynamically install a handler function (which may be coded in C,
744    unless in a high-priority interrupt handler). These hooks are enabled
745    and used by automatic regression tests, they are not part of a normal
746    ThreadX build. However an application is free to take advantage of
747    them. The interrupt/exception hooks are described in xtensa_rtos.h .
748
749    It is recommended that the application not make use of these hooks, but
750    rather use xt_set_interrupt_handler() and xt_set_exception_handler()
751    to install application-specific handlers. This method is more convenient
752    and allows arguments to be passed to the handlers. Software prioritization
753    of interrupts works only with this method. See xtensa_api.h for details.
754
7559.  Overlay Support (XEA2 only)
756
757ThreadX supports the overlay feature of the Xtensa toolsuite. To enable overlay support,
758the ThreadX library should be built with XT_USE_OVLY defined. In addition, the linker
759command line must use the overlay library via the -loverlay linker option and the
760xtensa_overlay_os_hook.o object file must be explicitly specified in order to override
761the overlay libary version.
762
763You will also need to generate a custom LSP for overlay use. Please reference the
764Xtensa System Software Reference and Xtenas Linker Support Packages (LSPs) for more
765information on using overlays.
766
767
76810.  Revision History
769
770For generic code revision information, please refer to the readme_threadx_generic.txt
771file, which is included in your distribution. The following details the revision
772information associated with this specific port of ThreadX:
773
774
77504-02-2021  Release 6.1.6 changes:
776            tx_port.h                           Updated macro definition
777
77812-31-2020  Initial Version 6.1.3
779
780
781Copyright(c) 1996-2020 Microsoft Corporation
782
783
784https://azure.com/rtos
785
786