Jelajahi Sumber

Merge branch 'bugfix/freertos_dual_core_hooks' into 'master'

bugfix/freertos_dual_core_hooks

See merge request !1399

He Yin Ling 8 tahun lalu
induk
melakukan
3a271a4ae7

+ 32 - 21
components/esp32/freertos_hooks.c

@@ -56,48 +56,59 @@ void esp_vApplicationIdleHook()
     }
 }
 
-
-esp_err_t esp_register_freertos_idle_hook(esp_freertos_idle_cb_t new_idle_cb) 
+esp_err_t esp_register_freertos_idle_hook_for_cpu(esp_freertos_idle_cb_t new_idle_cb, UBaseType_t cpuid)
 {
-    int n;
-    int core = xPortGetCoreID();
-    for (n=0; n<MAX_HOOKS; n++) {
-        if (idle_cb[core][n]==NULL) {
-            idle_cb[core][n]=new_idle_cb;
+    if(cpuid >= portNUM_PROCESSORS){
+        return ESP_ERR_INVALID_ARG;
+    }
+    for(int n = 0; n < MAX_HOOKS; n++){
+        if (idle_cb[cpuid][n]==NULL) {
+            idle_cb[cpuid][n]=new_idle_cb;
             return ESP_OK;
         }
     }
     return ESP_ERR_NO_MEM;
 }
 
-esp_err_t esp_register_freertos_tick_hook(esp_freertos_tick_cb_t new_tick_cb) 
+esp_err_t esp_register_freertos_idle_hook(esp_freertos_idle_cb_t new_idle_cb)
 {
-    int n;
-    int core = xPortGetCoreID();
-    for (n=0; n<MAX_HOOKS; n++) {
-        if (tick_cb[core][n]==NULL) {
-            tick_cb[core][n]=new_tick_cb;
+    return esp_register_freertos_idle_hook_for_cpu(new_idle_cb, xPortGetCoreID());
+}
+
+esp_err_t esp_register_freertos_tick_hook_for_cpu(esp_freertos_tick_cb_t new_tick_cb, UBaseType_t cpuid)
+{
+    if(cpuid >= portNUM_PROCESSORS){
+        return ESP_ERR_INVALID_ARG;
+    }
+    for(int n = 0; n < MAX_HOOKS; n++){
+        if (tick_cb[cpuid][n]==NULL) {
+            tick_cb[cpuid][n]=new_tick_cb;
             return ESP_OK;
         }
     }
     return ESP_ERR_NO_MEM;
 }
 
+esp_err_t esp_register_freertos_tick_hook(esp_freertos_tick_cb_t new_tick_cb) 
+{
+    return esp_register_freertos_tick_hook_for_cpu(new_tick_cb, xPortGetCoreID());
+}
+
 void esp_deregister_freertos_idle_hook(esp_freertos_idle_cb_t old_idle_cb)
 {
-    int n;
-    int core = xPortGetCoreID();
-    for (n=0; n<MAX_HOOKS; n++) {
-        if (idle_cb[core][n]==old_idle_cb) idle_cb[core][n]=NULL;
+    for(int m = 0; m < portNUM_PROCESSORS; m++) {
+        for(int n = 0; n < MAX_HOOKS; n++){
+            if(idle_cb[m][n] == old_idle_cb) idle_cb[m][n] = NULL;
+        }
     }
 }
 
 void esp_deregister_freertos_tick_hook(esp_freertos_tick_cb_t old_tick_cb)
 {
-    int n;
-    int core = xPortGetCoreID();
-    for (n=0; n<MAX_HOOKS; n++) {
-        if (tick_cb[core][n]==old_tick_cb) tick_cb[core][n]=NULL;
+    for(int m = 0; m < portNUM_PROCESSORS; m++){
+        for(int n = 0; n < MAX_HOOKS; n++){
+            if(tick_cb[m][n] == old_tick_cb) tick_cb[m][n] = NULL;
+        }
     }
 }
 

+ 47 - 13
components/esp32/include/esp_freertos_hooks.h

@@ -30,34 +30,66 @@ typedef bool (*esp_freertos_idle_cb_t)();
 typedef void (*esp_freertos_tick_cb_t)();
 
 /**
-  * @brief  Register a callback to be called on the freertos idle hook
-  *         The callback should return true if it's okay for the core to
-  *         sleep until an interrupt (or FreeRTOS tick) happens and false
-  *         if it should be called again as fast as possible.
+  * @brief  Register a callback to be called from the specified core's idle hook.
+  *         The callback should return true if it should be called by the idle hook
+  *         once per interrupt (or FreeRTOS tick), and return false if it should
+  *         be called repeatedly as fast as possible by the idle hook.
   *
-  * @warning Idle callbacks MUST NOT, UNDER ANY CIRCUMSTANCES, CALL 
+  * @warning Idle callbacks MUST NOT, UNDER ANY CIRCUMSTANCES, CALL
   *          A FUNCTION THAT MIGHT BLOCK.
   *
   * @param  esp_freertos_idle_cb_t new_idle_cb : Callback to be called
+  * @param  UBaseType_t cpuid : id of the core
   *
-  * @return ESP_OK : Callback registered
-  * @return ESP_ERR_NO_MEM : No more space to register hook
+  * @return ESP_OK : Callback registered to the specified core's idle hook
+  * @return ESP_ERR_NO_MEM : No more space on the specified core's idle hook to register callback
+  * @return ESP_ERR_INVALID_ARG : cpuid is invalid
+  */
+esp_err_t esp_register_freertos_idle_hook_for_cpu(esp_freertos_idle_cb_t new_idle_cb, UBaseType_t cpuid);
+
+/**
+  * @brief  Register a callback to the idle hook of the core that calls this function.
+  *         The callback should return true if it should be called by the idle hook
+  *         once per interrupt (or FreeRTOS tick), and return false if it should
+  *         be called repeatedly as fast as possible by the idle hook.
+  *
+  * @warning Idle callbacks MUST NOT, UNDER ANY CIRCUMSTANCES, CALL
+  *          A FUNCTION THAT MIGHT BLOCK.
+  *
+  * @param  esp_freertos_idle_cb_t new_idle_cb : Callback to be called
+  *
+  * @return ESP_OK : Callback registered to the calling core's idle hook
+  * @return ESP_ERR_NO_MEM : No more space the calling core's idle hook to register callback
   */
 esp_err_t esp_register_freertos_idle_hook(esp_freertos_idle_cb_t new_idle_cb);
 
 /**
-  * @brief  Register a callback to be called on the freertos tick hook
+  * @brief  Register a callback to be called from the specified core's tick hook.
   *
   * @param  esp_freertos_tick_cb_t new_tick_cb : Callback to be called
+  * @param  UBaseType_t cpuid : id of the core
   *
   * @return ESP_OK : Callback registered
-  * @return ESP_ERR_NO_MEM : No more space to register hook
+  * @return ESP_ERR_NO_MEM : No more space on the specified core's tick hook to register the callback
+  * @return ESP_ERR_INVALID_ARG : cpuid is invalid
   */
-esp_err_t esp_register_freertos_tick_hook(esp_freertos_tick_cb_t tick_cb);
+esp_err_t esp_register_freertos_tick_hook_for_cpu(esp_freertos_tick_cb_t new_tick_cb, UBaseType_t cpuid);
+
+/**
+  * @brief  Register a callback to be called from the calling core's tick hook.
+  *
+  * @param  esp_freertos_tick_cb_t new_tick_cb : Callback to be called
+  *
+  * @return ESP_OK : Callback registered
+  * @return ESP_ERR_NO_MEM : No more space on the calling core's tick hook to register the callback
+  */
+esp_err_t esp_register_freertos_tick_hook(esp_freertos_tick_cb_t new_tick_cb);
 
 
 /**
-  * @brief  Unregister an idle callback registered earlier
+  * @brief  Unregister an idle callback. If the idle callback is registered to
+  *         the idle hooks of both cores, the idle hook will be unregistered from
+  *         both cores
   *
   * @param  esp_freertos_idle_cb_t new_idle_cb : Callback to be unregistered
   *
@@ -67,7 +99,9 @@ void esp_deregister_freertos_idle_hook(esp_freertos_idle_cb_t old_idle_cb);
 
 
 /**
-  * @brief  Unregister a tick callback registered earlier
+  * @brief  Unregister a tick callback. If the tick callback is registered to the
+  *         tick hooks of both cores, the tick hook will be unregistered from
+  *         both cores
   *
   * @param  esp_freertos_idle_cb_t new_idle_cb : Callback to be unregistered
   *
@@ -80,4 +114,4 @@ void esp_deregister_freertos_tick_hook(esp_freertos_tick_cb_t old_tick_cb);
 #endif
 
 
-#endif
+#endif

+ 4 - 1
components/esp32/int_wdt.c

@@ -87,7 +87,10 @@ void esp_int_wdt_init() {
     TIMERG1.wdt_wprotect=0;
     TIMERG1.int_clr_timers.wdt=1;
     timer_group_intr_enable(TIMER_GROUP_1, TIMG_WDT_INT_ENA_M);
-    esp_register_freertos_tick_hook(tick_hook);
+    esp_register_freertos_tick_hook_for_cpu(tick_hook, 0);
+#ifndef CONFIG_FREERTOS_UNICORE
+    esp_register_freertos_tick_hook_for_cpu(tick_hook, 1);
+#endif
     ESP_INTR_DISABLE(WDT_INT_NUM);
     intr_matrix_set(xPortGetCoreID(), ETS_TG1_WDT_LEVEL_INTR_SOURCE, WDT_INT_NUM);
     //We do not register a handler for the interrupt because it is interrupt level 4 which