sync from github to svn: Xtensa GCC as-is.

This commit is contained in:
Yuhui.Zheng
2019-09-20 22:09:21 +00:00
parent 1c5fcc7f05
commit 6f958bbf80
19 changed files with 6146 additions and 0 deletions
@@ -0,0 +1,24 @@
/*
* Since at least FreeRTOS V7.5.3 uxTopUsedPriority is no longer
* present in the kernel, so it has to be supplied by other means for
* OpenOCD's threads awareness.
*
* Add this file to your project, and, if you're using --gc-sections,
* ``--undefined=uxTopUsedPriority'' (or
* ``-Wl,--undefined=uxTopUsedPriority'' when using gcc for final
* linking) to your LDFLAGS; same with all the other symbols you need.
*/
#include "FreeRTOS.h"
#include "esp_attr.h"
#include "sdkconfig.h"
#ifdef __GNUC__
#define USED __attribute__((used))
#else
#define USED
#endif
#ifdef CONFIG_ESP32_DEBUG_OCDAWARE
const int USED DRAM_ATTR uxTopUsedPriority = configMAX_PRIORITIES - 1;
#endif
@@ -0,0 +1,46 @@
/*******************************************************************************
// Copyright (c) 2003-2015 Cadence Design Systems, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
*/
/*
* This utility helps benchmarking interrupt latency and context switches.
* In order to enable it, set configBENCHMARK to 1 in FreeRTOSConfig.h.
* You will also need to download the FreeRTOS_trace patch that contains
* portbenchmark.c and the complete version of portbenchmark.h
*/
#ifndef PORTBENCHMARK_H
#define PORTBENCHMARK_H
#if configBENCHMARK
#error "You need to download the FreeRTOS_trace patch that overwrites this file"
#endif
#define portbenchmarkINTERRUPT_DISABLE()
#define portbenchmarkINTERRUPT_RESTORE(newstate)
#define portbenchmarkIntLatency()
#define portbenchmarkIntWait()
#define portbenchmarkReset()
#define portbenchmarkPrint()
#endif /* PORTBENCHMARK */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,130 @@
/*******************************************************************************
Copyright (c) 2006-2015 Cadence Design Systems Inc.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
******************************************************************************/
/******************************************************************************
Xtensa-specific API for RTOS ports.
******************************************************************************/
#ifndef __XTENSA_API_H__
#define __XTENSA_API_H__
#include <xtensa/hal.h>
#include "xtensa_context.h"
/* Typedef for C-callable interrupt handler function */
typedef void (*xt_handler)(void *);
/* Typedef for C-callable exception handler function */
typedef void (*xt_exc_handler)(XtExcFrame *);
/*
-------------------------------------------------------------------------------
Call this function to set a handler for the specified exception. The handler
will be installed on the core that calls this function.
n - Exception number (type)
f - Handler function address, NULL to uninstall handler.
The handler will be passed a pointer to the exception frame, which is created
on the stack of the thread that caused the exception.
If the handler returns, the thread context will be restored and the faulting
instruction will be retried. Any values in the exception frame that are
modified by the handler will be restored as part of the context. For details
of the exception frame structure see xtensa_context.h.
-------------------------------------------------------------------------------
*/
extern xt_exc_handler xt_set_exception_handler(int n, xt_exc_handler f);
/*
-------------------------------------------------------------------------------
Call this function to set a handler for the specified interrupt. The handler
will be installed on the core that calls this function.
n - Interrupt number.
f - Handler function address, NULL to uninstall handler.
arg - Argument to be passed to handler.
-------------------------------------------------------------------------------
*/
extern xt_handler xt_set_interrupt_handler(int n, xt_handler f, void * arg);
/*
-------------------------------------------------------------------------------
Call this function to enable the specified interrupts on the core that runs
this code.
mask - Bit mask of interrupts to be enabled.
-------------------------------------------------------------------------------
*/
extern void xt_ints_on(unsigned int mask);
/*
-------------------------------------------------------------------------------
Call this function to disable the specified interrupts on the core that runs
this code.
mask - Bit mask of interrupts to be disabled.
-------------------------------------------------------------------------------
*/
extern void xt_ints_off(unsigned int mask);
/*
-------------------------------------------------------------------------------
Call this function to set the specified (s/w) interrupt.
-------------------------------------------------------------------------------
*/
static inline void xt_set_intset(unsigned int arg)
{
xthal_set_intset(arg);
}
/*
-------------------------------------------------------------------------------
Call this function to clear the specified (s/w or edge-triggered)
interrupt.
-------------------------------------------------------------------------------
*/
static inline void xt_set_intclear(unsigned int arg)
{
xthal_set_intclear(arg);
}
/*
-------------------------------------------------------------------------------
Call this function to get handler's argument for the specified interrupt.
n - Interrupt number.
-------------------------------------------------------------------------------
*/
extern void * xt_get_interrupt_handler_arg(int n);
#endif /* __XTENSA_API_H__ */
@@ -0,0 +1,146 @@
/*******************************************************************************
// Copyright (c) 2003-2015 Cadence Design Systems, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
Configuration-specific information for Xtensa build. This file must be
included in FreeRTOSConfig.h to properly set up the config-dependent
parameters correctly.
NOTE: To enable thread-safe C library support, XT_USE_THREAD_SAFE_CLIB must
be defined to be > 0 somewhere above or on the command line.
*******************************************************************************/
#ifndef XTENSA_CONFIG_H
#define XTENSA_CONFIG_H
#ifdef __cplusplus
extern "C" {
#endif
#include <xtensa/hal.h>
#include <xtensa/config/core.h>
#include <xtensa/config/system.h> /* required for XSHAL_CLIB */
#include "xtensa_context.h"
/*-----------------------------------------------------------------------------
* STACK REQUIREMENTS
*
* This section defines the minimum stack size, and the extra space required to
* be allocated for saving coprocessor state and/or C library state information
* (if thread safety is enabled for the C library). The sizes are in bytes.
*
* Stack sizes for individual tasks should be derived from these minima based on
* the maximum call depth of the task and the maximum level of interrupt nesting.
* A minimum stack size is defined by XT_STACK_MIN_SIZE. This minimum is based
* on the requirement for a task that calls nothing else but can be interrupted.
* This assumes that interrupt handlers do not call more than a few levels deep.
* If this is not true, i.e. one or more interrupt handlers make deep calls then
* the minimum must be increased.
*
* If the Xtensa processor configuration includes coprocessors, then space is
* allocated to save the coprocessor state on the stack.
*
* If thread safety is enabled for the C runtime library, (XT_USE_THREAD_SAFE_CLIB
* is defined) then space is allocated to save the C library context in the TCB.
*
* Allocating insufficient stack space is a common source of hard-to-find errors.
* During development, it is best to enable the FreeRTOS stack checking features.
*
* Usage:
*
* XT_USE_THREAD_SAFE_CLIB -- Define this to a nonzero value to enable thread-safe
* use of the C library. This will require extra stack
* space to be allocated for tasks that use the C library
* reentrant functions. See below for more information.
*
* NOTE: The Xtensa toolchain supports multiple C libraries and not all of them
* support thread safety. Check your core configuration to see which C library
* was chosen for your system.
*
* XT_STACK_MIN_SIZE -- The minimum stack size for any task. It is recommended
* that you do not use a stack smaller than this for any
* task. In case you want to use stacks smaller than this
* size, you must verify that the smaller size(s) will work
* under all operating conditions.
*
* XT_STACK_EXTRA -- The amount of extra stack space to allocate for a task
* that does not make C library reentrant calls. Add this
* to the amount of stack space required by the task itself.
*
* XT_STACK_EXTRA_CLIB -- The amount of space to allocate for C library state.
*
-----------------------------------------------------------------------------*/
/* Extra space required for interrupt/exception hooks. */
#ifdef XT_INTEXC_HOOKS
#ifdef __XTENSA_CALL0_ABI__
#define STK_INTEXC_EXTRA 0x200
#else
#define STK_INTEXC_EXTRA 0x180
#endif
#else
#define STK_INTEXC_EXTRA 0
#endif
#define XT_CLIB_CONTEXT_AREA_SIZE 0
/*------------------------------------------------------------------------------
Extra size -- interrupt frame plus coprocessor save area plus hook space.
NOTE: Make sure XT_INTEXC_HOOKS is undefined unless you really need the hooks.
------------------------------------------------------------------------------*/
#ifdef __XTENSA_CALL0_ABI__
#define XT_XTRA_SIZE (XT_STK_FRMSZ + STK_INTEXC_EXTRA + 0x10 + XT_CP_SIZE)
#else
#define XT_XTRA_SIZE (XT_STK_FRMSZ + STK_INTEXC_EXTRA + 0x20 + XT_CP_SIZE)
#endif
/*------------------------------------------------------------------------------
Space allocated for user code -- function calls and local variables.
NOTE: This number can be adjusted to suit your needs. You must verify that the
amount of space you reserve is adequate for the worst-case conditions in your
application.
NOTE: The windowed ABI requires more stack, since space has to be reserved
for spilling register windows.
------------------------------------------------------------------------------*/
#ifdef __XTENSA_CALL0_ABI__
#define XT_USER_SIZE 0x200
#else
#define XT_USER_SIZE 0x400
#endif
/* Minimum recommended stack size. */
#define XT_STACK_MIN_SIZE ((XT_XTRA_SIZE + XT_USER_SIZE) / sizeof(unsigned char))
/* OS overhead with and without C library thread context. */
#define XT_STACK_EXTRA (XT_XTRA_SIZE)
#define XT_STACK_EXTRA_CLIB (XT_XTRA_SIZE + XT_CLIB_CONTEXT_AREA_SIZE)
#ifdef __cplusplus
}
#endif
#endif /* XTENSA_CONFIG_H */
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,159 @@
/*******************************************************************************
// Copyright (c) 2003-2015 Cadence Design Systems, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
XTENSA INFORMATION FOR RTOS TICK TIMER AND CLOCK FREQUENCY
This header contains definitions and macros for use primarily by Xtensa
RTOS assembly coded source files. It includes and uses the Xtensa hardware
abstraction layer (HAL) to deal with config specifics. It may also be
included in C source files.
User may edit to modify timer selection and to specify clock frequency and
tick duration to match timer interrupt to the real-time tick duration.
If the RTOS has no timer interrupt, then there is no tick timer and the
clock frequency is irrelevant, so all of these macros are left undefined
and the Xtensa core configuration need not have a timer.
*******************************************************************************/
#ifndef XTENSA_TIMER_H
#define XTENSA_TIMER_H
#ifdef __ASSEMBLER__
#include <xtensa/coreasm.h>
#endif
#include <xtensa/corebits.h>
#include <xtensa/config/system.h>
#include "xtensa_rtos.h" /* in case this wasn't included directly */
#include "FreeRTOSConfig.h"
/*
Select timer to use for periodic tick, and determine its interrupt number
and priority. User may specify a timer by defining XT_TIMER_INDEX with -D,
in which case its validity is checked (it must exist in this core and must
not be on a high priority interrupt - an error will be reported in invalid).
Otherwise select the first low or medium priority interrupt timer available.
*/
#if XCHAL_NUM_TIMERS == 0
#error "This Xtensa configuration is unsupported, it has no timers."
#else
#ifndef XT_TIMER_INDEX
#if XCHAL_TIMER3_INTERRUPT != XTHAL_TIMER_UNCONFIGURED
#if XCHAL_INT_LEVEL(XCHAL_TIMER3_INTERRUPT) <= XCHAL_EXCM_LEVEL
#undef XT_TIMER_INDEX
#define XT_TIMER_INDEX 3
#endif
#endif
#if XCHAL_TIMER2_INTERRUPT != XTHAL_TIMER_UNCONFIGURED
#if XCHAL_INT_LEVEL(XCHAL_TIMER2_INTERRUPT) <= XCHAL_EXCM_LEVEL
#undef XT_TIMER_INDEX
#define XT_TIMER_INDEX 2
#endif
#endif
#if XCHAL_TIMER1_INTERRUPT != XTHAL_TIMER_UNCONFIGURED
#if XCHAL_INT_LEVEL(XCHAL_TIMER1_INTERRUPT) <= XCHAL_EXCM_LEVEL
#undef XT_TIMER_INDEX
#define XT_TIMER_INDEX 1
#endif
#endif
#if XCHAL_TIMER0_INTERRUPT != XTHAL_TIMER_UNCONFIGURED
#if XCHAL_INT_LEVEL(XCHAL_TIMER0_INTERRUPT) <= XCHAL_EXCM_LEVEL
#undef XT_TIMER_INDEX
#define XT_TIMER_INDEX 0
#endif
#endif
#endif
#ifndef XT_TIMER_INDEX
#error "There is no suitable timer in this Xtensa configuration."
#endif
#define XT_CCOMPARE (CCOMPARE + XT_TIMER_INDEX)
#define XT_TIMER_INTNUM XCHAL_TIMER_INTERRUPT(XT_TIMER_INDEX)
#define XT_TIMER_INTPRI XCHAL_INT_LEVEL(XT_TIMER_INTNUM)
#define XT_TIMER_INTEN (1 << XT_TIMER_INTNUM)
#if XT_TIMER_INTNUM == XTHAL_TIMER_UNCONFIGURED
#error "The timer selected by XT_TIMER_INDEX does not exist in this core."
#elif XT_TIMER_INTPRI > XCHAL_EXCM_LEVEL
#error "The timer interrupt cannot be high priority (use medium or low)."
#endif
#endif /* XCHAL_NUM_TIMERS */
/*
Set processor clock frequency, used to determine clock divisor for timer tick.
User should BE SURE TO ADJUST THIS for the Xtensa platform being used.
If using a supported board via the board-independent API defined in xtbsp.h,
this may be left undefined and frequency and tick divisor will be computed
and cached during run-time initialization.
NOTE ON SIMULATOR:
Under the Xtensa instruction set simulator, the frequency can only be estimated
because it depends on the speed of the host and the version of the simulator.
Also because it runs much slower than hardware, it is not possible to achieve
real-time performance for most applications under the simulator. A frequency
too low does not allow enough time between timer interrupts, starving threads.
To obtain a more convenient but non-real-time tick duration on the simulator,
compile with xt-xcc option "-DXT_SIMULATOR".
Adjust this frequency to taste (it's not real-time anyway!).
*/
#if defined(XT_SIMULATOR) && !defined(XT_CLOCK_FREQ)
#define XT_CLOCK_FREQ configCPU_CLOCK_HZ
#endif
#if !defined(XT_CLOCK_FREQ) && !defined(XT_BOARD)
#error "XT_CLOCK_FREQ must be defined for the target platform."
#endif
/*
Default number of timer "ticks" per second (default 100 for 10ms tick).
RTOS may define this in its own way (if applicable) in xtensa_rtos.h.
User may redefine this to an optimal value for the application, either by
editing this here or in xtensa_rtos.h, or compiling with xt-xcc option
"-DXT_TICK_PER_SEC=<value>" where <value> is a suitable number.
*/
#ifndef XT_TICK_PER_SEC
#define XT_TICK_PER_SEC configTICK_RATE_HZ /* 10 ms tick = 100 ticks per second */
#endif
/*
Derivation of clock divisor for timer tick and interrupt (one per tick).
*/
#ifdef XT_CLOCK_FREQ
#define XT_TICK_DIVISOR (XT_CLOCK_FREQ / XT_TICK_PER_SEC)
#endif
#ifndef __ASSEMBLER__
extern unsigned _xt_tick_divisor;
extern void _xt_tick_divisor_init(void);
#endif
#endif /* XTENSA_TIMER_H */
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,111 @@
/*
Copyright (C) 2016-2017 Espressif Shanghai PTE LTD
Copyright (C) 2015 Real Time Engineers Ltd.
All rights reserved
FreeRTOS is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
***************************************************************************
>>! NOTE: The modification to the GPL is included to allow you to !<<
>>! distribute a combined work that includes FreeRTOS without being !<<
>>! obliged to provide the source code for proprietary components !<<
>>! outside of the FreeRTOS kernel. !<<
***************************************************************************
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. Full license text is available on the following
link: http://www.freertos.org/a00114.html
*/
/* This header exists for performance reasons, in order to inline the
implementation of vPortCPUAcquireMutexIntsDisabled and
vPortCPUReleaseMutexIntsDisabled into the
vTaskEnterCritical/vTaskExitCritical functions in task.c as well as the
vPortCPUAcquireMutex/vPortCPUReleaseMutex implementations.
Normally this kind of performance hack is over the top, but
vTaskEnterCritical/vTaskExitCritical is called a great
deal by FreeRTOS internals.
It should be #included by freertos port.c or tasks.c, in esp-idf.
The way it works is that it essentially uses portmux_impl.inc.h as a
generator template of sorts. When no external memory is used, this
template is only used to generate the vPortCPUAcquireMutexIntsDisabledInternal
and vPortCPUReleaseMutexIntsDisabledInternal functions, which use S32C1 to
do an atomic compare & swap. When external memory is used the functions
vPortCPUAcquireMutexIntsDisabledExtram and vPortCPUReleaseMutexIntsDisabledExtram
are also generated, which use uxPortCompareSetExtram to fake the S32C1 instruction.
The wrapper functions vPortCPUAcquireMutexIntsDisabled and
vPortCPUReleaseMutexIntsDisabled will then use the appropriate function to do the
actual lock/unlock.
*/
#include "soc/cpu.h"
#include "portable.h"
/* XOR one core ID with this value to get the other core ID */
#define CORE_ID_XOR_SWAP (CORE_ID_PRO ^ CORE_ID_APP)
//Define the mux routines for use with muxes in internal RAM
#define PORTMUX_AQUIRE_MUX_FN_NAME vPortCPUAcquireMutexIntsDisabledInternal
#define PORTMUX_RELEASE_MUX_FN_NAME vPortCPUReleaseMutexIntsDisabledInternal
#define PORTMUX_COMPARE_SET_FN_NAME uxPortCompareSet
#include "portmux_impl.inc.h"
#undef PORTMUX_AQUIRE_MUX_FN_NAME
#undef PORTMUX_RELEASE_MUX_FN_NAME
#undef PORTMUX_COMPARE_SET_FN_NAME
#if defined(CONFIG_SPIRAM_SUPPORT)
#define PORTMUX_AQUIRE_MUX_FN_NAME vPortCPUAcquireMutexIntsDisabledExtram
#define PORTMUX_RELEASE_MUX_FN_NAME vPortCPUReleaseMutexIntsDisabledExtram
#define PORTMUX_COMPARE_SET_FN_NAME uxPortCompareSetExtram
#include "portmux_impl.inc.h"
#undef PORTMUX_AQUIRE_MUX_FN_NAME
#undef PORTMUX_RELEASE_MUX_FN_NAME
#undef PORTMUX_COMPARE_SET_FN_NAME
#endif
#ifdef CONFIG_FREERTOS_PORTMUX_DEBUG
#define PORTMUX_AQUIRE_MUX_FN_ARGS portMUX_TYPE *mux, int timeout_cycles, const char *fnName, int line
#define PORTMUX_RELEASE_MUX_FN_ARGS portMUX_TYPE *mux, const char *fnName, int line
#define PORTMUX_AQUIRE_MUX_FN_CALL_ARGS(x) x, timeout_cycles, fnName, line
#define PORTMUX_RELEASE_MUX_FN_CALL_ARGS(x) x, fnName, line
#else
#define PORTMUX_AQUIRE_MUX_FN_ARGS portMUX_TYPE *mux, int timeout_cycles
#define PORTMUX_RELEASE_MUX_FN_ARGS portMUX_TYPE *mux
#define PORTMUX_AQUIRE_MUX_FN_CALL_ARGS(x) x, timeout_cycles
#define PORTMUX_RELEASE_MUX_FN_CALL_ARGS(x) x
#endif
static inline bool __attribute__((always_inline)) vPortCPUAcquireMutexIntsDisabled(PORTMUX_AQUIRE_MUX_FN_ARGS) {
#if defined(CONFIG_SPIRAM_SUPPORT)
if (esp_ptr_external_ram(mux)) {
return vPortCPUAcquireMutexIntsDisabledExtram(PORTMUX_AQUIRE_MUX_FN_CALL_ARGS(mux));
}
#endif
return vPortCPUAcquireMutexIntsDisabledInternal(PORTMUX_AQUIRE_MUX_FN_CALL_ARGS(mux));
}
static inline void vPortCPUReleaseMutexIntsDisabled(PORTMUX_RELEASE_MUX_FN_ARGS) {
#if defined(CONFIG_SPIRAM_SUPPORT)
if (esp_ptr_external_ram(mux)) {
vPortCPUReleaseMutexIntsDisabledExtram(PORTMUX_RELEASE_MUX_FN_CALL_ARGS(mux));
return;
}
#endif
vPortCPUReleaseMutexIntsDisabledInternal(PORTMUX_RELEASE_MUX_FN_CALL_ARGS(mux));
}
@@ -0,0 +1,169 @@
/*
Copyright (C) 2016-2017 Espressif Shanghai PTE LTD
Copyright (C) 2015 Real Time Engineers Ltd.
All rights reserved
FreeRTOS is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
***************************************************************************
>>! NOTE: The modification to the GPL is included to allow you to !<<
>>! distribute a combined work that includes FreeRTOS without being !<<
>>! obliged to provide the source code for proprietary components !<<
>>! outside of the FreeRTOS kernel. !<<
***************************************************************************
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. Full license text is available on the following
link: http://www.freertos.org/a00114.html
*/
/*
Warning: funky preprocessor hackery ahead. Including these headers will generate two
functions, which names are defined by the preprocessor macros
PORTMUX_AQUIRE_MUX_FN_NAME and PORTMUX_RELEASE_MUX_FN_NAME. In order to do the compare
and exchange function, they will use whatever PORTMUX_COMPARE_SET_FN_NAME resolves to.
In some scenarios, this header is included *twice* in portmux_impl.h: one time
for the 'normal' mux code which uses a compare&exchange routine, another time
to generate code for a second set of these routines that use a second mux
(in internal ram) to fake a compare&exchange on a variable in external memory.
*/
static inline bool __attribute__((always_inline))
#ifdef CONFIG_FREERTOS_PORTMUX_DEBUG
PORTMUX_AQUIRE_MUX_FN_NAME(portMUX_TYPE *mux, int timeout_cycles, const char *fnName, int line) {
#else
PORTMUX_AQUIRE_MUX_FN_NAME(portMUX_TYPE *mux, int timeout_cycles) {
#endif
#if !CONFIG_FREERTOS_UNICORE
uint32_t res;
portBASE_TYPE coreID, otherCoreID;
uint32_t ccount_start;
bool set_timeout = timeout_cycles > portMUX_NO_TIMEOUT;
#ifdef CONFIG_FREERTOS_PORTMUX_DEBUG
if (!set_timeout) {
timeout_cycles = 10000; // Always set a timeout in debug mode
set_timeout = true;
}
#endif
if (set_timeout) { // Timeout
RSR(CCOUNT, ccount_start);
}
#ifdef CONFIG_FREERTOS_PORTMUX_DEBUG
uint32_t owner = mux->owner;
if (owner != portMUX_FREE_VAL && owner != CORE_ID_PRO && owner != CORE_ID_APP) {
ets_printf("ERROR: vPortCPUAcquireMutex: mux %p is uninitialized (0x%X)! Called from %s line %d.\n", mux, owner, fnName, line);
mux->owner=portMUX_FREE_VAL;
}
#endif
/* Spin until we own the core */
RSR(PRID, coreID);
/* Note: coreID is the full 32 bit core ID (CORE_ID_PRO/CORE_ID_APP),
not the 0/1 value returned by xPortGetCoreID()
*/
otherCoreID = CORE_ID_XOR_SWAP ^ coreID;
do {
/* mux->owner should be one of portMUX_FREE_VAL, CORE_ID_PRO,
CORE_ID_APP:
- If portMUX_FREE_VAL, we want to atomically set to 'coreID'.
- If "our" coreID, we can drop through immediately.
- If "otherCoreID", we spin here.
*/
res = coreID;
PORTMUX_COMPARE_SET_FN_NAME(&mux->owner, portMUX_FREE_VAL, &res);
if (res != otherCoreID) {
break; // mux->owner is "our" coreID
}
if (set_timeout) {
uint32_t ccount_now;
RSR(CCOUNT, ccount_now);
if (ccount_now - ccount_start > (unsigned)timeout_cycles) {
#ifdef CONFIG_FREERTOS_PORTMUX_DEBUG
ets_printf("Timeout on mux! last non-recursive lock %s line %d, curr %s line %d\n", mux->lastLockedFn, mux->lastLockedLine, fnName, line);
ets_printf("Owner 0x%x count %d\n", mux->owner, mux->count);
#endif
return false;
}
}
} while (1);
assert(res == coreID || res == portMUX_FREE_VAL); /* any other value implies memory corruption or uninitialized mux */
assert((res == portMUX_FREE_VAL) == (mux->count == 0)); /* we're first to lock iff count is zero */
assert(mux->count < 0xFF); /* Bad count value implies memory corruption */
/* now we own it, we can increment the refcount */
mux->count++;
#ifdef CONFIG_FREERTOS_PORTMUX_DEBUG
if (res==portMUX_FREE_VAL) { //initial lock
mux->lastLockedFn=fnName;
mux->lastLockedLine=line;
} else {
ets_printf("Recursive lock: count=%d last non-recursive lock %s line %d, curr %s line %d\n", mux->count-1,
mux->lastLockedFn, mux->lastLockedLine, fnName, line);
}
#endif /* CONFIG_FREERTOS_PORTMUX_DEBUG */
#endif /* CONFIG_FREERTOS_UNICORE */
return true;
}
#ifdef CONFIG_FREERTOS_PORTMUX_DEBUG
static inline void PORTMUX_RELEASE_MUX_FN_NAME(portMUX_TYPE *mux, const char *fnName, int line) {
#else
static inline void PORTMUX_RELEASE_MUX_FN_NAME(portMUX_TYPE *mux) {
#endif
#if !CONFIG_FREERTOS_UNICORE
portBASE_TYPE coreID;
#ifdef CONFIG_FREERTOS_PORTMUX_DEBUG
const char *lastLockedFn=mux->lastLockedFn;
int lastLockedLine=mux->lastLockedLine;
mux->lastLockedFn=fnName;
mux->lastLockedLine=line;
uint32_t owner = mux->owner;
if (owner != portMUX_FREE_VAL && owner != CORE_ID_PRO && owner != CORE_ID_APP) {
ets_printf("ERROR: vPortCPUReleaseMutex: mux %p is invalid (0x%x)!\n", mux, mux->owner);
}
#endif
#if CONFIG_FREERTOS_PORTMUX_DEBUG || !defined(NDEBUG)
RSR(PRID, coreID);
#endif
#ifdef CONFIG_FREERTOS_PORTMUX_DEBUG
if (coreID != mux->owner) {
ets_printf("ERROR: vPortCPUReleaseMutex: mux %p was already unlocked!\n", mux);
ets_printf("Last non-recursive unlock %s line %d, curr unlock %s line %d\n", lastLockedFn, lastLockedLine, fnName, line);
}
#endif
assert(coreID == mux->owner); // This is a mutex we didn't lock, or it's corrupt
mux->count--;
if(mux->count == 0) {
mux->owner = portMUX_FREE_VAL;
} else {
assert(mux->count < 0x100); // Indicates memory corruption
#ifdef CONFIG_FREERTOS_PORTMUX_DEBUG_RECURSIVE
ets_printf("Recursive unlock: count=%d last locked %s line %d, curr %s line %d\n", mux->count, lastLockedFn, lastLockedLine, fnName, line);
#endif
}
#endif //!CONFIG_FREERTOS_UNICORE
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,55 @@
/*******************************************************************************
// Copyright (c) 2003-2015 Cadence Design Systems, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
XTENSA INITIALIZATION ROUTINES CODED IN C
This file contains miscellaneous Xtensa RTOS-generic initialization functions
that are implemented in C.
*******************************************************************************/
#ifdef XT_BOARD
#include <xtensa/xtbsp.h>
#endif
#include "xtensa_rtos.h"
#include "esp_clk.h"
#ifdef XT_RTOS_TIMER_INT
unsigned _xt_tick_divisor = 0; /* cached number of cycles per tick */
void _xt_tick_divisor_init(void)
{
_xt_tick_divisor = esp_clk_cpu_freq() / XT_TICK_PER_SEC;
}
/* Deprecated, to be removed */
int xt_clock_freq(void)
{
return esp_clk_cpu_freq();
}
#endif /* XT_RTOS_TIMER_INT */
@@ -0,0 +1,158 @@
/*******************************************************************************
Copyright (c) 2006-2015 Cadence Design Systems Inc.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
******************************************************************************/
/******************************************************************************
Xtensa-specific interrupt and exception functions for RTOS ports.
Also see xtensa_intr_asm.S.
******************************************************************************/
#include <stdlib.h>
#include <xtensa/config/core.h>
#include "freertos/FreeRTOS.h"
#include "freertos/xtensa_api.h"
#include "freertos/portable.h"
#include "rom/ets_sys.h"
#if XCHAL_HAVE_EXCEPTIONS
/* Handler table is in xtensa_intr_asm.S */
extern xt_exc_handler _xt_exception_table[XCHAL_EXCCAUSE_NUM*portNUM_PROCESSORS];
/*
Default handler for unhandled exceptions.
CHANGED: We do this in panic.c now
*/
//void xt_unhandled_exception(XtExcFrame *frame)
//{
//exit(-1);
//}
extern void xt_unhandled_exception(XtExcFrame *frame);
/*
This function registers a handler for the specified exception.
The function returns the address of the previous handler.
On error, it returns 0.
*/
xt_exc_handler xt_set_exception_handler(int n, xt_exc_handler f)
{
xt_exc_handler old;
if( n < 0 || n >= XCHAL_EXCCAUSE_NUM )
return 0; /* invalid exception number */
/* Convert exception number to _xt_exception_table name */
n = n * portNUM_PROCESSORS + xPortGetCoreID();
old = _xt_exception_table[n];
if (f) {
_xt_exception_table[n] = f;
}
else {
_xt_exception_table[n] = &xt_unhandled_exception;
}
return ((old == &xt_unhandled_exception) ? 0 : old);
}
#endif
#if XCHAL_HAVE_INTERRUPTS
/* Handler table is in xtensa_intr_asm.S */
typedef struct xt_handler_table_entry {
void * handler;
void * arg;
} xt_handler_table_entry;
extern xt_handler_table_entry _xt_interrupt_table[XCHAL_NUM_INTERRUPTS*portNUM_PROCESSORS];
/*
Default handler for unhandled interrupts.
*/
void xt_unhandled_interrupt(void * arg)
{
ets_printf("Unhandled interrupt %d on cpu %d!\n", (int)arg, xPortGetCoreID());
}
/*
This function registers a handler for the specified interrupt. The "arg"
parameter specifies the argument to be passed to the handler when it is
invoked. The function returns the address of the previous handler.
On error, it returns 0.
*/
xt_handler xt_set_interrupt_handler(int n, xt_handler f, void * arg)
{
xt_handler_table_entry * entry;
xt_handler old;
if( n < 0 || n >= XCHAL_NUM_INTERRUPTS )
return 0; /* invalid interrupt number */
if( Xthal_intlevel[n] > XCHAL_EXCM_LEVEL )
return 0; /* priority level too high to safely handle in C */
/* Convert exception number to _xt_exception_table name */
n = n * portNUM_PROCESSORS + xPortGetCoreID();
entry = _xt_interrupt_table + n;
old = entry->handler;
if (f) {
entry->handler = f;
entry->arg = arg;
}
else {
entry->handler = &xt_unhandled_interrupt;
entry->arg = (void*)n;
}
return ((old == &xt_unhandled_interrupt) ? 0 : old);
}
#if CONFIG_SYSVIEW_ENABLE
void * xt_get_interrupt_handler_arg(int n)
{
xt_handler_table_entry * entry;
if( n < 0 || n >= XCHAL_NUM_INTERRUPTS )
return 0; /* invalid interrupt number */
/* Convert exception number to _xt_exception_table name */
n = n * portNUM_PROCESSORS + xPortGetCoreID();
entry = _xt_interrupt_table + n;
return entry->arg;
}
#endif
#endif /* XCHAL_HAVE_INTERRUPTS */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,67 @@
// xtensa_overlay_os_hook.c -- Overlay manager OS hooks for FreeRTOS.
// Copyright (c) 2015-2015 Cadence Design Systems Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "FreeRTOS.h"
#include "semphr.h"
#if configUSE_MUTEX
/* Mutex object that controls access to the overlay. Currently only one
* overlay region is supported so one mutex suffices.
*/
static SemaphoreHandle_t xt_overlay_mutex;
/* This function should be overridden to provide OS specific init such
* as the creation of a mutex lock that can be used for overlay locking.
* Typically this mutex would be set up with priority inheritance. See
* overlay manager documentation for more details.
*/
void xt_overlay_init_os(void)
{
/* Create the mutex for overlay access. Priority inheritance is
* required.
*/
xt_overlay_mutex = xSemaphoreCreateMutex();
}
/* This function locks access to shared overlay resources, typically
* by acquiring a mutex.
*/
void xt_overlay_lock(void)
{
xSemaphoreTake(xt_overlay_mutex, 0);
}
/* This function releases access to shared overlay resources, typically
* by unlocking a mutex.
*/
void xt_overlay_unlock(void)
{
xSemaphoreGive(xt_overlay_mutex);
}
#endif
@@ -0,0 +1,164 @@
// Copyright 2015-2017 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "xtensa_rtos.h"
#include "esp_panic.h"
#include "sdkconfig.h"
#include "soc/soc.h"
/*
This file contains the default handlers for the high interrupt levels as well as some specialized exceptions.
The default behaviour is to just exit the interrupt or call the panic handler on the exceptions
*/
#if XCHAL_HAVE_DEBUG
.global xt_debugexception
.weak xt_debugexception
.set xt_debugexception, _xt_debugexception
.section .iram1,"ax"
.type _xt_debugexception,@function
.align 4
_xt_debugexception:
movi a0,PANIC_RSN_DEBUGEXCEPTION
wsr a0,EXCCAUSE
/* _xt_panic assumes a level 1 exception. As we're
crashing anyhow, copy EPC & EXCSAVE from DEBUGLEVEL
to level 1. */
rsr a0,(EPC + XCHAL_DEBUGLEVEL)
wsr a0,EPC_1
rsr a0,(EXCSAVE + XCHAL_DEBUGLEVEL)
wsr a0,EXCSAVE_1
call0 _xt_panic /* does not return */
rfi XCHAL_DEBUGLEVEL
#endif /* Debug exception */
#if XCHAL_NUM_INTLEVELS >=2 && XCHAL_EXCM_LEVEL <2 && XCHAL_DEBUGLEVEL !=2
.global xt_highint2
.weak xt_highint2
.set xt_highint2, _xt_highint2
.section .iram1,"ax"
.type _xt_highint2,@function
.align 4
_xt_highint2:
/* Default handler does nothing; just returns */
.align 4
.L_xt_highint2_exit:
rsr a0, EXCSAVE_2 /* restore a0 */
rfi 2
#endif /* Level 2 */
#if XCHAL_NUM_INTLEVELS >=3 && XCHAL_EXCM_LEVEL <3 && XCHAL_DEBUGLEVEL !=3
.global xt_highint3
.weak xt_highint3
.set xt_highint3, _xt_highint3
.section .iram1,"ax"
.type _xt_highint3,@function
.align 4
_xt_highint3:
/* Default handler does nothing; just returns */
.align 4
.L_xt_highint3_exit:
rsr a0, EXCSAVE_3 /* restore a0 */
rfi 3
#endif /* Level 3 */
#if XCHAL_NUM_INTLEVELS >=4 && XCHAL_EXCM_LEVEL <4 && XCHAL_DEBUGLEVEL !=4
.global xt_highint4
.weak xt_highint4
.set xt_highint4, _xt_highint4
.section .iram1,"ax"
.type _xt_highint4,@function
.align 4
_xt_highint4:
/* Default handler does nothing; just returns */
.align 4
.L_xt_highint4_exit:
rsr a0, EXCSAVE_4 /* restore a0 */
rfi 4
#endif /* Level 4 */
#if XCHAL_NUM_INTLEVELS >=5 && XCHAL_EXCM_LEVEL <5 && XCHAL_DEBUGLEVEL !=5
.global xt_highint5
.weak xt_highint5
.set xt_highint5, _xt_highint5
.section .iram1,"ax"
.type _xt_highint5,@function
.align 4
_xt_highint5:
/* Default handler does nothing; just returns */
.align 4
.L_xt_highint5_exit:
rsr a0, EXCSAVE_5 /* restore a0 */
rfi 5
#endif /* Level 5 */
#if XCHAL_NUM_INTLEVELS >=6 && XCHAL_EXCM_LEVEL <6 && XCHAL_DEBUGLEVEL !=6
.global _xt_highint6
.global xt_highint6
.weak xt_highint6
.set xt_highint6, _xt_highint6
.section .iram1,"ax"
.type _xt_highint6,@function
.align 4
_xt_highint6:
/* Default handler does nothing; just returns */
.align 4
.L_xt_highint6_exit:
rsr a0, EXCSAVE_6 /* restore a0 */
rfi 6
#endif /* Level 6 */
#if XCHAL_HAVE_NMI
.global _xt_nmi
.global xt_nmi
.weak xt_nmi
.set xt_nmi, _xt_nmi
.section .iram1,"ax"
.type _xt_nmi,@function
.align 4
_xt_nmi:
/* Default handler does nothing; just returns */
.align 4
.L_xt_nmi_exit:
rsr a0, EXCSAVE + XCHAL_NMILEVEL /* restore a0 */
rfi XCHAL_NMILEVEL
#endif /* NMI */
File diff suppressed because it is too large Load Diff