mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-04-19 21:11:57 -04:00
parent
4383c8fae3
commit
adbfca5420
|
@ -305,12 +305,32 @@
|
|||
uint32_t compare,
|
||||
uint32_t * set )
|
||||
{
|
||||
#if ( XCHAL_HAVE_S32C1I > 0 )
|
||||
__asm__ __volatile__ (
|
||||
"WSR %2,SCOMPARE1 \n"
|
||||
"S32C1I %0, %1, 0 \n"
|
||||
: "=r" ( *set )
|
||||
: "r" ( addr ), "r" ( compare ), "0" ( *set )
|
||||
);
|
||||
#else
|
||||
/* No S32C1I, so do this by disabling and re-enabling interrupts (slower) */
|
||||
uint32_t intlevel, old_value;
|
||||
__asm__ __volatile__ ( "rsil %0, " XTSTR( XCHAL_EXCM_LEVEL ) "\n"
|
||||
: "=r" ( intlevel ) );
|
||||
|
||||
old_value = *addr;
|
||||
|
||||
if( old_value == compare )
|
||||
{
|
||||
*addr = *set;
|
||||
}
|
||||
|
||||
__asm__ __volatile__ ( "memw \n"
|
||||
"wsr %0, ps\n"
|
||||
: : "r" ( intlevel ) );
|
||||
|
||||
*set = old_value;
|
||||
#endif /* if ( XCHAL_HAVE_S32C1I > 0 ) */
|
||||
}
|
||||
|
||||
void uxPortCompareSetExtram( volatile uint32_t * addr,
|
||||
|
@ -407,13 +427,6 @@
|
|||
#define xPortGetFreeHeapSize esp_get_free_heap_size
|
||||
#define xPortGetMinimumEverFreeHeapSize esp_get_minimum_free_heap_size
|
||||
|
||||
/*
|
||||
* Send an interrupt to another core in order to make the task running
|
||||
* on it yield for a higher-priority task.
|
||||
*/
|
||||
|
||||
void vPortYieldOtherCore( BaseType_t coreid ) PRIVILEGED_FUNCTION;
|
||||
|
||||
|
||||
/*
|
||||
* Callback to set a watchpoint on the end of the stack. Called every context switch to change the stack
|
||||
|
|
41
portable/ThirdParty/GCC/Xtensa_ESP32/port.c
vendored
41
portable/ThirdParty/GCC/Xtensa_ESP32/port.c
vendored
|
@ -96,17 +96,23 @@
|
|||
|
||||
#include "xtensa_rtos.h"
|
||||
|
||||
#include "rom/ets_sys.h"
|
||||
#if CONFIG_IDF_TARGET_ESP32S2
|
||||
#include "esp32s2/rom/ets_sys.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32
|
||||
#include "esp32/rom/ets_sys.h"
|
||||
#endif
|
||||
#include "soc/cpu.h"
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
#include "esp_panic.h"
|
||||
#include "esp_private/panic_reason.h"
|
||||
#include "esp_debug_helpers.h"
|
||||
#include "esp_heap_caps.h"
|
||||
#include "esp_crosscore_int.h"
|
||||
#include "esp_private/crosscore_int.h"
|
||||
|
||||
#include "esp_intr_alloc.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
/* Defined in portasm.h */
|
||||
extern void _frxt_tick_timer_init( void );
|
||||
|
@ -132,6 +138,19 @@ unsigned port_interruptNesting[ portNUM_PROCESSORS ] = { 0 }; /* Interrupt nest
|
|||
/* User exception dispatcher when exiting */
|
||||
void _xt_user_exit( void );
|
||||
|
||||
#if CONFIG_FREERTOS_TASK_FUNCTION_WRAPPER
|
||||
/* Wrapper to allow task functions to return (increases stack overhead by 16 bytes) */
|
||||
static void vPortTaskWrapper( TaskFunction_t pxCode,
|
||||
void * pvParameters )
|
||||
{
|
||||
pxCode( pvParameters );
|
||||
/*FreeRTOS tasks should not return. Log the task name and abort. */
|
||||
char * pcTaskName = pcTaskGetTaskName( NULL );
|
||||
ESP_LOGE( "FreeRTOS", "FreeRTOS Task \"%s\" should not return, Aborting now!", pcTaskName );
|
||||
abort();
|
||||
}
|
||||
#endif /* if CONFIG_FREERTOS_TASK_FUNCTION_WRAPPER */
|
||||
|
||||
/*
|
||||
* Stack initialization
|
||||
*/
|
||||
|
@ -165,7 +184,11 @@ void _xt_user_exit( void );
|
|||
frame = ( XtExcFrame * ) sp;
|
||||
|
||||
/* Explicitly initialize certain saved registers */
|
||||
#if CONFIG_FREERTOS_TASK_FUNCTION_WRAPPER
|
||||
frame->pc = ( UBaseType_t ) vPortTaskWrapper; /* task wrapper */
|
||||
#else
|
||||
frame->pc = ( UBaseType_t ) pxCode; /* task entrypoint */
|
||||
#endif
|
||||
frame->a0 = 0; /* to terminate GDB backtrace */
|
||||
frame->a1 = ( UBaseType_t ) sp + XT_STK_FRMSZ; /* physical top of stack frame */
|
||||
frame->exit = ( UBaseType_t ) _xt_user_exit; /* user exception exit dispatcher */
|
||||
|
@ -173,13 +196,23 @@ void _xt_user_exit( void );
|
|||
/* Set initial PS to int level 0, EXCM disabled ('rfe' will enable), user mode. */
|
||||
/* Also set entry point argument parameter. */
|
||||
#ifdef __XTENSA_CALL0_ABI__
|
||||
#if CONFIG_FREERTOS_TASK_FUNCTION_WRAPPER
|
||||
frame->a2 = ( UBaseType_t ) pxCode;
|
||||
frame->a3 = ( UBaseType_t ) pvParameters;
|
||||
#else
|
||||
frame->a2 = ( UBaseType_t ) pvParameters;
|
||||
#endif
|
||||
frame->ps = PS_UM | PS_EXCM;
|
||||
#else
|
||||
/* + for windowed ABI also set WOE and CALLINC (pretend task was 'call4'd). */
|
||||
#if CONFIG_FREERTOS_TASK_FUNCTION_WRAPPER
|
||||
frame->a6 = ( UBaseType_t ) pxCode;
|
||||
frame->a7 = ( UBaseType_t ) pvParameters;
|
||||
#else
|
||||
frame->a6 = ( UBaseType_t ) pvParameters;
|
||||
frame->ps = PS_UM | PS_EXCM | PS_WOE | PS_CALLINC( 1 );
|
||||
#endif
|
||||
frame->ps = PS_UM | PS_EXCM | PS_WOE | PS_CALLINC( 1 );
|
||||
#endif /* ifdef __XTENSA_CALL0_ABI__ */
|
||||
|
||||
#ifdef XT_USE_SWPRI
|
||||
/* Set the initial virtual priority mask value to all 1's. */
|
||||
|
|
26
portable/ThirdParty/GCC/Xtensa_ESP32/portasm.S
vendored
26
portable/ThirdParty/GCC/Xtensa_ESP32/portasm.S
vendored
|
@ -138,8 +138,24 @@ _frxt_int_enter:
|
|||
mull a2, a4, a2
|
||||
add a1, a1, a2 /* for current proc */
|
||||
|
||||
#ifdef CONFIG_FREERTOS_FPU_IN_ISR
|
||||
#if XCHAL_CP_NUM > 0
|
||||
rsr a3, CPENABLE /* Restore thread scope CPENABLE */
|
||||
addi sp, sp,-4 /* ISR will manage FPU coprocessor by forcing */
|
||||
s32i a3, a1, 0 /* its trigger */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
.Lnested:
|
||||
1:
|
||||
#ifdef CONFIG_FREERTOS_FPU_IN_ISR
|
||||
#if XCHAL_CP_NUM > 0
|
||||
movi a3, 0 /* whilst ISRs pending keep CPENABLE exception active */
|
||||
wsr a3, CPENABLE
|
||||
rsync
|
||||
#endif
|
||||
#endif
|
||||
|
||||
mov a0, a12 /* restore return addr and return */
|
||||
ret
|
||||
|
||||
|
@ -176,6 +192,15 @@ _frxt_int_exit:
|
|||
s32i a2, a3, 0 /* save nesting count */
|
||||
bnez a2, .Lnesting /* !=0 after decr so still nested */
|
||||
|
||||
#ifdef CONFIG_FREERTOS_FPU_IN_ISR
|
||||
#if XCHAL_CP_NUM > 0
|
||||
l32i a3, sp, 0 /* Grab last CPENABLE before leave ISR */
|
||||
addi sp, sp, 4
|
||||
wsr a3, CPENABLE
|
||||
rsync /* ensure CPENABLE was modified */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
movi a2, pxCurrentTCB
|
||||
addx4 a2, a4, a2
|
||||
l32i a2, a2, 0 /* a2 = current TCB */
|
||||
|
@ -642,7 +667,6 @@ _frxt_task_coproc_state:
|
|||
addx4 a15, a3, a15
|
||||
l32i a15, a15, 0 /* && pxCurrentTCB != 0) { */
|
||||
|
||||
|
||||
beqz a15, 2f
|
||||
l32i a15, a15, CP_TOPOFSTACK_OFFS
|
||||
ret
|
||||
|
|
|
@ -34,7 +34,11 @@
|
|||
#endif
|
||||
|
||||
#include "xtensa_rtos.h"
|
||||
#include "esp_clk.h"
|
||||
#if CONFIG_IDF_TARGET_ESP32S2
|
||||
#include "esp32s2/clk.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32
|
||||
#include "esp32/clk.h"
|
||||
#endif
|
||||
|
||||
#ifdef XT_RTOS_TIMER_INT
|
||||
|
||||
|
|
|
@ -34,7 +34,11 @@
|
|||
#include "freertos/xtensa_api.h"
|
||||
#include "freertos/portable.h"
|
||||
|
||||
#include "rom/ets_sys.h"
|
||||
#if CONFIG_IDF_TARGET_ESP32S2
|
||||
#include "esp32s2/rom/ets_sys.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32
|
||||
#include "esp32/rom/ets_sys.h"
|
||||
#endif
|
||||
|
||||
#if XCHAL_HAVE_EXCEPTIONS
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
// limitations under the License.
|
||||
|
||||
#include "xtensa_rtos.h"
|
||||
#include "esp_panic.h"
|
||||
#include "esp_private/panic_reason.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "soc/soc.h"
|
||||
|
||||
|
|
|
@ -91,10 +91,9 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
*******************************************************************************/
|
||||
|
||||
#include "xtensa_rtos.h"
|
||||
#include "esp_panic.h"
|
||||
#include "esp_private/panic_reason.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "soc/soc.h"
|
||||
#include "soc/dport_reg.h"
|
||||
|
||||
/*
|
||||
Define for workaround: pin no-cpu-affinity tasks to a cpu when fpu is used.
|
||||
|
@ -103,7 +102,25 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
#define TASKTCB_XCOREID_OFFSET (0x38+configMAX_TASK_NAME_LEN+3)&~3
|
||||
.extern pxCurrentTCB
|
||||
|
||||
/* Enable stack backtrace across exception/interrupt - see below */
|
||||
/*
|
||||
--------------------------------------------------------------------------------
|
||||
In order for backtracing to be able to trace from the pre-exception stack
|
||||
across to the exception stack (including nested interrupts), we need to create
|
||||
a pseudo base-save area to make it appear like the exception dispatcher was
|
||||
triggered by a CALL4 from the pre-exception code. In reality, the exception
|
||||
dispatcher uses the same window as pre-exception code, and only CALL0s are
|
||||
used within the exception dispatcher.
|
||||
|
||||
To create the pseudo base-save area, we need to store a copy of the pre-exception's
|
||||
base save area (a0 to a4) below the exception dispatcher's SP. EXCSAVE_x will
|
||||
be used to store a copy of the SP that points to the interrupted code's exception
|
||||
frame just in case the exception dispatcher's SP does not point to the exception
|
||||
frame (which is the case when switching from task to interrupt stack).
|
||||
|
||||
Clearing the pseudo base-save area is uncessary as the interrupt dispatcher
|
||||
will restore the current SP to that of the pre-exception SP.
|
||||
--------------------------------------------------------------------------------
|
||||
*/
|
||||
#ifdef CONFIG_FREERTOS_INTERRUPT_BACKTRACE
|
||||
#define XT_DEBUG_BACKTRACE 1
|
||||
#endif
|
||||
|
@ -202,9 +219,22 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
/* This bit of code provides a nice debug backtrace in the debugger.
|
||||
It does take a few more instructions, so undef XT_DEBUG_BACKTRACE
|
||||
if you want to save the cycles.
|
||||
At this point, the exception frame should have been allocated and filled,
|
||||
and current sp points to the interrupt stack (for non-nested interrupt)
|
||||
or below the allocated exception frame (for nested interrupts). Copy the
|
||||
pre-exception's base save area below the current SP.
|
||||
*/
|
||||
#ifdef XT_DEBUG_BACKTRACE
|
||||
#ifndef __XTENSA_CALL0_ABI__
|
||||
rsr a0, EXCSAVE_1 + \level - 1 /* Get exception frame pointer stored in EXCSAVE_x */
|
||||
l32i a3, a0, XT_STK_A0 /* Copy pre-exception a0 (return address) */
|
||||
s32e a3, a1, -16
|
||||
l32i a3, a0, XT_STK_A1 /* Copy pre-exception a1 (stack pointer) */
|
||||
s32e a3, a1, -12
|
||||
/* Backtracing only needs a0 and a1, no need to create full base save area.
|
||||
Also need to change current frame's return address to point to pre-exception's
|
||||
last run instruction.
|
||||
*/
|
||||
rsr a0, EPC_1 + \level - 1 /* return address */
|
||||
movi a4, 0xC0000000 /* constant with top 2 bits set (call size) */
|
||||
or a0, a0, a4 /* set top 2 bits */
|
||||
|
@ -698,8 +728,16 @@ _xt_user_exc:
|
|||
#endif
|
||||
wsr a0, PS
|
||||
|
||||
/*
|
||||
Create pseudo base save area. At this point, sp is still pointing to the
|
||||
allocated and filled exception stack frame.
|
||||
*/
|
||||
#ifdef XT_DEBUG_BACKTRACE
|
||||
#ifndef __XTENSA_CALL0_ABI__
|
||||
l32i a3, sp, XT_STK_A0 /* Copy pre-exception a0 (return address) */
|
||||
s32e a3, sp, -16
|
||||
l32i a3, sp, XT_STK_A1 /* Copy pre-exception a1 (stack pointer) */
|
||||
s32e a3, sp, -12
|
||||
rsr a0, EPC_1 /* return address for debug backtrace */
|
||||
movi a5, 0xC0000000 /* constant with top 2 bits set (call size) */
|
||||
rsync /* wait for WSR.PS to complete */
|
||||
|
@ -945,7 +983,12 @@ _xt_coproc_exc:
|
|||
|
||||
/* Get co-processor state save area of new owner thread. */
|
||||
call0 XT_RTOS_CP_STATE /* a15 = new owner's save area */
|
||||
beqz a15, .L_goto_invalid /* not in a thread (invalid) */
|
||||
|
||||
#ifndef CONFIG_FREERTOS_FPU_IN_ISR
|
||||
beqz a15, .L_goto_invalid
|
||||
#endif
|
||||
|
||||
/*When FPU in ISR is enabled we could deal with zeroed a15 */
|
||||
|
||||
/* Enable the co-processor's bit in CPENABLE. */
|
||||
movi a0, _xt_coproc_mask
|
||||
|
@ -987,7 +1030,13 @@ locking.
|
|||
rsync /* ensure wsr.CPENABLE is complete */
|
||||
|
||||
/* Only need to context switch if new owner != old owner. */
|
||||
/* If float is necessary on ISR, we need to remove this check */
|
||||
/* below, because on restoring from ISR we may have new == old condition used
|
||||
* to force cp restore to next thread
|
||||
*/
|
||||
#ifndef CONFIG_FREERTOS_FPU_IN_ISR
|
||||
beq a15, a2, .L_goto_done /* new owner == old, we're done */
|
||||
#endif
|
||||
|
||||
/* If no old owner then nothing to save. */
|
||||
beqz a2, .L_check_new
|
||||
|
@ -1029,6 +1078,7 @@ locking.
|
|||
.L_check_new:
|
||||
/* Check if any state has to be restored for new owner. */
|
||||
/* NOTE: a15 = new owner's save area, cannot be zero when we get here. */
|
||||
beqz a15, .L_xt_coproc_done
|
||||
|
||||
l16ui a3, a15, XT_CPSTORED /* a3 = new owner's CPSTORED */
|
||||
movi a4, _xt_coproc_sa_offset
|
||||
|
@ -1114,6 +1164,16 @@ _xt_lowint1:
|
|||
movi a0, _xt_user_exit /* save exit point for dispatch */
|
||||
s32i a0, sp, XT_STK_EXIT
|
||||
|
||||
/* EXCSAVE_1 should now be free to use. Use it to keep a copy of the
|
||||
current stack pointer that points to the exception frame (XT_STK_FRAME).*/
|
||||
#ifdef XT_DEBUG_BACKTRACE
|
||||
#ifndef __XTENSA_CALL0_ABI__
|
||||
mov a0, sp
|
||||
wsr a0, EXCSAVE_1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/* Save rest of interrupt context and enter RTOS. */
|
||||
call0 XT_RTOS_INT_ENTER /* common RTOS interrupt entry */
|
||||
|
||||
|
@ -1194,6 +1254,16 @@ _xt_medint2:
|
|||
movi a0, _xt_medint2_exit /* save exit point for dispatch */
|
||||
s32i a0, sp, XT_STK_EXIT
|
||||
|
||||
/* EXCSAVE_2 should now be free to use. Use it to keep a copy of the
|
||||
current stack pointer that points to the exception frame (XT_STK_FRAME).*/
|
||||
#ifdef XT_DEBUG_BACKTRACE
|
||||
#ifndef __XTENSA_CALL0_ABI__
|
||||
mov a0, sp
|
||||
wsr a0, EXCSAVE_2
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/* Save rest of interrupt context and enter RTOS. */
|
||||
call0 XT_RTOS_INT_ENTER /* common RTOS interrupt entry */
|
||||
|
||||
|
@ -1265,6 +1335,16 @@ _xt_medint3:
|
|||
movi a0, _xt_medint3_exit /* save exit point for dispatch */
|
||||
s32i a0, sp, XT_STK_EXIT
|
||||
|
||||
/* EXCSAVE_3 should now be free to use. Use it to keep a copy of the
|
||||
current stack pointer that points to the exception frame (XT_STK_FRAME).*/
|
||||
#ifdef XT_DEBUG_BACKTRACE
|
||||
#ifndef __XTENSA_CALL0_ABI__
|
||||
mov a0, sp
|
||||
wsr a0, EXCSAVE_3
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/* Save rest of interrupt context and enter RTOS. */
|
||||
call0 XT_RTOS_INT_ENTER /* common RTOS interrupt entry */
|
||||
|
||||
|
@ -1335,6 +1415,16 @@ _xt_medint4:
|
|||
movi a0, _xt_medint4_exit /* save exit point for dispatch */
|
||||
s32i a0, sp, XT_STK_EXIT
|
||||
|
||||
/* EXCSAVE_4 should now be free to use. Use it to keep a copy of the
|
||||
current stack pointer that points to the exception frame (XT_STK_FRAME).*/
|
||||
#ifdef XT_DEBUG_BACKTRACE
|
||||
#ifndef __XTENSA_CALL0_ABI__
|
||||
mov a0, sp
|
||||
wsr a0, EXCSAVE_4
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/* Save rest of interrupt context and enter RTOS. */
|
||||
call0 XT_RTOS_INT_ENTER /* common RTOS interrupt entry */
|
||||
|
||||
|
@ -1405,6 +1495,15 @@ _xt_medint5:
|
|||
movi a0, _xt_medint5_exit /* save exit point for dispatch */
|
||||
s32i a0, sp, XT_STK_EXIT
|
||||
|
||||
/* EXCSAVE_5 should now be free to use. Use it to keep a copy of the
|
||||
current stack pointer that points to the exception frame (XT_STK_FRAME).*/
|
||||
#ifdef XT_DEBUG_BACKTRACE
|
||||
#ifndef __XTENSA_CALL0_ABI__
|
||||
mov a0, sp
|
||||
wsr a0, EXCSAVE_5
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Save rest of interrupt context and enter RTOS. */
|
||||
call0 XT_RTOS_INT_ENTER /* common RTOS interrupt entry */
|
||||
|
||||
|
@ -1475,6 +1574,15 @@ _xt_medint6:
|
|||
movi a0, _xt_medint6_exit /* save exit point for dispatch */
|
||||
s32i a0, sp, XT_STK_EXIT
|
||||
|
||||
/* EXCSAVE_6 should now be free to use. Use it to keep a copy of the
|
||||
current stack pointer that points to the exception frame (XT_STK_FRAME).*/
|
||||
#ifdef XT_DEBUG_BACKTRACE
|
||||
#ifndef __XTENSA_CALL0_ABI__
|
||||
mov a0, sp
|
||||
wsr a0, EXCSAVE_6
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Save rest of interrupt context and enter RTOS. */
|
||||
call0 XT_RTOS_INT_ENTER /* common RTOS interrupt entry */
|
||||
|
||||
|
|
Loading…
Reference in a new issue