forked from espressif/esp-idf
Merge branch 'fix/freertos-clang-riscv-port' into 'master'
freertos: riscv: implement vPortTaskWrapper with asm only Closes IDF-6347 See merge request espressif/esp-idf!22199
This commit is contained in:
@@ -469,23 +469,15 @@ FORCE_INLINE_ATTR UBaseType_t uxInitialiseStackTLS(UBaseType_t uxStackPointer, u
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if CONFIG_FREERTOS_TASK_FUNCTION_WRAPPER
|
#if CONFIG_FREERTOS_TASK_FUNCTION_WRAPPER
|
||||||
/**
|
static void vPortTaskWrapper(TaskFunction_t pxCode, void *pvParameters)
|
||||||
* Wrapper to allow task functions to return. Force the optimization option -O1 on that function to make sure there
|
|
||||||
* is no tail-call. Indeed, we need the compiler to keep the return address to this function when calling `panic_abort`.
|
|
||||||
*
|
|
||||||
* Thanks to `naked` attribute, the compiler won't generate a prologue and epilogue for the function, which saves time
|
|
||||||
* and stack space.
|
|
||||||
*/
|
|
||||||
static void __attribute__((optimize("O1"), naked)) vPortTaskWrapper(TaskFunction_t pxCode, void *pvParameters)
|
|
||||||
{
|
{
|
||||||
asm volatile(".cfi_undefined ra\n");
|
__asm__ volatile(".cfi_undefined ra"); // tell to debugger that it's outermost (inital) frame
|
||||||
extern void __attribute__((noreturn)) panic_abort(const char *details);
|
extern void __attribute__((noreturn)) panic_abort(const char *details);
|
||||||
static char DRAM_ATTR msg[80] = "FreeRTOS: FreeRTOS Task \"\0";
|
static char DRAM_ATTR msg[80] = "FreeRTOS: FreeRTOS Task \"\0";
|
||||||
pxCode(pvParameters);
|
pxCode(pvParameters);
|
||||||
//FreeRTOS tasks should not return. Log the task name and abort.
|
/* FreeRTOS tasks should not return. Log the task name and abort. */
|
||||||
char *pcTaskName = pcTaskGetName(NULL);
|
|
||||||
/* We cannot use s(n)printf because it is in flash */
|
/* We cannot use s(n)printf because it is in flash */
|
||||||
strcat(msg, pcTaskName);
|
strcat(msg, pcTaskGetName(NULL));
|
||||||
strcat(msg, "\" should not return, Aborting now!");
|
strcat(msg, "\" should not return, Aborting now!");
|
||||||
panic_abort(msg);
|
panic_abort(msg);
|
||||||
}
|
}
|
||||||
|
@@ -194,37 +194,17 @@ FORCE_INLINE_ATTR UBaseType_t uxInitialiseStackTLS(UBaseType_t uxStackPointer, u
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if CONFIG_FREERTOS_TASK_FUNCTION_WRAPPER
|
#if CONFIG_FREERTOS_TASK_FUNCTION_WRAPPER
|
||||||
/**
|
static void vPortTaskWrapper(TaskFunction_t pxCode, void *pvParameters)
|
||||||
* Wrapper to allow task functions to return. Force the optimization option -O1 on that function to make sure there
|
|
||||||
* is no tail-call. Indeed, we need the compiler to keep the return address to this function when calling `panic_abort`.
|
|
||||||
*
|
|
||||||
* Thanks to `naked` attribute, the compiler won't generate a prologue and epilogue for the function, which saves time
|
|
||||||
* and stack space.
|
|
||||||
*/
|
|
||||||
static void __attribute__((optimize("O1"), naked)) vPortTaskWrapper(TaskFunction_t pxCode, void *pvParameters)
|
|
||||||
{
|
{
|
||||||
#ifdef __clang__
|
__asm__ volatile(".cfi_undefined ra"); // tell to debugger that it's outermost (inital) frame
|
||||||
// clang generates error "error: non-ASM statement in naked function is not supported"
|
|
||||||
// The reason for it is described at
|
|
||||||
// https://stackoverflow.com/questions/47316611/clang-error-non-asm-statement-in-naked-function-is-not-supported.
|
|
||||||
// GCC docs say that there is no guarantee that non-ASM statement in naked function will work:
|
|
||||||
// "Only basic asm statements can safely be included in naked functions (see Basic Asm).
|
|
||||||
// While using extended asm or a mixture of basic asm and C code may appear to work, they cannot be
|
|
||||||
// depended upon to work reliably and are not supported."
|
|
||||||
// TODO: IDF-6347
|
|
||||||
#error CONFIG_FREERTOS_TASK_FUNCTION_WRAPPER not supported yet when building with Clang!
|
|
||||||
#else
|
|
||||||
asm volatile(".cfi_undefined ra\n");
|
|
||||||
extern void __attribute__((noreturn)) panic_abort(const char *details);
|
extern void __attribute__((noreturn)) panic_abort(const char *details);
|
||||||
static char DRAM_ATTR msg[80] = "FreeRTOS: FreeRTOS Task \"\0";
|
static char DRAM_ATTR msg[80] = "FreeRTOS: FreeRTOS Task \"\0";
|
||||||
pxCode(pvParameters);
|
pxCode(pvParameters);
|
||||||
//FreeRTOS tasks should not return. Log the task name and abort.
|
/* FreeRTOS tasks should not return. Log the task name and abort. */
|
||||||
char *pcTaskName = pcTaskGetName(NULL);
|
|
||||||
/* We cannot use s(n)printf because it is in flash */
|
/* We cannot use s(n)printf because it is in flash */
|
||||||
strcat(msg, pcTaskName);
|
strcat(msg, pcTaskGetName(NULL));
|
||||||
strcat(msg, "\" should not return, Aborting now!");
|
strcat(msg, "\" should not return, Aborting now!");
|
||||||
panic_abort(msg);
|
panic_abort(msg);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
#endif // CONFIG_FREERTOS_TASK_FUNCTION_WRAPPER
|
#endif // CONFIG_FREERTOS_TASK_FUNCTION_WRAPPER
|
||||||
|
|
||||||
|
@@ -232,8 +232,6 @@ entries:
|
|||||||
if IDF_TARGET_ARCH_XTENSA = y:
|
if IDF_TARGET_ARCH_XTENSA = y:
|
||||||
port:xPortStartScheduler (default)
|
port:xPortStartScheduler (default)
|
||||||
port:vPortEndScheduler (default)
|
port:vPortEndScheduler (default)
|
||||||
if FREERTOS_TASK_FUNCTION_WRAPPER = y:
|
|
||||||
port:vPortTaskWrapper (default)
|
|
||||||
port:pxPortInitialiseStack (default)
|
port:pxPortInitialiseStack (default)
|
||||||
if IDF_TARGET_ESP32 = y || IDF_TARGET_ESP32S3 = y :
|
if IDF_TARGET_ESP32 = y || IDF_TARGET_ESP32S3 = y :
|
||||||
port:vPortCleanUpCoprocArea (default)
|
port:vPortCleanUpCoprocArea (default)
|
||||||
@@ -245,7 +243,5 @@ entries:
|
|||||||
if IDF_TARGET_ARCH_RISCV = y:
|
if IDF_TARGET_ARCH_RISCV = y:
|
||||||
port:xPortStartScheduler (default)
|
port:xPortStartScheduler (default)
|
||||||
port:vPortEndScheduler (default)
|
port:vPortEndScheduler (default)
|
||||||
if FREERTOS_TASK_FUNCTION_WRAPPER = y:
|
|
||||||
port:vPortTaskWrapper (default)
|
|
||||||
port:pxPortInitialiseStack (default)
|
port:pxPortInitialiseStack (default)
|
||||||
port:xPortGetTickRateHz (default)
|
port:xPortGetTickRateHz (default)
|
||||||
|
@@ -215,8 +215,6 @@ entries:
|
|||||||
port:vPortFree (default)
|
port:vPortFree (default)
|
||||||
port:vPortInitialiseBlocks (default)
|
port:vPortInitialiseBlocks (default)
|
||||||
port:xPortGetFreeHeapSize (default)
|
port:xPortGetFreeHeapSize (default)
|
||||||
if FREERTOS_TASK_FUNCTION_WRAPPER = y:
|
|
||||||
port:vPortTaskWrapper (default)
|
|
||||||
port:pxPortInitialiseStack (default)
|
port:pxPortInitialiseStack (default)
|
||||||
if FREERTOS_UNICORE = n:
|
if FREERTOS_UNICORE = n:
|
||||||
port:vPortCleanUpCoprocArea (default)
|
port:vPortCleanUpCoprocArea (default)
|
||||||
@@ -235,8 +233,6 @@ entries:
|
|||||||
port:vPortFree (default)
|
port:vPortFree (default)
|
||||||
port:vPortInitialiseBlocks (default)
|
port:vPortInitialiseBlocks (default)
|
||||||
port:xPortGetFreeHeapSize (default)
|
port:xPortGetFreeHeapSize (default)
|
||||||
if FREERTOS_TASK_FUNCTION_WRAPPER = y:
|
|
||||||
port:vPortTaskWrapper (default)
|
|
||||||
port:pxPortInitialiseStack (default)
|
port:pxPortInitialiseStack (default)
|
||||||
if FREERTOS_TLSP_DELETION_CALLBACKS = y:
|
if FREERTOS_TLSP_DELETION_CALLBACKS = y:
|
||||||
port:vPortTLSPointersDelCb (default)
|
port:vPortTLSPointersDelCb (default)
|
||||||
|
Reference in New Issue
Block a user