FreeRTOS Port for Xtensa Configurable and Diamond Processors ============================================================ FreeRTOS Version 8.2.0 Introduction ------------ This document describes the Xtensa port for FreeRTOS multitasking RTOS. For an introduction to FreeRTOS itself, please refer to FreeRTOS documentation. This port currently works with version 8.2.0. Xtensa Configuration Requirements and Restrictions -------------------------------------------------- The Xtensa configurable architecture supports a vast space of processor features. This port supports all of them, including custom processor extensions defined in the TIE language, with certain minimum requirements. You must use Xtensa Tools to compile and link FreeRTOS and your application for your Xtensa configuration. The port uses the Xtensa Hardware Abstraction Layer (HAL) to adapt to your Xtensa configuration. NOTE: It may be possible to build and run this with the open-source xtensa-linux tools provided you have the correct overlay for your Xtensa configuration. However, this has not been tested and is currently not supported by Cadence. This port includes optional reentrancy support for the 'newlib' C runtime library that is distributed with Xtensa Tools, providing thread-safety on a per task basis (for use in tasks only, not interrupt handlers). NOTE: At this time only the 'newlib' C library is supported for thread safety. The 'xclib' and 'uclibc' libraries are not reentrant and do not provide thread safety at this time. However, if you are not concerned with reentrancy then you can use any of these libraries. This port also includes a simple example application that may run on a supported board or the Xtensa instruction set simulator (ISS). There are also a couple of test programs used in maintaining the port, which serve as additional examples. FreeRTOS for Xtensa configurable processors requires the following minimum processor configuration options: - Timer interrupt option with at least one interruptible timer. - Interrupt option (implied by the timer interrupt option). - Exception Architecture 2 (XEA2). Please note that XEA1 is NOT supported. All 'Diamond', 'Xtensa 6', 'Xtensa LX' and 'Xtensa LX2' processors and most 'Xtensa T1050' processors are configured with XEA2. All Diamond processor cores meet these requirements and are supported. Minimal support for certain evaluation boards is provided via a board independent XTBSP API implemented by a board specific library distributed with the Xtensa Tools. This provides the board clock frequency and basic polled drivers for the display and console device. Note that XTBSP is not a tradtional RTOS "board support package" with RTOS specific interrupt-driven drivers - it is not specific to any RTOS. Note that FreeRTOS can run on any Xtensa or Diamond board without 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. Installation ------------ This port is downloaded in a ZIP file from FreeRTOS Web site. You will also need to obtain the common FreeRTOS source package from FreeRTOS's website in order to build the OS and applications. The Xtensa port files are not currently included in the common package. All source is provided along with a Makefile that works for any host platform supported by Xtensa Tools (Windows, Linux). These instructions are written for Windows users, but can easily be understood and adapted to other host platforms. First install the FreeRTOS common package in a directory of your choosing. The structure of that package will look like this: FreeRTOS |-- Demo | |-- Common | | |-- Minimal | | `-- include | | | |-- Xtensa_XCC | `-- ParTest | `-- Source |-- include `-- portable |-- MemMang `-- XCC `-- Xtensa Since the Xtensa specific files are currently unavailable in the common package, then you will need the separate zip file containing the Xtensa port files. Extract from that zip file the Source/portable/XCC and Demo/Xtensa_XCC folders and place them in the appropriate location under the common tree. The Xtensa Tools are available from Cadence as part of a processor license. Be sure you have installed the Xtensa Tools and your processor configuration. Building FreeRTOS for Xtensa ---------------------------- The Makefiles are provided for your convenience and you do not need to use them. Essentially you need to compile all the FreeRTOS common files, the port files, and your application, and link them all. However all the build instructions in this note use the Makefiles. 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 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. The provided Makefile simplifies building FreeRTOS and the example for your Xtensa configuration and platform (ISS, board, etc.). There are detailed instructions in the comment at the top of the Makefile. The test/Makefile provides similar support for building the tests, and may be invoked directly from the top level Makefile. The Makefiles work on any host platform and support incremental builds. The build for each Xtensa configuration and target platform is placed in a subdirectory so several core and platform builds can co-exist even with incremental rebuilds. You may specify the root of the build area (if tou want it to be elsewhere than under the source tree) by defining BLDROOT either in the make command or your shell environment. First, be sure you have installed Xtensa Tools and your processor configuration, and be sure that Xtensa Tools are in your search path. You can use xt-make, which comes with the Xtensa Tools, to run the makefiles. Change directories to the Xtensa port directory: > cd FreeRTOS/Source/portable/XCC/Xtensa Now build the FreeRTOS RTOS as a library (libfreertos.a) as follows: > xt-make which by default builds for the simulator (TARGET=sim), or: > xt-make TARGET=board which builds for a supported board. Note that the board type does not need to be specified when building the FreeRTOS library. 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= XTENSA_SYSTEM= ... There are more details about build options in the comment in the Makefile. After the library has been built, you must link your application with this library in order to use FreeRTOS. Building a FreeRTOS Application ------------------------------- The provided FreeRTOS example is designed to run on the Xtensa instruction set simulator (ISS) or a supported evaluation board programmed with your Xtensa processor configuration. To build the example for the default platform (simulator): > xt-make example which is the same as > xt-make example TARGET=sim The boards currently supported are the Xilinx ML605 and KC705 FPGA development boards. To target these boards, type > xt-make example TARGET=ml605 or > xt-make example TARGET=kc705 To build in a location other than the default, specify the new location using the BLDROOT variable. Note that this makefile will invoke the FreeRTOS library build makefile automatically, passing on the relevant parameters based on what you specified. You can override the default compilation options by specifying the new options via CFLAGS. For example: > xt-make example TARGET=sim CFLAGS="-O2 -Os -g" This compiles example.c and links it with the FreeRTOS library libfreertos.a and the appropriate linker-support package (LSP) for your target platform (you can override the LSP by adding LSP= to the xt-make command line). The resulting file example.exe is an ELF binary file that can be downloaded and executed on the target. The example.exe binary appears in the platform specific subdirectory described earlier. For the following commands, change to that directory or prepend it as the path of example.exe. To build your application with thread-safe C library support using the open-source 'newlib' library provided with the Xtensa Tools, you need to make certain modifications to the application to plug in and invoke the newlib reentrancy support. This allows each task to use the library without interference with other tasks (it is not safe for interrupt handlers to call the C library). First, you must define XT_USE_THREAD_SAFE_CLIB to a nonzero either in FreeRTOSConfig.h or in the compiler's command line. Then, you must also make sure to allocate extra space on the stack for each task that will use the C library reentrant functions. This extra space is to be allocated over and above the actual stack space required by the task itself. The define XT_STACK_EXTRA_CLIB specifies the amount of extra space to be added on to the stack to allow saving the context for the C library as well as the coprocessors if any. E.g. if your task requires 2000 bytes of stack space, you must allocate (2000 + XT_STACK_EXTRA_CLIB) bytes for the stack. To build the example with thread-safe C library support: > xt-make CFLAGS="-O0 -DXT_USE_THREAD_SAFE_CLIB" example The "-O0" is necessary because you are overriding the default COPT=-O0. You can specify any optimization level you require (if none, the compiler defaults to -O2). Running or Debugging an Application ----------------------------------- To execute the example application on the simulator: > xt-run [--turbo] example.exe The option --turbo provides much faster, but non-cycle-accurate simulation (the --turbo option is only available with Xtensa Tools version 7 or later). To execute on the simulator using the Xplorer GUI based debugger: > xplorer --debug example.exe To execute on a supported evaluation board, download example.exe 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. 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. To use GDBIO, link with the gdbio LSP. Refer to Xtensa tools documentation for details. Task Stack Sizes ---------------- The application must ensure that every task has enough space for its stack. Each task needs enough space for its own use, its own interrupt stack frame (defined in xtensa_context.h) and space to save coprocessor state, if any. Several factors influence the size of the stack required, including the compiler optimization level and the use of the C library. Calls to standard output functions such as printf() can use up a lot of stack space. The tool xt-stack-usage is helpful in determining safe stack sizes for your application. Some macros are provided in xtensa_config.h to help determine the stack size for tasks that do and do not use the C library. Use these as the basis for each task's stack size. They are minimum requirements taking into account your configuration and use of the C library. In particular, the define XT_STACK_MIN_SIZE defines the minimum stack size for any task. Be very careful if you try to use a stack size smaller than this minimum. Stack overruns can cause all kinds of hard-to-debug errors. It is recommended that you enable the FreeRTOS stack checking features during development. WARNING: The newlib printf() function uses a lot of stack space. Be very careful in using it. Optionally you can use the 'libxtutil' library for output - it implements a subset of printf() that has smaller code size and uses far less stack space. More information about this library is in the Xtensa Tools documentation. Interrupt Stack --------------- Beginning with port version 1.2, the port uses a separate interrupt stack for handling interrupts. Thus, it is no longer necessary for each task to reserve space on its stack to handle interrupts. The size of the interrupt stack is controlled by the parameter "configISR_STACK_SIZE" defined in FreeRTOSConfig.h. Define this carefully to match your system requirements. Assembler / Compiler Switches ----------------------------- The following are compiler switches are used by the provided Makefile in building the FreeRTOS library and example application. These can be modified by editing the Makefile or by overriding the CFLAGS variable in the make command line, for example: > xt-make CFLAGS="-O2 -DXT_USE_THREAD_SAFE_CLIB" -g Specifies debug information. -c Specifies object code generation. -On Sets compiler optimization level n (default -O0). -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. See the compiler / linker documentation for a full list of switches and their use. Many definitions can be provided at compile-time via the -D option without editing the source code. Here are some of the more useful ones: XT_USE_THREAD_SAFE_CLIB Enable support for the reentrancy to provide thread-safety in the GNU newlib supplied with Xtensa Tools. Default off. Note, the follwing defines are unique to the Xtensa port so have names beginning with "XT_". XT_SIMULATOR Set this if building to run on the simulator. Takes advantage of certain simulator control and reporting facilities, and adjusts timing of periodic tick to provide a more acceptable performance in simulation (see XT_CLOCK_FREQ). Set by default unless PLATFORM is overridden. XT_BOARD Set this if building for a supported board. Be sure to specify the correct LSP for the board. See the example makefile for usage. XT_CLOCK_FREQ=freq Specifies the target processor's clock frequency in Hz. Used primarily to set the timer that generates the periodic interrupt. Defaults are provided and may be edited in xtensa_timer.h (see comments there also). Default for simulator provides more acceptable performance, but cannot provide real-time performance due to variation in simulation speed per host platform and insufficient cycles between interrupts to process them. Supported board platforms by default leave this undefined and compute the clock frequency at initialization unless this is explicitly defined. XT_TICK_PER_SEC=n Specifies the frequency of the periodic tick. XT_TIMER_INDEX=n Specifies which timer to use for periodic tick. Set this if your Xtensa processor configuration provides more than one suitable timer and you want to override the default. See xtensa_timer.h . XT_INTEXC_HOOKS Enables hooks in interrupt vector handlers to support dynamic installation of exception and interrupt handlers. Disabled by default. XT_USE_OVLY Enable code overlay support. It uses a mutex, hence configUSE_MUTEX must be enabled. This option is currently unsupported. XT_USE_SWPRI Enable software prioritization of interrupts. Enabling this will prioritize interrupts with 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. Register Usage and Stack Frames ------------------------------- The Xtensa architecture specifies two ABIs that determine how the general purpose registers a0-a15 are used: the standard windowed ABI use with the Xtensa windowed register file architecture, and the optional and more conventional Call0 ABI (required for Xtensa configurations without a windowed register file). Xtensa processors may have other special registers (including co-processor registers and other TIE "states") that are independent of this choice of ABI. See Xtensa documentation for more details. In the windowed ABI the registers of the current window are used as follows: a0 = return address a1 = stack pointer (alias sp) a2 = first argument and result of call (in simple cases) a3-7 = second through sixth arguments of call (in simple cases). Note that complex or large arguments are passed on the stack. Details are in the Xtensa Tools manuals. a8-a15 = available for use as temporaries. There are no callee-save registers. The windowed hardware automatically saves registers a0-a3 on a call4, a0-a8 on a call8, a0-a12 on a call12, by rotating the register window. Hardware triggers window overflow and underflow exceptions as necessary when registers outside the current window need to be spilled to preallocated space in the stack frame, or restored. Complete details are in the Xtensa manuals. The entire windowed register file is saved and restored on interrupt or task context switch. The Call0 ABI does not make use of register windows, relying instead on a fixed set of 16 registers without window rotation. The Call0 ABI is more conventional and uses registers as follows: a0 = return address a1 = stack pointer (alias sp) a2 = first argument and result of call (in simple cases) a3-7 = second through sixth arguments of call (in simple cases). Note that complex or large arguments are passed on the stack. Details are in the Xtensa Tools manuals. a8-a11 = scratch. a12-a15 = callee-save (a function must preserve these for its caller). On a FreeRTOS API call, callee-save registers are saved only when a task context switch occurs, and other registers are not saved at all (the caller does not expect them to be preserved). On an interrupt, callee-saved registers might only be saved and restored when a task context-switch occurs, but all other registers are always saved and restored. An Xtensa processor has other special registers independent of the ABI, depending on the configuration (including co-processor registers and other TIE state) that are part of the task context. FreeRTOS preserves all such registers over an unsolicited context-switch triggered by an interrupt. However it does NOT preserve these over a solicited context-switch during a FreeRTOS API call. This bears some explanation. These special registers are either ignored by the compiler or treated as caller-saved, meaning that if kept "live" over a function call (ie. need to be preserved) they must be saved and restored by the caller. Since solicited entry to FreeRTOS is always made by a function call, FreeRTOS assumes the caller has saved any of these registers that are "live". FreeRTOS avoids a lot of overhead by not having to save and restore every special register (there can be many) on every solicited context switch. As a consequence, the application developer should NOT assume that special registers are preserved over a FreeRTOS API call such as vTaskDelay(). If multiple tasks 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 task-level API calls (solicited frame) are described in human readable form in xtensa_context.h . All suspended tasks have one of these two types of stack frames. The top of the suspended task's stack is pointed to by pxCurrentTCB->pxTopOfStack. A special location common to both stack frames differentiates solicited and interrupt stack frames. Improving Performance, Footprint, or Ease of Debugging ------------------------------------------------------ By default FreeRTOS for Xtensa is built with debug (-g) and without compiler optimizations (-O0). This makes debugging easier. Of course, -O0 costs performance and usually also increases stack usage. To make FreeRTOS run faster you can change the Makefile to enable the desired optimizations or set a predefined optimization level (-O) . Maximum performance is achieved with -O3 -ipa, but that might increase the footprint substantially. A good compromise is -O2. See the compiler manual for details. Minimal footprint is achieved by optimizing for space with -Os, at the cost of some performance. See the compiler manual for details. The Xtensa architecture port-specific assembly files are coded with no file-scope labels inside functions (all labels inside functions begin with ".L"). This allows a profiler to accurately associate an address with a function, and also allows the debugger's stack trace to show the correct function wherever the program counter is within that function. However there are some tradeoffs in debugging. Local (".L") labels are not visible to the debugger, so the following limitations may be observed during debugging: - You cannot set a breakpoint on a local label inside a function. - Disassembly will show the entire function, but will get out of sync and show incorrect opcodes if it crosses any padding before an aligned local branch target (".L" label, not ".Ln"). Restart disassembly specifying an address range explicitly between points where there is padding. Since FreeRTOS is provided in source form, it is not difficult to remove the ".L" and ".Ln" prefixes from local labels if you want them visible. They can also be made visible by passing the '-L' option to the assembler and linker (see the assembler and linker manuals for details). Interrupt and Exception Handling -------------------------------- FreeRTOS provides a complete set of efficient exception and first-level interrupt handlers installed at the appropriate exception and interrupt vector locations. The Xtensa architecture supports several different classes of exceptions and interrupts. Being a configurable architecture, many of these are optional, and the vector locations are determined by your processor configuration. (Note that Diamond cores are pre-configured with specific vector locations.) The handlers provided use conditional compilation to adapt to your processor configuration and include only the code that is needed. Xtensa vector locations may reside almost anywhere, including in ROM. The amount of code space available at each of these locations is often very small (e.g. due to following vectors). A small stub of code installed at the vector jumps to the corresponding handler, usually in RAM. The exception and interrupt handlers are defined in xtensa_vectors.S. They are not specific to FreeRTOS, but call into FreeRTOS where appropriate via macros defined in xtensa_rtos.h . The handlers provided for low and medium priority interrupts are just dispatchers that save relevant state and call user-definable handlers. See the files xtensa_vectors.S and xtensa_api.h for more details of how to create and install application-specific user interrupt handlers. Similarly, user-defined handlers can be installed for exceptions (other than a few which are always handled by the OS). The high priority interrupt handlers provided may be considered templates into which the application adds code to service specific interrupts. The places where application handlers should be inserted are tagged with the comment "USER_EDIT" in xtensa_vectors.S. This FreeRTOS port supports strict priority-based nesting of interrupts. An interrupt may only nest on top of one of strictly lower priority. Equal priority interrupts concurrently pending are handled in an application-defined sequence before any lower priority interrupts are handled. During interrupt and exception handling, the processor's interrupt level (PS.INTLEVEL) is used to control the interrupt priority level that can be accepted; interrupt sources are not controlled individually by FreeRTOS (the application is free to access the INTENABLE register directly to enable/disable individual interrupts, eg. using Xtensa HAL services). This approach provides the most deterministic bounds on interrupt latency (for a given priority) and stack depth. Software prioritization of interrupts at the same priority is controlled by the definition of XT_USE_SWPRI. See above for a description of this parameter. The following subsections describe the handling of each class of exception and interrupt in more detail. Many have nothing to do with FreeRTOS but are mentioned because there is code to handle them in xtensa_vectors.S. User Exception and Interrupt Handler (Low/Medium Priority): All Xtensa 'general exceptions' come to the user, kernel, or double exception vector. The exception type is identified by the EXCCAUSE special register (level 1 interrupts are one particular cause of a general exception). This port sets up PS to direct all such exceptions to the user vector. Exceptions taken at the other two vectors usually indicate a kernel or application bug. Level 1 interrupts are identified at the beginning of the handler and are dispatched to a dedicated handler. Then, syscall and alloca exceptions are identified and dispatched to special handlers described below. After this, coprocessor exceptions are identified and dispatched to the coprocessor handler. Any remaining exceptions are processed as follows: Having allocated the exception stack frame, the user exception handler saves the current task state and sets up a C environment and enables the high-priority class of interrupts (which do not interact with FreeRTOS), then reads EXCCAUSE and uses the cause (number) to index into a table of user-specified handlers. The correct handler is then called. If the handler returns, the context is restored and control is returned to the code that caused the exception. The user-defined handler may alter the saved context, or any other system state, that allows the faulting instruction to be retried. If the cause is a level 1 (low-priority) or medium-priority interrupt, the handler enables all interrupts above that priority level after saving the task context. It then sets up the environment for C code and then calls the handler (found in the handler table) for the interrupt number. If the user has not specified a handler, then the default handler will be called, which will terminate the program. If the interrupt is for the system timer, it calls a special interrupt handler for the system timer tick, which calls _frxt_timer_int then clears its bit from the mask. This interrupt cannot be hooked by the user-defined handler. Finally, the handler calls _frxt_int_exit to allow FreeRTOS to perform any scheduling necessary and return either to the interrupted task or another. If software prioritization is enabled, the handler will re-enable all interrupts at the same level that are numerically higher than the current one, before calling the user handler. This allows a higher priority interrupt to pre-empt the lower priority handler. Medium Priority Interrupt Handlers: Medium priority interrupts are those at levels 2 up to XCHAL_EXCM_LEVEL, a configuration-specific maximum interrupt level affected by the global 'exception mode' bit in the processor status word (PS.EXCM). Interrupt levels above XCHAL_EXCM_LEVEL are of the high-priority class. The Xtensa hardware documentation considers medium priority interrupts to be a special case of high-priority interrupts, but from a software perspective they are very different. Dispatch of medium-priority interrupts is discussed in the section above. High Priority Interrupt Handlers: High priority interrupts are those strictly above XCHAL_EXCM_LEVEL, a configuration-specific maximum interrupt level affected by the global 'exception mode' bit in the processor status word (PS.EXCM). High priority handlers may not directly interact with FreeRTOS at all, and are described here only for the sake of completeness. They must be coded in assembler (may not be coded in C) and are intended to be used for handling extremely high frequency hardware events that need to be handled in only a few cycles. A high priority interrupt handler may trigger a software interrupt at a medium or low priority level to occasionally signal FreeRTOS. Please see Xtensa documentation. There is a separate vector and a few special registers for each high priority interrupt, providing for fast dispatch and efficient nesting on top of lower priority interrupts. Handlers are templates included only for the vectors that exist in your Xtensa processor configuration. These templates are written for only one interrupt per high priority level to minimize latency servicing very fast time-critical interrupts. The vector code jumps to the corresponding first-level interrupt handler, which then executes application-provided assembler code before returning quickly to the interrupted task or lower priority handler. Kernel Exception Handler: Kernel mode is not used in this port of FreeRTOS, and therefore kernel exceptions should not happen. A stub is provided for the vector that triggers the debugger (if connected) or calls _xt_panic to freeze the processor should a kernel exception occur. Alloca Exception Handler: Alloca exceptions are generated by the 'movsp' instruction, which is used only in the windowed ABI. Its purpose is to allocate some space on top of the stack. Because the window hardware may have spilled some registers to the 16 byte "base save" area below the stack pointer, it is necessary to protect those values. The alloca handler accomplishes this quickly without setting up an interrupt frame or entering FreeRTOS, by emulating a register underflow and re-executing 'movsp'. Syscall Exception Handler: Syscall exceptions are generated by a 'syscall' instruction. The windowed ABI specifies that executing this instruction with a value of zero in register a2 must spill any unsaved registers in the windowed register file to their pre-determined locations on the caller's stack. The handler does exactly that, and skips over the 'syscall' instruction before returning to the caller. If a2 is non-zero, the handler returns a2 == -1 to the caller. Co-Processor Exception Handler: A co-processor exception is generated when a task accesses a co-processor that it does not "own". Ownership represents which task's state is currently in the co-processor. Co-processors are context-switched "lazily" (on demand) only when a non-owning task uses a co-processor instruction, otherwise a task retains ownership even when it is preempted from the main processor. The co-processor exception handler performs the context-switch and manages ownership. Co-processors may not be used by any code outside the context of a task. A co-processor exception triggered by code that is not part of a running task is a fatal error and FreeRTOS for Xtensa will panic. This restriction is intended to reduce the overhead of saving and restoring co-processor state (which can be quite large) and in particular remove that overhead from interrupt handlers. Debug Exception Handler: A debug exception is caused as a result of running code, such as by a 'break' instruction or hardware breakpoints and watchpoints, or as a result of an external debug interrupt, such as from an OCD based debugger or multiprocessor debug events ("breakin/breakout"). If the processor is running in OCD mode under control of an OCD-based debugger, the trigger event immediately halts the processor and gives control to the OCD debugger. Otherwise control is transferred to the debug vector. The debug vector handler calls the simulator if running on the ISS, which then takes control and interacts with any attached debugger. If running on hardware and not in OCD mode, debug exceptions are not expected, so the debug handler calls _xt_panic to freeze the processor. Double Exception Handler: A double exception is a general exception that happens while the processor is in exception mode (PS.EXCM set), and thus indicates a bug in kernel code. The double exception vector handler triggers the debugger (if connected) or calls _xt_panic to freeze the processor. Window Overflow and Underflow Exception Handlers: Window overflow and underflow handlers are required for use of the windowed ABI. Each has its own dedicated vector and highly optimized code that is independent of OS. See Xtensa documentation for details. Hooks for Dynamic Installation of Handlers: Optional hooks are provided in the user exception and low level interrupt handler and all medium and high priority interrupt handlers, to dynamically install a handler function (which may be coded in C, unless in a high-priority interrupt handler). These hooks are enabled and used by automatic regression tests, they are not part of a normal FreeRTOS build. However an application is free to take advantage of them. The interrupt/exception hooks are described in xtensa_rtos.h . It is recommended that the application not make use of these hooks, but rather use xt_set_interrupt_handler() and xt_set_exception_handler() to install application-specific handlers. This method is more convenient and allows arguments to be passed to the handlers. Software prioritization of interrupts works only with this method. See xtensa_api.h for details. Overlay Support Code overlays are currently not supported for FreeRTOS. This will be supported in a future release. Make sure that the option XT_USE_OVLY is never defined when building. Note on Porting Methodology and Copyrights ------------------------------------------ This port is based on a well-tested Cadence RTOS porting layer that abstracts out Xtensa-generic aspects from the RTOS specifics in the same way most RTOSes abstract out their generic code from the architecture specific port code. This code is common to several RTOSes ported by Cadence, and deals with highly Xtensa specific aspects such as context save/restore, interrupt and exception dispatch, and handling of co-processor, alloc and window over/underflow exceptions. The porting layer files are prefixed "xtensa_" and belong to Cadence (they are provided freely as part of this port but are not subject to FreeRTOS's copyright). The rest of the port is FreeRTOS specific and are under FreeRTOS's copyright. The Makefiles are also provided by Cadence so have much in common with other RTOS Makefiles provided by Cadence. -End-