diff --git a/components/esp_common/include/esp_expression_with_stack.h b/components/esp_common/include/esp_expression_with_stack.h index f97137042..afaf43d0f 100644 --- a/components/esp_common/include/esp_expression_with_stack.h +++ b/components/esp_common/include/esp_expression_with_stack.h @@ -31,30 +31,33 @@ ({ \ if(lock && stack && stack_size) { \ uint32_t backup; \ - int watchpoint_place=(int)stack; \ - portSTACK_TYPE *top_of_stack = &stack[0] + \ - (sizeof(stack_size * sizeof(portSTACK_TYPE)) / \ - sizeof(portSTACK_TYPE)); \ - watchpoint_place=(watchpoint_place+31)&(~31); \ xSemaphoreTake(lock, portMAX_DELAY); \ - esp_set_watchpoint(2, (char*)watchpoint_place, 32, ESP_WATCHPOINT_STORE);\ + StackType_t *top_of_stack = esp_switch_stack_setup(stack, stack_size);\ esp_switch_stack_enter(top_of_stack, &backup); \ { \ expression; \ } \ - esp_clear_watchpoint(2); \ esp_switch_stack_exit(&backup); \ xSemaphoreGive(lock); \ } \ }) +/** + * @brief Fill stack frame with CPU-specifics value before use + * @param stack Caller allocated stack pointer + * @param stack_size Size of stack in bytes + * @return New pointer to the top of stack + * @note Application must not call this function directly + */ +StackType_t * esp_switch_stack_setup(StackType_t *stack, size_t stack_size); + /** * @brief Changes CPU sp-register to use another stack space and save the previous one * @param stack Caller allocated stack pointer * @param backup_stack Pointer to a place to save the current stack * @note Application must not call this function directly */ -extern void esp_switch_stack_enter(portSTACK_TYPE *stack, uint32_t *backup_stack); +extern void esp_switch_stack_enter(StackType_t *stack, uint32_t *backup_stack); /** * @brief Restores the previous CPU sp-register diff --git a/components/xtensa/CMakeLists.txt b/components/xtensa/CMakeLists.txt index 6b4d2429c..a360fb2ed 100644 --- a/components/xtensa/CMakeLists.txt +++ b/components/xtensa/CMakeLists.txt @@ -5,7 +5,8 @@ else() set(priv_requires soc freertos) set(srcs "debug_helpers.c" "debug_helpers_asm.S" - "expression_with_stack_xtensa.S" + "expression_with_stack_xtensa_asm.S" + "expression_with_stack_xtensa.c" "eri.c" ) diff --git a/components/xtensa/expression_with_stack_xtensa.c b/components/xtensa/expression_with_stack_xtensa.c new file mode 100644 index 000000000..c24470971 --- /dev/null +++ b/components/xtensa/expression_with_stack_xtensa.c @@ -0,0 +1,24 @@ +#include +#include +#include + +StackType_t * esp_switch_stack_setup(StackType_t *stack, size_t stack_size) +{ + int watchpoint_place = (((int)stack + 31) & ~31); + StackType_t *top_of_stack = (StackType_t *)&stack[0] + + (sizeof(stack_size * sizeof(StackType_t)) / + sizeof(StackType_t)); + + //Align stack to a 16byte boundary, as required by CPU specific: + top_of_stack = (StackType_t *)(((UBaseType_t)(top_of_stack - 1) - + ALIGNUP(0x10, sizeof(XtSolFrame) )) & + ~0xf); + + //Fake stack frame to do not break the backtrace + XtSolFrame *frame = (XtSolFrame *)top_of_stack; + frame->a0 = 0; + frame->a1 = (UBaseType_t)top_of_stack; + + esp_set_watchpoint(2, (char*)watchpoint_place, 32, ESP_WATCHPOINT_STORE); + return top_of_stack; +} \ No newline at end of file diff --git a/components/xtensa/expression_with_stack_xtensa.S b/components/xtensa/expression_with_stack_xtensa_asm.S similarity index 90% rename from components/xtensa/expression_with_stack_xtensa.S rename to components/xtensa/expression_with_stack_xtensa_asm.S index fdac7fada..01d5034da 100644 --- a/components/xtensa/expression_with_stack_xtensa.S +++ b/components/xtensa/expression_with_stack_xtensa_asm.S @@ -12,7 +12,11 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include + + .extern esp_clear_watchpoint .text + /** * extern void switch_stack_enter(portSTACK_TYPE *stack, portSTACK_TYPE *backup_stack); */ @@ -42,6 +46,8 @@ esp_switch_stack_exit: #ifndef __XTENSA_CALL0_ABI__ entry sp, 0x10 + movi a6, 2 + call4 esp_clear_watchpoint /* clear the watchpoint before releasing stack */ l32i a4, a2, 0 /* recover the original task stack */ mov a1, a4 /* put it on sp register again */ retw