فهرست منبع

Nfc: replace cmsis thread with furi, fix condition race in thread stop routine. (#1003)

* Nfc: replace cmsis thread with furi, fix condition race on thread stop routine.
* Nfc: fix memory leak
* FuriCore, CMSIS: properly handle thread names before scheduler start
あく 3 سال پیش
والد
کامیت
3c77ae2eb8
4فایلهای تغییر یافته به همراه25 افزوده شده و 9 حذف شده
  1. 14 5
      applications/nfc/nfc_worker.c
  2. 2 3
      applications/nfc/nfc_worker_i.h
  3. 6 0
      core/furi/memmgr_heap.c
  4. 3 1
      lib/FreeRTOS-glue/cmsis_os2.c

+ 14 - 5
applications/nfc/nfc_worker.c

@@ -9,11 +9,17 @@
 
 NfcWorker* nfc_worker_alloc() {
     NfcWorker* nfc_worker = malloc(sizeof(NfcWorker));
+
     // Worker thread attributes
-    nfc_worker->thread_attr.name = "NfcWorker";
-    nfc_worker->thread_attr.stack_size = 8192;
+    nfc_worker->thread = furi_thread_alloc();
+    furi_thread_set_name(nfc_worker->thread, "NfcWorker");
+    furi_thread_set_stack_size(nfc_worker->thread, 8192);
+    furi_thread_set_callback(nfc_worker->thread, nfc_worker_task);
+    furi_thread_set_context(nfc_worker->thread, nfc_worker);
+
     nfc_worker->callback = NULL;
     nfc_worker->context = NULL;
+
     // Initialize rfal
     while(furi_hal_nfc_is_busy()) {
         osDelay(10);
@@ -25,6 +31,7 @@ NfcWorker* nfc_worker_alloc() {
 
 void nfc_worker_free(NfcWorker* nfc_worker) {
     furi_assert(nfc_worker);
+    furi_thread_free(nfc_worker->thread);
     free(nfc_worker);
 }
 
@@ -48,7 +55,7 @@ void nfc_worker_start(
     nfc_worker->context = context;
     nfc_worker->dev_data = dev_data;
     nfc_worker_change_state(nfc_worker, state);
-    nfc_worker->thread = osThreadNew(nfc_worker_task, nfc_worker, &nfc_worker->thread_attr);
+    furi_thread_start(nfc_worker->thread);
 }
 
 void nfc_worker_stop(NfcWorker* nfc_worker) {
@@ -58,6 +65,7 @@ void nfc_worker_stop(NfcWorker* nfc_worker) {
     }
     furi_hal_nfc_stop();
     nfc_worker_change_state(nfc_worker, NfcWorkerStateStop);
+    furi_thread_join(nfc_worker->thread);
 }
 
 void nfc_worker_change_state(NfcWorker* nfc_worker, NfcWorkerState state) {
@@ -66,7 +74,7 @@ void nfc_worker_change_state(NfcWorker* nfc_worker, NfcWorkerState state) {
 
 /***************************** NFC Worker Thread *******************************/
 
-void nfc_worker_task(void* context) {
+int32_t nfc_worker_task(void* context) {
     NfcWorker* nfc_worker = context;
 
     furi_hal_power_insomnia_enter();
@@ -92,7 +100,8 @@ void nfc_worker_task(void* context) {
     furi_hal_nfc_deactivate();
     nfc_worker_change_state(nfc_worker, NfcWorkerStateReady);
     furi_hal_power_insomnia_exit();
-    osThreadExit();
+
+    return 0;
 }
 
 void nfc_worker_detect(NfcWorker* nfc_worker) {

+ 2 - 3
applications/nfc/nfc_worker_i.h

@@ -17,8 +17,7 @@
 #include <st25r3916_irq.h>
 
 struct NfcWorker {
-    osThreadAttr_t thread_attr;
-    osThreadId_t thread;
+    FuriThread* thread;
 
     NfcDeviceData* dev_data;
 
@@ -30,7 +29,7 @@ struct NfcWorker {
 
 void nfc_worker_change_state(NfcWorker* nfc_worker, NfcWorkerState state);
 
-void nfc_worker_task(void* context);
+int32_t nfc_worker_task(void* context);
 
 void nfc_worker_read_emv_app(NfcWorker* nfc_worker);
 

+ 6 - 0
core/furi/memmgr_heap.c

@@ -288,6 +288,9 @@ static void print_heap_init() {
 static void print_heap_malloc(void* ptr, size_t size) {
     char tmp_str[33];
     const char* name = osThreadGetName(osThreadGetId());
+    if(!name) {
+        name = "";
+    }
 
     // {thread name|m|address|size}
     FURI_CRITICAL_ENTER();
@@ -306,6 +309,9 @@ static void print_heap_malloc(void* ptr, size_t size) {
 static void print_heap_free(void* ptr) {
     char tmp_str[33];
     const char* name = osThreadGetName(osThreadGetId());
+    if(!name) {
+        name = "";
+    }
 
     // {thread name|f|address}
     FURI_CRITICAL_ENTER();

+ 3 - 1
lib/FreeRTOS-glue/cmsis_os2.c

@@ -578,8 +578,10 @@ const char *osThreadGetName (osThreadId_t thread_id) {
 
   if ((IRQ_Context() != 0U) || (hTask == NULL)) {
     name = NULL;
-  } else {
+  } else if(osKernelGetState() == osKernelRunning) {
     name = pcTaskGetName (hTask);
+  } else {
+    name = NULL;
   }
 
   /* Return name as null-terminated string */