123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764 |
- FreeRTOS Port for Xtensa Configurable and Diamond Processors
- ============================================================
- FreeRTOS Kernel Version 10.0.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 FreeRTOS kernel version 10.0.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' and
- 'xclib' C runtime libraries 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 'newlib' and 'xclib' C libraries are supported
- for thread safety. The 'uclibc' library is not reentrant and does 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
- ------------
- The Xtensa port of FreeRTOS is available at this location:
- https://github.com/foss-xtensa/amazon-freertos
- This download includes the core FreeRTOS source and include files needed
- to build the port. You can also download the official release of FreeRTOS
- version 1.0.0 or later from this location:
- https://github.com/aws/amazon-freertos
- The Xtensa port files are currently not included in the official 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:
- <install directory>
- |-- demos
- | `-- cadence
- | `-- sim
- | |-- common
- | | |-- application_code
- | | | `-- cadence_code
- | | `-- config_files
- | `-- xplorer
- `-- lib
- |-- FreeRTOS
- | `-- portable
- | |-- Common
- | |-- MemMang
- | `-- XCC
- | `-- Xtensa
- `-- include
- `-- private
- 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
- ----------------------------
- To build the FreeRTOS library and the example programs, go into the
- directory 'demos/cadence/sim' and use the makefile in that directory.
- "make all" will build all the examples. There is another makefile in
- the 'lib/FreeRTOS/portable/XCC/Xtensa' directory that builds just the
- FreeRTOS library.
- 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 comments at the top of the makefile.
- The makefiles work on Windows and Linux 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.
- Building the FreeRTOS Library
- -----------------------------
- 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 lib/FreeRTOS/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=<your_config_name> XTENSA_SYSTEM=<your_registry> ...
- 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 the FreeRTOS Examples
- ------------------------------
- The provided examples are designed to run on the Xtensa instruction set
- simulator (ISS) or a supported evaluation board programmed with your
- Xtensa processor configuration.
- To build the examples for the default platform (simulator):
- > cd demos/cadence/sim
- > xt-make all
- which is the same as
- > xt-make all TARGET=sim
- The boards currently supported are the Xilinx ML605 and KC705 FPGA
- development boards. To target these boards, type
- > xt-make all TARGET=ml605
- or
- > xt-make all 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 all TARGET=sim CFLAGS="-O2 -Os -g"
- This compiles the examples and links them 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=<lsp> to the
- xt-make command line). The resulting ELF files can be downloaded and
- executed on the target. The example binaries appear in the platform
- specific subdirectory described earlier.
- To build your application with thread-safe C library support, you
- need to make certain modifications to the application to plug in and
- invoke the 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 value either in xtensa_config.h or on the compiler's command
- line. Note that the default xtensa_config.h provided with this port does
- define this to 1 if either newlib or xclib is detected.
- 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.
- IMPORTANT NOTE
- --------------
- The header file FreeRTOS.h, which is a part of the core FreeRTOS sources,
- includes <reent.h> if thread safety for the C libraries is enabled. For
- xclib, this file exists in <sys/reent.h> and so is reported as missing.
- To work around this, the makefiles supplied with this port will copy the
- reent.h header into the build directory during the build process. If you
- use a different build process, then you must make sure to copy this file
- to a location that is included in the list of include paths. This can be
- the build directory or the directory that contains the Xtensa port source
- files.
- 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 for the newlib and xclib libraries
- supplied with Xtensa Tools. Default ON.
- 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<level>) .
- 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.
- -End-
|