Quellcode durchsuchen

Merge branch 'bugfix/coex_semaphore_take_in_isr_lock_v4.0' into 'release/v4.0'

fix bug that semaphore may schedule out in ISR locking

See merge request espressif/esp-idf!6426
Jiang Jiang Jian vor 6 Jahren
Ursprung
Commit
3a1d0e9352

+ 1 - 1
components/bt/controller/bt.c

@@ -742,7 +742,7 @@ static void task_delete_wrapper(void *task_handle)
 
 static bool IRAM_ATTR is_in_isr_wrapper(void)
 {
-    return (bool)xPortInIsrContext();
+    return !xPortCanYield();
 }
 
 static void IRAM_ATTR cause_sw_intr(void *arg)

+ 6 - 1
components/esp32/esp_adapter.c

@@ -508,6 +508,11 @@ void IRAM_ATTR coex_bb_reset_unlock_wrapper(uint32_t restore)
 #endif
 }
 
+int32_t IRAM_ATTR coex_is_in_isr_wrapper(void)
+{
+    return !xPortCanYield();
+}
+
 wifi_osi_funcs_t g_wifi_osi_funcs = {
     ._version = ESP_WIFI_OS_ADAPTER_VERSION,
     ._set_isr = set_isr_wrapper,
@@ -617,7 +622,7 @@ coex_adapter_funcs_t g_coex_adapter_funcs = {
     ._semphr_give_from_isr = semphr_give_from_isr_wrapper,
     ._semphr_take = semphr_take_wrapper,
     ._semphr_give = semphr_give_wrapper,
-    ._is_in_isr = xPortInIsrContext,
+    ._is_in_isr = coex_is_in_isr_wrapper,
     ._malloc_internal =  malloc_internal_wrapper,
     ._free = free,
     ._timer_disarm = timer_disarm_wrapper,

+ 20 - 0
components/freertos/include/freertos/portable.h

@@ -86,6 +86,8 @@ specific constants has been moved into the deprecated_definitions.h header
 file. */
 #include "deprecated_definitions.h"
 
+#include "soc/cpu.h"
+
 /* If portENTER_CRITICAL is not defined then including deprecated_definitions.h
 did not result in a portmacro.h header file being included - and it should be
 included here.  In this case the path to the correct portmacro.h header file
@@ -215,6 +217,24 @@ static inline uint32_t IRAM_ATTR xPortGetCoreID() {
 /* Get tick rate per second */
 uint32_t xPortGetTickRateHz(void);
 
+
+static inline bool IRAM_ATTR xPortCanYield(void)
+{
+    uint32_t ps_reg = 0;
+
+    //Get the current value of PS (processor status) register
+    RSR(PS, ps_reg);
+
+    /*
+     * intlevel = (ps_reg & 0xf);
+     * excm  = (ps_reg >> 4) & 0x1;
+     * CINTLEVEL is max(excm * EXCMLEVEL, INTLEVEL), where EXCMLEVEL is 3.
+     * However, just return true, only intlevel is zero.
+     */
+
+    return ((ps_reg & PS_INTLEVEL_MASK) == 0);
+}
+
 #ifdef __cplusplus
 }
 #endif

+ 2 - 2
components/newlib/locks.c

@@ -137,7 +137,7 @@ static int IRAM_ATTR lock_acquire_generic(_lock_t *lock, uint32_t delay, uint8_t
     }
 
     BaseType_t success;
-    if (xPortInIsrContext()) {
+    if (!xPortCanYield()) {
         /* In ISR Context */
         if (mutex_type == queueQUEUE_TYPE_RECURSIVE_MUTEX) {
             abort(); /* recursive mutexes make no sense in ISR context */
@@ -191,7 +191,7 @@ static void IRAM_ATTR lock_release_generic(_lock_t *lock, uint8_t mutex_type) {
         return;
     }
 
-    if (xPortInIsrContext()) {
+    if (!xPortCanYield()) {
         if (mutex_type == queueQUEUE_TYPE_RECURSIVE_MUTEX) {
             abort(); /* indicates logic bug, it shouldn't be possible to lock recursively in ISR */
         }