Merge branch 'feature/call_with_shared_stack' into 'master'

Call with shared stack improvements

See merge request espressif/esp-idf!7228
This commit is contained in:
Angus Gratton
2020-01-10 11:40:11 +08:00
5 changed files with 53 additions and 16 deletions

View File

@@ -77,6 +77,13 @@ menu "Common ESP-related"
FreeRTOS timer task size, see "FreeRTOS timer task stack size" option FreeRTOS timer task size, see "FreeRTOS timer task stack size" option
in "FreeRTOS" menu. in "FreeRTOS" menu.
config ESP_MINIMAL_SHARED_STACK_SIZE
int "Minimal allowed size for shared stack"
default 2048
help
Minimal value of size, in bytes, accepted to execute a expression
with shared stack.
choice ESP_CONSOLE_UART choice ESP_CONSOLE_UART
prompt "UART for console output" prompt "UART for console output"
default ESP_CONSOLE_UART_DEFAULT default ESP_CONSOLE_UART_DEFAULT

View File

@@ -11,14 +11,16 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#pragma once
#ifndef __ESP_EXPRESSION_WITH_STACK_H
#define __ESP_EXPRESSION_WITH_STACK_H
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
#include "freertos/semphr.h" #include "freertos/semphr.h"
#include "esp_debug_helpers.h" #include "esp_debug_helpers.h"
#include "esp_log.h"
#ifdef __cplusplus
extern "C" {
#endif
/** /**
* @brief Executes a 1-line expression with a application alocated stack * @brief Executes a 1-line expression with a application alocated stack
@@ -26,20 +28,21 @@
* @param stack Pointer to user alocated stack * @param stack Pointer to user alocated stack
* @param stack_size Size of current stack in bytes * @param stack_size Size of current stack in bytes
* @param expression Expression or function to be executed using the stack * @param expression Expression or function to be executed using the stack
* @note if either lock, stack or stack size is invalid, the expression will
* be called using the current stack.
*/ */
#define ESP_EXECUTE_EXPRESSION_WITH_STACK(lock, stack, stack_size, expression) \ #define ESP_EXECUTE_EXPRESSION_WITH_STACK(lock, stack, stack_size, expression) \
({ \ ({ \
if (lock && stack && stack_size) { \ assert(lock && stack && (stack_size >= CONFIG_ESP_MINIMAL_SHARED_STACK_SIZE)); \
uint32_t backup; \ uint32_t backup; \
xSemaphoreTake(lock, portMAX_DELAY); \ xSemaphoreTake(lock, portMAX_DELAY); \
StackType_t *top_of_stack = esp_switch_stack_setup(stack, stack_size);\ StackType_t *top_of_stack = esp_switch_stack_setup(stack, stack_size); \
esp_switch_stack_enter(top_of_stack, &backup); \ esp_switch_stack_enter(top_of_stack, &backup); \
{ \ { \
expression; \ expression; \
} \ } \
esp_switch_stack_exit(&backup); \ esp_switch_stack_exit(&backup); \
xSemaphoreGive(lock); \ xSemaphoreGive(lock); \
} \
}) })
/** /**
@@ -66,4 +69,6 @@ extern void esp_switch_stack_enter(StackType_t *stack, uint32_t *backup_stack);
*/ */
extern void esp_switch_stack_exit(uint32_t *backup_stack); extern void esp_switch_stack_exit(uint32_t *backup_stack);
#ifdef __cplusplus
}
#endif #endif

View File

@@ -1,4 +1,5 @@
#include <stdio.h> #include <stdio.h>
#include <string.h>
#include "unity.h" #include "unity.h"
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
#include "freertos/task.h" #include "freertos/task.h"
@@ -29,3 +30,4 @@ TEST_CASE("test printf using shared buffer stack", "[newlib]")
vSemaphoreDelete(printf_lock); vSemaphoreDelete(printf_lock);
free(shared_stack); free(shared_stack);
} }

View File

@@ -1,10 +1,26 @@
// Copyright 2015-2019 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 <esp_expression_with_stack.h> #include <esp_expression_with_stack.h>
#include <freertos/xtensa_rtos.h> #include <freertos/xtensa_rtos.h>
#include <freertos/xtensa_context.h> #include <freertos/xtensa_context.h>
StackType_t * esp_switch_stack_setup(StackType_t *stack, size_t stack_size) StackType_t * esp_switch_stack_setup(StackType_t *stack, size_t stack_size)
{ {
#if CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK
int watchpoint_place = (((int)stack + 31) & ~31); int watchpoint_place = (((int)stack + 31) & ~31);
#endif
StackType_t *top_of_stack = (StackType_t *)&stack[0] + StackType_t *top_of_stack = (StackType_t *)&stack[0] +
((stack_size * sizeof(StackType_t)) / sizeof(StackType_t)); ((stack_size * sizeof(StackType_t)) / sizeof(StackType_t));
@@ -18,6 +34,9 @@ StackType_t * esp_switch_stack_setup(StackType_t *stack, size_t stack_size)
frame->a0 = 0; frame->a0 = 0;
frame->a1 = (UBaseType_t)top_of_stack; frame->a1 = (UBaseType_t)top_of_stack;
#if CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK
esp_set_watchpoint(2, (char*)watchpoint_place, 32, ESP_WATCHPOINT_STORE); esp_set_watchpoint(2, (char*)watchpoint_place, 32, ESP_WATCHPOINT_STORE);
#endif
return top_of_stack; return top_of_stack;
} }

View File

@@ -46,9 +46,13 @@ esp_switch_stack_exit:
#ifndef __XTENSA_CALL0_ABI__ #ifndef __XTENSA_CALL0_ABI__
entry sp, 0x10 entry sp, 0x10
#if CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK
movi a6, 2 movi a6, 2
movi a4, esp_clear_watchpoint movi a4, esp_clear_watchpoint
callx4 a4 /* clear the watchpoint before releasing stack */ callx4 a4 /* clear the watchpoint before releasing stack */
#endif
l32i a4, a2, 0 /* recover the original task stack */ l32i a4, a2, 0 /* recover the original task stack */
mov a1, a4 /* put it on sp register again */ mov a1, a4 /* put it on sp register again */
retw retw