1 // Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #if 0 16 #include <stdint.h> 17 #include <stdlib.h> 18 #include <stdbool.h> 19 #include "esp_osal/esp_osal.h" 20 #include "esp_attr.h" 21 #include "esp_freertos_hooks.h" 22 23 #include "sdkconfig.h" 24 #include "esp_pm.h" 25 #include "esp_private/pm_impl.h" 26 27 //We use just a static array here because it's not expected many components will need 28 //an idle or tick hook. 29 #define MAX_HOOKS 8 30 31 static portMUX_TYPE hooks_spinlock = portMUX_INITIALIZER_UNLOCKED; 32 static esp_freertos_idle_cb_t idle_cb[portNUM_PROCESSORS][MAX_HOOKS]={0}; 33 static esp_freertos_tick_cb_t tick_cb[portNUM_PROCESSORS][MAX_HOOKS]={0}; 34 35 void IRAM_ATTR esp_vApplicationTickHook(void) 36 { 37 int n; 38 int core = xPortGetCoreID(); 39 for (n=0; n<MAX_HOOKS; n++) { 40 if (tick_cb[core][n]!=NULL) { 41 tick_cb[core][n](); 42 } 43 } 44 } 45 46 void esp_vApplicationIdleHook(void) 47 { 48 bool can_go_idle=true; 49 int core = xPortGetCoreID(); 50 for (int n = 0; n < MAX_HOOKS; n++) { 51 if (idle_cb[core][n] != NULL && !idle_cb[core][n]()) { 52 can_go_idle = false; 53 } 54 } 55 if (!can_go_idle) { 56 return; 57 } 58 59 #ifdef CONFIG_PM_ENABLE 60 esp_pm_impl_idle_hook(); 61 #endif 62 63 esp_pm_impl_waiti(); 64 } 65 66 esp_err_t esp_register_freertos_idle_hook_for_cpu(esp_freertos_idle_cb_t new_idle_cb, UBaseType_t cpuid) 67 { 68 if(cpuid >= portNUM_PROCESSORS){ 69 return ESP_ERR_INVALID_ARG; 70 } 71 portENTER_CRITICAL(&hooks_spinlock); 72 for(int n = 0; n < MAX_HOOKS; n++){ 73 if (idle_cb[cpuid][n]==NULL) { 74 idle_cb[cpuid][n]=new_idle_cb; 75 portEXIT_CRITICAL(&hooks_spinlock); 76 return ESP_OK; 77 } 78 } 79 portEXIT_CRITICAL(&hooks_spinlock); 80 return ESP_ERR_NO_MEM; 81 } 82 83 esp_err_t esp_register_freertos_idle_hook(esp_freertos_idle_cb_t new_idle_cb) 84 { 85 return esp_register_freertos_idle_hook_for_cpu(new_idle_cb, xPortGetCoreID()); 86 } 87 88 esp_err_t esp_register_freertos_tick_hook_for_cpu(esp_freertos_tick_cb_t new_tick_cb, UBaseType_t cpuid) 89 { 90 if(cpuid >= portNUM_PROCESSORS){ 91 return ESP_ERR_INVALID_ARG; 92 } 93 portENTER_CRITICAL(&hooks_spinlock); 94 for(int n = 0; n < MAX_HOOKS; n++){ 95 if (tick_cb[cpuid][n]==NULL) { 96 tick_cb[cpuid][n]=new_tick_cb; 97 portEXIT_CRITICAL(&hooks_spinlock); 98 return ESP_OK; 99 } 100 } 101 portEXIT_CRITICAL(&hooks_spinlock); 102 return ESP_ERR_NO_MEM; 103 } 104 105 esp_err_t esp_register_freertos_tick_hook(esp_freertos_tick_cb_t new_tick_cb) 106 { 107 return esp_register_freertos_tick_hook_for_cpu(new_tick_cb, xPortGetCoreID()); 108 } 109 110 void esp_deregister_freertos_idle_hook_for_cpu(esp_freertos_idle_cb_t old_idle_cb, UBaseType_t cpuid) 111 { 112 if(cpuid >= portNUM_PROCESSORS){ 113 return; 114 } 115 portENTER_CRITICAL(&hooks_spinlock); 116 for(int n = 0; n < MAX_HOOKS; n++){ 117 if(idle_cb[cpuid][n] == old_idle_cb) idle_cb[cpuid][n] = NULL; 118 } 119 portEXIT_CRITICAL(&hooks_spinlock); 120 } 121 122 void esp_deregister_freertos_idle_hook(esp_freertos_idle_cb_t old_idle_cb) 123 { 124 portENTER_CRITICAL(&hooks_spinlock); 125 for(int m = 0; m < portNUM_PROCESSORS; m++) { 126 esp_deregister_freertos_idle_hook_for_cpu(old_idle_cb, m); 127 } 128 portEXIT_CRITICAL(&hooks_spinlock); 129 } 130 131 void esp_deregister_freertos_tick_hook_for_cpu(esp_freertos_tick_cb_t old_tick_cb, UBaseType_t cpuid) 132 { 133 if(cpuid >= portNUM_PROCESSORS){ 134 return; 135 } 136 portENTER_CRITICAL(&hooks_spinlock); 137 for(int n = 0; n < MAX_HOOKS; n++){ 138 if(tick_cb[cpuid][n] == old_tick_cb) tick_cb[cpuid][n] = NULL; 139 } 140 portEXIT_CRITICAL(&hooks_spinlock); 141 } 142 143 void esp_deregister_freertos_tick_hook(esp_freertos_tick_cb_t old_tick_cb) 144 { 145 portENTER_CRITICAL(&hooks_spinlock); 146 for(int m = 0; m < portNUM_PROCESSORS; m++){ 147 esp_deregister_freertos_tick_hook_for_cpu(old_tick_cb, m); 148 } 149 portEXIT_CRITICAL(&hooks_spinlock); 150 } 151 #endif 152 153