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
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
prompt "UART for console output"
default ESP_CONSOLE_UART_DEFAULT

View File

@ -11,14 +11,16 @@
// 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.
#ifndef __ESP_EXPRESSION_WITH_STACK_H
#define __ESP_EXPRESSION_WITH_STACK_H
#pragma once
#include "freertos/FreeRTOS.h"
#include "freertos/semphr.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
@ -26,20 +28,21 @@
* @param stack Pointer to user alocated stack
* @param stack_size Size of current stack in bytes
* @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) \
({ \
if (lock && stack && stack_size) { \
uint32_t backup; \
xSemaphoreTake(lock, portMAX_DELAY); \
StackType_t *top_of_stack = esp_switch_stack_setup(stack, stack_size);\
esp_switch_stack_enter(top_of_stack, &backup); \
{ \
expression; \
} \
esp_switch_stack_exit(&backup); \
xSemaphoreGive(lock); \
} \
#define ESP_EXECUTE_EXPRESSION_WITH_STACK(lock, stack, stack_size, expression) \
({ \
assert(lock && stack && (stack_size >= CONFIG_ESP_MINIMAL_SHARED_STACK_SIZE)); \
uint32_t backup; \
xSemaphoreTake(lock, portMAX_DELAY); \
StackType_t *top_of_stack = esp_switch_stack_setup(stack, stack_size); \
esp_switch_stack_enter(top_of_stack, &backup); \
{ \
expression; \
} \
esp_switch_stack_exit(&backup); \
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);
#ifdef __cplusplus
}
#endif

View File

@ -1,4 +1,5 @@
#include <stdio.h>
#include <string.h>
#include "unity.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
@ -29,3 +30,4 @@ TEST_CASE("test printf using shared buffer stack", "[newlib]")
vSemaphoreDelete(printf_lock);
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 <freertos/xtensa_rtos.h>
#include <freertos/xtensa_context.h>
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);
#endif
StackType_t *top_of_stack = (StackType_t *)&stack[0] +
((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->a1 = (UBaseType_t)top_of_stack;
#if CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK
esp_set_watchpoint(2, (char*)watchpoint_place, 32, ESP_WATCHPOINT_STORE);
#endif
return top_of_stack;
}

View File

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