|
|
@@ -0,0 +1,108 @@
|
|
|
+/*
|
|
|
+ * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
|
|
+ *
|
|
|
+ * SPDX-License-Identifier: Unlicense OR CC0-1.0
|
|
|
+ */
|
|
|
+#include <iostream>
|
|
|
+#include <thread>
|
|
|
+#include <chrono>
|
|
|
+#include <memory>
|
|
|
+#include <string>
|
|
|
+#include <sstream>
|
|
|
+#include <esp_pthread.h>
|
|
|
+#include <freertos/FreeRTOS.h>
|
|
|
+#include <freertos/task.h>
|
|
|
+#include <esp_log.h>
|
|
|
+
|
|
|
+using namespace std::chrono;
|
|
|
+
|
|
|
+const auto sleep_time = seconds
|
|
|
+{
|
|
|
+ 5
|
|
|
+};
|
|
|
+
|
|
|
+void print_thread_info(const char *extra = nullptr)
|
|
|
+{
|
|
|
+ std::stringstream ss;
|
|
|
+ if (extra) {
|
|
|
+ ss << extra;
|
|
|
+ }
|
|
|
+ ss << "Core id: " << xPortGetCoreID()
|
|
|
+ << ", prio: " << uxTaskPriorityGet(nullptr)
|
|
|
+ << ", minimum free stack: " << uxTaskGetStackHighWaterMark(nullptr) << " bytes.";
|
|
|
+ ESP_LOGI(pcTaskGetName(nullptr), "%s", ss.str().c_str());
|
|
|
+}
|
|
|
+
|
|
|
+void thread_func_inherited()
|
|
|
+{
|
|
|
+ while (true) {
|
|
|
+ print_thread_info("This is the INHERITING thread with the same parameters as our parent, including name. ");
|
|
|
+ std::this_thread::sleep_for(sleep_time);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void spawn_another_thread()
|
|
|
+{
|
|
|
+ // Create a new thread, it will inherit our configuration
|
|
|
+ std::thread inherits(thread_func_inherited);
|
|
|
+
|
|
|
+ while (true) {
|
|
|
+ print_thread_info();
|
|
|
+ std::this_thread::sleep_for(sleep_time);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void thread_func_any_core()
|
|
|
+{
|
|
|
+ while (true) {
|
|
|
+ print_thread_info("This thread (with the default name) may run on any core.");
|
|
|
+ std::this_thread::sleep_for(sleep_time);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void thread_func()
|
|
|
+{
|
|
|
+ while (true) {
|
|
|
+ print_thread_info();
|
|
|
+ std::this_thread::sleep_for(sleep_time);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+esp_pthread_cfg_t create_config(const char *name, int core_id, int stack, int prio)
|
|
|
+{
|
|
|
+ auto cfg = esp_pthread_get_default_config();
|
|
|
+ cfg.thread_name = name;
|
|
|
+ cfg.pin_to_core = core_id;
|
|
|
+ cfg.stack_size = stack;
|
|
|
+ cfg.prio = prio;
|
|
|
+ return cfg;
|
|
|
+}
|
|
|
+
|
|
|
+extern "C" void app_main(void)
|
|
|
+{
|
|
|
+ // Create a thread using deafult values that can run on any core
|
|
|
+ auto cfg = esp_pthread_get_default_config();
|
|
|
+ esp_pthread_set_cfg(&cfg);
|
|
|
+ std::thread any_core(thread_func_any_core);
|
|
|
+
|
|
|
+ // Create a thread on core 0 that spawns another thread, they will both have the same name etc.
|
|
|
+ cfg = create_config("Thread 1", 0, 3 * 1024, 5);
|
|
|
+ cfg.inherit_cfg = true;
|
|
|
+ esp_pthread_set_cfg(&cfg);
|
|
|
+ std::thread thread_1(spawn_another_thread);
|
|
|
+
|
|
|
+ // Create a thread on core 1.
|
|
|
+ cfg = create_config("Thread 2", 1, 3 * 1024, 5);
|
|
|
+ esp_pthread_set_cfg(&cfg);
|
|
|
+ std::thread thread_2(thread_func);
|
|
|
+
|
|
|
+ // Let the main task do something too
|
|
|
+ while (true) {
|
|
|
+ std::stringstream ss;
|
|
|
+ ss << "core id: " << xPortGetCoreID()
|
|
|
+ << ", prio: " << uxTaskPriorityGet(nullptr)
|
|
|
+ << ", minimum free stack: " << uxTaskGetStackHighWaterMark(nullptr) << " bytes.";
|
|
|
+ ESP_LOGI(pcTaskGetName(nullptr), "%s", ss.str().c_str());
|
|
|
+ std::this_thread::sleep_for(sleep_time);
|
|
|
+ }
|
|
|
+}
|