the setup / loop() on the ESP32 is just a task amongst the others created in main
and the loop task does basically call setup and then loop for ever, patting the dog along the way
void loopTask(void *pvParameters) {
setup();
for(;;) {
if(loopTaskWDTEnabled) esp_task_wdt_reset();
loop();
if (serialEventRun) serialEventRun();
}
}
(simplified)
so your own setup can use in the same way xTaskCreate to spawn other tasks and you can decide on which core the task is run.
may be this previous conversation can help
(there is another one with more stuff, can't find it right now)
or read ESP32 Dual Core with Arduino IDE | Random Nerd Tutorials