1 // Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
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
7 // http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include "freertos/FreeRTOS.h"
21 #include "esp_freertos_hooks.h"
23 #include "sdkconfig.h"
27 //We use just a static array here because it's not expected many components will need
28 //an idle or tick hook.
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};
35 void IRAM_ATTR esp_vApplicationTickHook()
38 int core = xPortGetCoreID();
39 for (n=0; n<MAX_HOOKS; n++) {
40 if (tick_cb[core][n]!=NULL) {
46 void esp_vApplicationIdleHook()
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]()) {
59 #ifdef CONFIG_PM_ENABLE
60 esp_pm_impl_idle_hook();
64 extern void esp_vApplicationWaitiHook( void )
69 esp_err_t esp_register_freertos_idle_hook_for_cpu(esp_freertos_idle_cb_t new_idle_cb, UBaseType_t cpuid)
71 if(cpuid >= portNUM_PROCESSORS){
72 return ESP_ERR_INVALID_ARG;
74 portENTER_CRITICAL(&hooks_spinlock);
75 for(int n = 0; n < MAX_HOOKS; n++){
76 if (idle_cb[cpuid][n]==NULL) {
77 idle_cb[cpuid][n]=new_idle_cb;
78 portEXIT_CRITICAL(&hooks_spinlock);
82 portEXIT_CRITICAL(&hooks_spinlock);
83 return ESP_ERR_NO_MEM;
86 esp_err_t esp_register_freertos_idle_hook(esp_freertos_idle_cb_t new_idle_cb)
88 return esp_register_freertos_idle_hook_for_cpu(new_idle_cb, xPortGetCoreID());
91 esp_err_t esp_register_freertos_tick_hook_for_cpu(esp_freertos_tick_cb_t new_tick_cb, UBaseType_t cpuid)
93 if(cpuid >= portNUM_PROCESSORS){
94 return ESP_ERR_INVALID_ARG;
96 portENTER_CRITICAL(&hooks_spinlock);
97 for(int n = 0; n < MAX_HOOKS; n++){
98 if (tick_cb[cpuid][n]==NULL) {
99 tick_cb[cpuid][n]=new_tick_cb;
100 portEXIT_CRITICAL(&hooks_spinlock);
104 portEXIT_CRITICAL(&hooks_spinlock);
105 return ESP_ERR_NO_MEM;
108 esp_err_t esp_register_freertos_tick_hook(esp_freertos_tick_cb_t new_tick_cb)
110 return esp_register_freertos_tick_hook_for_cpu(new_tick_cb, xPortGetCoreID());
113 void esp_deregister_freertos_idle_hook_for_cpu(esp_freertos_idle_cb_t old_idle_cb, UBaseType_t cpuid)
115 portENTER_CRITICAL(&hooks_spinlock);
116 if(cpuid >= portNUM_PROCESSORS){
119 for(int n = 0; n < MAX_HOOKS; n++){
120 if(idle_cb[cpuid][n] == old_idle_cb) idle_cb[cpuid][n] = NULL;
122 portEXIT_CRITICAL(&hooks_spinlock);
125 void esp_deregister_freertos_idle_hook(esp_freertos_idle_cb_t old_idle_cb)
127 portENTER_CRITICAL(&hooks_spinlock);
128 for(int m = 0; m < portNUM_PROCESSORS; m++) {
129 esp_deregister_freertos_idle_hook_for_cpu(old_idle_cb, m);
131 portEXIT_CRITICAL(&hooks_spinlock);
134 void esp_deregister_freertos_tick_hook_for_cpu(esp_freertos_tick_cb_t old_tick_cb, UBaseType_t cpuid)
136 portENTER_CRITICAL(&hooks_spinlock);
137 if(cpuid >= portNUM_PROCESSORS){
140 for(int n = 0; n < MAX_HOOKS; n++){
141 if(tick_cb[cpuid][n] == old_tick_cb) tick_cb[cpuid][n] = NULL;
143 portEXIT_CRITICAL(&hooks_spinlock);
146 void esp_deregister_freertos_tick_hook(esp_freertos_tick_cb_t old_tick_cb)
148 portENTER_CRITICAL(&hooks_spinlock);
149 for(int m = 0; m < portNUM_PROCESSORS; m++){
150 esp_deregister_freertos_tick_hook_for_cpu(old_tick_cb, m);
152 portEXIT_CRITICAL(&hooks_spinlock);