bugfix/freertos_dual_core_hooks

This commit fixes bugs with the dual core changes to freeRTOS tick and idle hooks.
Interrupt watchdog now registers tick hooks to both cores.
API for cross core tick and idle hook registration were also added
This commit is contained in:
Darian Leung 2017-10-13 18:27:53 +08:00
parent a0ad3ff008
commit 95d63137d1
3 changed files with 86 additions and 38 deletions

View file

@ -56,14 +56,33 @@ 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_idle_hook(esp_freertos_idle_cb_t new_idle_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;
}
}
@ -72,32 +91,24 @@ esp_err_t esp_register_freertos_idle_hook(esp_freertos_idle_cb_t new_idle_cb)
esp_err_t esp_register_freertos_tick_hook(esp_freertos_tick_cb_t new_tick_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_OK;
}
}
return ESP_ERR_NO_MEM;
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;
}
}
}

View file

@ -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 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
* @return ESP_ERR_NO_MEM : No more space to register hook
* @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 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_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 to register hook
* @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 tick_cb);
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

View file

@ -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