pw_thread_freertos: Don't resume before scheduler is running

Calling vTaskResume() before vTaskStartScheduler() can cause
port_YIELD() to be called, resulting in a crash either now or later.

It's safe to call xTaskResumeAll() instead, so apply the fix by only
using vTaskResume() is both that method and xTaskGetSchedulerState()
are available.

No-Docs-Update-Reason: bugfix
Change-Id: I07214c2a294a29ca579aac589e80ad9a90933104
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/56548
Pigweed-Auto-Submit: Scott James Remnant <keybuk@google.com>
Commit-Queue: Auto-Submit <auto-submit@pigweed.google.com.iam.gserviceaccount.com>
Reviewed-by: Keir Mierle <keir@google.com>
diff --git a/pw_thread_freertos/thread.cc b/pw_thread_freertos/thread.cc
index 7854e19..d516b65 100644
--- a/pw_thread_freertos/thread.cc
+++ b/pw_thread_freertos/thread.cc
@@ -184,18 +184,25 @@
 void Thread::detach() {
   PW_CHECK(joinable());
 
-#if INCLUDE_vTaskSuspend == 1
+#if (INCLUDE_vTaskSuspend == 1) && (INCLUDE_xTaskGetSchedulerState == 1)
   // No need to suspend extra tasks.
-  vTaskSuspend(native_type_->task_handle());
+  if (xTaskGetSchedulerState() == taskSCHEDULER_RUNNING) {
+    vTaskSuspend(native_type_->task_handle());
+  }
 #else
+  // Safe to suspend all tasks while scheduler is not running.
   vTaskSuspendAll();
 #endif  // INCLUDE_vTaskSuspend == 1
   native_type_->set_detached();
   const bool thread_done = native_type_->thread_done();
-#if INCLUDE_vTaskSuspend == 1
-  // No need to suspend extra tasks.
-  vTaskResume(native_type_->task_handle());
+#if (INCLUDE_vTaskSuspend == 1) && (INCLUDE_xTaskGetSchedulerState == 1)
+  // No need to suspend extra tasks, but only safe to call once scheduler is
+  // running.
+  if (xTaskGetSchedulerState() == taskSCHEDULER_RUNNING) {
+    vTaskResume(native_type_->task_handle());
+  }
 #else
+  // Safe to resume all tasks while scheduler is not running.
   vTaskResumeAll();
 #endif  // INCLUDE_vTaskSuspend == 1