FreeRTOS app bug fix.

Change-Id: Ic0a900c29f0ff24a7505ff952f326643c1bff5c0
diff --git a/applications/freertos/main.cpp b/applications/freertos/main.cpp
index 1c1821d..ae4bc38 100644
--- a/applications/freertos/main.cpp
+++ b/applications/freertos/main.cpp
@@ -21,6 +21,7 @@
  ****************************************************************************/
 
 #include "FreeRTOS.h"
+#include "portmacro.h"
 #include "queue.h"
 #include "semphr.h"
 #include "task.h"
@@ -120,31 +121,60 @@
 extern "C" {
 
 void *ethosu_mutex_create(void) {
-    return xSemaphoreCreateMutex();
+    SemaphoreHandle_t sem = xSemaphoreCreateMutex();
+    if (sem == NULL) {
+        printf("Error: Failed to create mutex.\n");
+    }
+    return (void *)sem;
 }
 
 void ethosu_mutex_lock(void *mutex) {
     SemaphoreHandle_t handle = reinterpret_cast<SemaphoreHandle_t>(mutex);
-    xSemaphoreTake(handle, portMAX_DELAY);
+    if (xSemaphoreTake(handle, portMAX_DELAY) != pdTRUE) {
+        printf("Error: Failed to lock mutex.\n");
+    }
 }
 
 void ethosu_mutex_unlock(void *mutex) {
     SemaphoreHandle_t handle = reinterpret_cast<SemaphoreHandle_t>(mutex);
-    xSemaphoreGive(handle);
+    if (xSemaphoreGive(handle) != pdTRUE) {
+        printf("Error: Failed to unlock mutex.\n");
+    }
 }
 
 void *ethosu_semaphore_create(void) {
-    return xSemaphoreCreateBinary();
+    SemaphoreHandle_t sem = xSemaphoreCreateBinary();
+    if (sem == NULL) {
+        printf("Error: Failed to create semaphore.\n");
+    }
+    return (void *)sem;
 }
 
 void ethosu_semaphore_take(void *sem) {
     SemaphoreHandle_t handle = reinterpret_cast<SemaphoreHandle_t>(sem);
-    xSemaphoreTake(handle, portMAX_DELAY);
+    if (xSemaphoreTake(handle, portMAX_DELAY) != pdTRUE) {
+        printf("Error: Failed to take semaphore.\n");
+    }
 }
 
 void ethosu_semaphore_give(void *sem) {
     SemaphoreHandle_t handle = reinterpret_cast<SemaphoreHandle_t>(sem);
-    xSemaphoreGive(handle);
+    BaseType_t ret;
+
+    if (xPortIsInsideInterrupt()) {
+        ret = xSemaphoreGiveFromISR(handle, NULL);
+        if (ret != pdTRUE) {
+            printf("Error: Failed to give semaphore from ISR. ret - 0x%08x\n", ret);
+        }
+    } else {
+        ret = xSemaphoreGive(handle);
+        if (ret != pdTRUE) {
+            /* The next line is in comment because xSemaphoreGive returns pdFAIL when
+               calling it twice in a row during this application run.
+               This failure doesn't affect the final result of the FreeRTOS application. */
+            /* printf("Error: Failed to give semaphore. ret - 0x%08x\n", ret); */
+        }
+    }
 }
 }
 
@@ -161,10 +191,17 @@
     for (;;) {
         xInferenceJob *xJob;
 
-        xQueueReceive(params.queueHandle, &xJob, portMAX_DELAY);
+        if (xQueueReceive(params.queueHandle, &xJob, portMAX_DELAY) != pdPASS) {
+            printf("Error: inferenceProcessTask failed in receive from Q.\n");
+            exit(1);
+        }
+
         bool status  = inferenceProcess.runJob(*xJob);
         xJob->status = status;
-        xQueueSend(xJob->responseQueue, &xJob, portMAX_DELAY);
+        if (xQueueSend(xJob->responseQueue, &xJob, portMAX_DELAY) != pdPASS) {
+            printf("Error: inferenceProcessTask failed in send to Q.\n");
+            exit(1);
+        }
     }
     vTaskDelete(nullptr);
 }
@@ -189,14 +226,20 @@
         job->expectedOutput.push_back(DataPtr(expectedOutputData, sizeof(expectedOutputData)));
         job->responseQueue = senderQueue;
         // Send job
-        printf("Sending inference job: job=%p, name=%s\n", job, job->name.c_str());
-        xQueueSend(inferenceProcessQueue, &job, portMAX_DELAY);
+        printf("inferenceSenderTask: Sending inference job: job=%p, name=%s\n", job, job->name.c_str());
+        if (xQueueSend(inferenceProcessQueue, &job, portMAX_DELAY) != pdPASS) {
+            printf("Error: inferenceSenderTask failed in send to Q.\n");
+            exit(1);
+        }
     }
 
     // Listen for completion status
     do {
         xInferenceJob *pSendJob;
-        xQueueReceive(senderQueue, &pSendJob, portMAX_DELAY);
+        if (xQueueReceive(senderQueue, &pSendJob, portMAX_DELAY) != pdPASS) {
+            printf("Error: inferenceSenderTask failed in receive from Q.\n");
+            exit(1);
+        }
         printf("inferenceSenderTask: received response for job: %s, status = %u\n",
                pSendJob->name.c_str(),
                pSendJob->status);
@@ -226,7 +269,7 @@
     for (int n = 0; n < NUM_JOB_TASKS; n++) {
         ret = xTaskCreate(inferenceSenderTask, "inferenceSenderTask", 2 * 1024, inferenceProcessQueue, 2, nullptr);
         if (ret != pdPASS) {
-            printf("FreeRTOS: Failed to create 'inferenceSenderTask%i'\n", n);
+            printf("Error: Failed to create 'inferenceSenderTask%i'\n", n);
             exit(1);
         }
     }
@@ -236,7 +279,7 @@
         taskParams[n] = ProcessTaskParams(inferenceProcessQueue, inferenceProcessTensorArena[n], arenaSize);
         ret           = xTaskCreate(inferenceProcessTask, "inferenceProcessTask", 8 * 1024, &taskParams[n], 3, nullptr);
         if (ret != pdPASS) {
-            printf("FreeRTOS: Failed to create 'inferenceProcessTask%i'\n", n);
+            printf("Error: Failed to create 'inferenceProcessTask%i'\n", n);
             exit(1);
         }
     }
@@ -244,7 +287,7 @@
     // Start Scheduler
     vTaskStartScheduler();
 
-    printf("FreeRTOS application failed to initialise \n");
+    printf("Error: FreeRTOS application failed to initialise.\n");
     exit(1);
 
     return 0;