mirror of
				https://github.com/espressif/esp-idf.git
				synced 2025-10-31 04:59:55 +00:00 
			
		
		
		
	 83c686c744
			
		
	
	83c686c744
	
	
	
		
			
			- vTaskPreemptionDisable()/vTaskPreemptionEnable() are no longer available in single-core builds. - xTaskIncrementTick() calls must now be wrapped by critical section - Minimal Idle Task renamed to Passive Idle Task - Port critical section APIs updated
		
			
				
	
	
		
			154 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
			
		
		
	
	
			154 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
| /*
 | |
|  * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
 | |
|  *
 | |
|  * SPDX-License-Identifier: Apache-2.0
 | |
|  */
 | |
| #include "sdkconfig.h"
 | |
| #include "portmacro.h"
 | |
| #if CONFIG_ESP_SYSTEM_HW_STACK_GUARD
 | |
| #include "esp_private/hw_stack_guard.h"
 | |
| #endif
 | |
| 
 | |
| #if CONFIG_FREERTOS_UNICORE
 | |
| #define pxCurrentTCBs   pxCurrentTCB
 | |
| #endif
 | |
| 
 | |
|     .global uxInterruptNesting
 | |
|     .global uxSchedulerRunning
 | |
|     .global xIsrStackTop
 | |
|     .global pxCurrentTCBs
 | |
|     .global vTaskSwitchContext
 | |
|     .global xPortSwitchFlag
 | |
| #if CONFIG_ESP_SYSTEM_HW_STACK_GUARD
 | |
|     .global xIsrStack
 | |
|     .global port_offset_pxStack
 | |
|     .global port_offset_pxEndOfStack
 | |
|     .global esp_hw_stack_guard_monitor_stop
 | |
|     .global esp_hw_stack_guard_monitor_start
 | |
|     .global esp_hw_stack_guard_set_bounds
 | |
| #endif /* CONFIG_ESP_SYSTEM_HW_STACK_GUARD */
 | |
| 
 | |
|     .section .text
 | |
| 
 | |
| /**
 | |
|  * This function makes the RTOS aware about a ISR entering, it takes the
 | |
|  * current task stack saved, places into the TCB, loads the ISR stack.
 | |
|  * TODO: ISR nesting code improvements ?
 | |
|  */
 | |
| 
 | |
|     .global rtos_int_enter
 | |
|     .type rtos_int_enter, @function
 | |
| rtos_int_enter:
 | |
|     /* scheduler not enabled, jump directly to ISR handler */
 | |
|     lw t0, uxSchedulerRunning
 | |
|     beq t0,zero, rtos_enter_end
 | |
| 
 | |
|     /* increments the ISR nesting count */
 | |
| 	la t3, uxInterruptNesting
 | |
| 	lw t4, 0x0(t3)
 | |
| 	addi t5,t4,1
 | |
| 	sw  t5, 0x0(t3)
 | |
| 
 | |
|     /* If reached here from another low-prio ISR, skip stack pushing to TCB */
 | |
| 	bne t4,zero, rtos_enter_end
 | |
| 
 | |
| #if CONFIG_ESP_SYSTEM_HW_STACK_GUARD
 | |
|     /* esp_hw_stack_guard_monitor_stop(); pass the scratch registers */
 | |
|     ESP_HW_STACK_GUARD_MONITOR_STOP_CUR_CORE a0 a1
 | |
| #endif /* CONFIG_ESP_SYSTEM_HW_STACK_GUARD */
 | |
| 
 | |
|     /* Save current TCB and load the ISR stack */
 | |
|     lw  t0, pxCurrentTCBs
 | |
|     sw  sp, 0x0(t0)
 | |
|     lw  sp, xIsrStackTop
 | |
| 
 | |
| #if CONFIG_ESP_SYSTEM_HW_STACK_GUARD
 | |
|     /* esp_hw_stack_guard_set_bounds(xIsrStack, xIsrStackTop); */
 | |
|     la      a0, xIsrStack
 | |
|     mv      a1, sp
 | |
|     ESP_HW_STACK_GUARD_SET_BOUNDS_CUR_CORE a2
 | |
|     /* esp_hw_stack_guard_monitor_start(); */
 | |
|     ESP_HW_STACK_GUARD_MONITOR_START_CUR_CORE a0 a1
 | |
| #endif /* CONFIG_ESP_SYSTEM_HW_STACK_GUARD */
 | |
| 
 | |
| rtos_enter_end:
 | |
|     ret
 | |
| 
 | |
| /**
 | |
|  * @brief Restore the stack pointer of the next task to run.
 | |
|  *
 | |
|  * @param a0 Former mstatus
 | |
|  *
 | |
|  * @returns New mstatus
 | |
|  */
 | |
|     .global rtos_int_exit
 | |
|     .type rtos_int_exit, @function
 | |
| rtos_int_exit:
 | |
|     /* To speed up this routine and because this current routine is only meant to be called from the interrupt
 | |
|      * handler, let's use callee-saved registers instead of stack space. Registers `s3-s11` are not used by
 | |
|      * the caller */
 | |
|     mv s11, a0
 | |
|     /* may skip RTOS aware interrupt since scheduler was not started */
 | |
|     lw t0, uxSchedulerRunning
 | |
|     beq t0,zero, rtos_exit_end
 | |
| 
 | |
|     /* update nesting interrupts counter */
 | |
|     la t2, uxInterruptNesting
 | |
|     lw t3, 0x0(t2)
 | |
| 
 | |
|     /* Already zero, protect against underflow */
 | |
|     beq t3, zero, isr_skip_decrement
 | |
|     addi t3,t3, -1
 | |
|     sw  t3, 0x0(t2)
 | |
| 
 | |
| isr_skip_decrement:
 | |
| 
 | |
|     /* may still have interrupts pending, skip section below and exit */
 | |
|     bne t3,zero,rtos_exit_end
 | |
| 
 | |
|     /* Schedule the next task if a yield is pending */
 | |
|     la t0, xPortSwitchFlag
 | |
|     lw t2, 0x0(t0)
 | |
|     beq t2, zero, no_switch
 | |
| 
 | |
|     /* preserve return address and schedule next task
 | |
|        stack pointer for riscv should always be 16 byte aligned */
 | |
|     addi sp,sp,-16
 | |
|     sw  ra, 0(sp)
 | |
|     /* vTaskSwitchContext(xCoreID) now expects xCoreID as an argument, so the assembly calls below have been modified. xCoreID is hard-wired to 0 for single-core risc-v. */
 | |
|     li a0, 0
 | |
|     call vTaskSwitchContext
 | |
|     lw  ra, 0(sp)
 | |
|     addi sp, sp, 16
 | |
| 
 | |
|     /* Clears the switch pending flag */
 | |
|     la t0, xPortSwitchFlag
 | |
|     mv t2, zero
 | |
|     sw  t2, 0x0(t0)
 | |
| 
 | |
| no_switch:
 | |
| 
 | |
| #if CONFIG_ESP_SYSTEM_HW_STACK_GUARD
 | |
|     /* esp_hw_stack_guard_monitor_stop(); */
 | |
|     ESP_HW_STACK_GUARD_MONITOR_STOP_CUR_CORE a0 a1
 | |
| #endif /* CONFIG_ESP_SYSTEM_HW_STACK_GUARD */
 | |
| 
 | |
|     /* Recover the stack of next task */
 | |
|     lw t0, pxCurrentTCBs
 | |
|     lw sp, 0x0(t0)
 | |
| 
 | |
| #if CONFIG_ESP_SYSTEM_HW_STACK_GUARD
 | |
|     /* esp_hw_stack_guard_set_bounds(pxCurrentTCBs[0]->pxStack,
 | |
|      *                               pxCurrentTCBs[0]->pxEndOfStack);
 | |
|      */
 | |
|     lw      a0, PORT_OFFSET_PX_STACK(t0)
 | |
|     lw      a1, PORT_OFFSET_PX_END_OF_STACK(t0)
 | |
|     ESP_HW_STACK_GUARD_SET_BOUNDS_CUR_CORE a2
 | |
|     /* esp_hw_stack_guard_monitor_start(); */
 | |
|     ESP_HW_STACK_GUARD_MONITOR_START_CUR_CORE a0 a1
 | |
| #endif /* CONFIG_ESP_SYSTEM_HW_STACK_GUARD */
 | |
| 
 | |
| rtos_exit_end:
 | |
|     mv a0, s11                         /* a0 = new mstatus */
 | |
|     ret
 |