cpp_pthread.cpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. /*
  2. * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Unlicense OR CC0-1.0
  5. */
  6. #include <iostream>
  7. #include <thread>
  8. #include <chrono>
  9. #include <memory>
  10. #include <string>
  11. #include <sstream>
  12. #include <esp_pthread.h>
  13. #include <freertos/FreeRTOS.h>
  14. #include <freertos/task.h>
  15. #include <esp_log.h>
  16. using namespace std::chrono;
  17. const auto sleep_time = seconds
  18. {
  19. 5
  20. };
  21. void print_thread_info(const char *extra = nullptr)
  22. {
  23. std::stringstream ss;
  24. if (extra) {
  25. ss << extra;
  26. }
  27. ss << "Core id: " << xPortGetCoreID()
  28. << ", prio: " << uxTaskPriorityGet(nullptr)
  29. << ", minimum free stack: " << uxTaskGetStackHighWaterMark(nullptr) << " bytes.";
  30. ESP_LOGI(pcTaskGetName(nullptr), "%s", ss.str().c_str());
  31. }
  32. void thread_func_inherited()
  33. {
  34. while (true) {
  35. print_thread_info("This is the INHERITING thread with the same parameters as our parent, including name. ");
  36. std::this_thread::sleep_for(sleep_time);
  37. }
  38. }
  39. void spawn_another_thread()
  40. {
  41. // Create a new thread, it will inherit our configuration
  42. std::thread inherits(thread_func_inherited);
  43. while (true) {
  44. print_thread_info();
  45. std::this_thread::sleep_for(sleep_time);
  46. }
  47. }
  48. void thread_func_any_core()
  49. {
  50. while (true) {
  51. print_thread_info("This thread (with the default name) may run on any core.");
  52. std::this_thread::sleep_for(sleep_time);
  53. }
  54. }
  55. void thread_func()
  56. {
  57. while (true) {
  58. print_thread_info();
  59. std::this_thread::sleep_for(sleep_time);
  60. }
  61. }
  62. esp_pthread_cfg_t create_config(const char *name, int core_id, int stack, int prio)
  63. {
  64. auto cfg = esp_pthread_get_default_config();
  65. cfg.thread_name = name;
  66. cfg.pin_to_core = core_id;
  67. cfg.stack_size = stack;
  68. cfg.prio = prio;
  69. return cfg;
  70. }
  71. extern "C" void app_main(void)
  72. {
  73. // Create a thread using deafult values that can run on any core
  74. auto cfg = esp_pthread_get_default_config();
  75. esp_pthread_set_cfg(&cfg);
  76. std::thread any_core(thread_func_any_core);
  77. // Create a thread on core 0 that spawns another thread, they will both have the same name etc.
  78. cfg = create_config("Thread 1", 0, 3 * 1024, 5);
  79. cfg.inherit_cfg = true;
  80. esp_pthread_set_cfg(&cfg);
  81. std::thread thread_1(spawn_another_thread);
  82. // Create a thread on core 1.
  83. cfg = create_config("Thread 2", 1, 3 * 1024, 5);
  84. esp_pthread_set_cfg(&cfg);
  85. std::thread thread_2(thread_func);
  86. // Let the main task do something too
  87. while (true) {
  88. std::stringstream ss;
  89. ss << "core id: " << xPortGetCoreID()
  90. << ", prio: " << uxTaskPriorityGet(nullptr)
  91. << ", minimum free stack: " << uxTaskGetStackHighWaterMark(nullptr) << " bytes.";
  92. ESP_LOGI(pcTaskGetName(nullptr), "%s", ss.str().c_str());
  93. std::this_thread::sleep_for(sleep_time);
  94. }
  95. }