/** * Context switches are realized using software interrupts since interrupt * entry and exit functions are the only way to save and restore complete * context including spilling the register windows to the stack */ void IRAM_ATTR thread_yield_isr(void* arg) { /* clear the interrupt first */ DPORT_WRITE_PERI_REG(DPORT_CPU_INTR_FROM_CPU_0_REG, 0); /* set the context switch flag (indicates that context has to be switched is switch on exit from interrupt in _frxt_int_exit */ _frxt_setup_switch(); }
int trax_enable(trax_ena_select_t which) { #if !CONFIG_ESP32_TRAX ESP_LOGE(TAG, "Trax_enable called, but trax is disabled in menuconfig!"); return ESP_ERR_NO_MEM; #endif #if !CONFIG_ESP32_TRAX_TWOBANKS if (which == TRAX_ENA_PRO_APP || which == TRAX_ENA_PRO_APP_SWAP) return ESP_ERR_NO_MEM; #endif if (which == TRAX_ENA_PRO_APP || which == TRAX_ENA_PRO_APP_SWAP) { DPORT_WRITE_PERI_REG(DPORT_TRACEMEM_MUX_MODE_REG, (which == TRAX_ENA_PRO_APP_SWAP)?TRACEMEM_MUX_PROBLK1_APPBLK0:TRACEMEM_MUX_PROBLK0_APPBLK1); } else { DPORT_WRITE_PERI_REG(DPORT_TRACEMEM_MUX_MODE_REG, TRACEMEM_MUX_BLK0_ONLY); } DPORT_WRITE_PERI_REG(DPORT_PRO_TRACEMEM_ENA_REG, (which == TRAX_ENA_PRO_APP || which == TRAX_ENA_PRO_APP_SWAP || which == TRAX_ENA_PRO)); DPORT_WRITE_PERI_REG(DPORT_APP_TRACEMEM_ENA_REG, (which == TRAX_ENA_PRO_APP || which == TRAX_ENA_PRO_APP_SWAP || which == TRAX_ENA_APP)); return ESP_OK; }
/** * If we are already in an interrupt handler, the function simply sets the * context switch flag, which indicates that the context has to be switched * in the _frxt_int_exit function when exiting the interrupt. Otherwise, we * will generate a software interrupt to force the context switch when * terminating the software interrupt (see thread_yield_isr). */ void thread_yield_higher(void) { /* reset hardware watchdog */ system_wdt_feed(); /* yield next task */ #if defined(ENABLE_DEBUG) && defined(DEVELHELP) if (sched_active_thread) { DEBUG("%u old task %u %s %u\n", system_get_time(), sched_active_thread->pid, sched_active_thread->name, sched_active_thread->sp - sched_active_thread-> stack_start); } #endif if (!irq_is_in()) { /* generate the software interrupt to switch the context */ DPORT_WRITE_PERI_REG(DPORT_CPU_INTR_FROM_CPU_0_REG, DPORT_CPU_INTR_FROM_CPU_0); } else { /* set the context switch flag */ _frxt_setup_switch(); } #if defined(ENABLE_DEBUG) && defined(DEVELHELP) if (sched_active_thread) { DEBUG("%u new task %u %s %u\n", system_get_time(), sched_active_thread->pid, sched_active_thread->name, sched_active_thread->sp - sched_active_thread-> stack_start); } #endif /* * Instruction fetch synchronize: Waits for all previously fetched load, * store, cache, and special register write instructions that affect * instruction fetch to be performed before fetching the next instruction. */ __asm__("isync"); return; }