diff --git a/src/whd_port/rtos/cyabs_rtos.c b/src/whd_port/rtos/cyabs_rtos.c index 944488d..8e7325f 100644 --- a/src/whd_port/rtos/cyabs_rtos.c +++ b/src/whd_port/rtos/cyabs_rtos.c @@ -10,9 +10,9 @@ * so we have to implement the 'join' function with a binary semaphore. * The task being signalled to stop will release the semaphore right before the task is deleted, * then we can 'join' the task by simply wait for the semaphore to be given. - * This semaphore is created along with the new task, and is deleted within 'join' function, + * This semaphore is created along with the new task, and is deleted within 'join' function, * and the handle of the semaphore is stored in the Thread Local Storage (TLS) of the target task. - * + * */ #define CY_RTOS_JOIN_SEMPHR_TLS_ID 0 @@ -54,7 +54,8 @@ cy_rslt_t cy_rtos_exit_thread(void) { } cy_rslt_t cy_rtos_terminate_thread(cy_thread_t *thread) { - /* Empty function, thread resource will be released after task function returns. */ + /* Empty function, thread resource will be released after task function joined. */ + /* WARNING: Current WHD drivers does not call this function. LEAVE IT BLANK FOR NOW. */ return CY_RSLT_SUCCESS; } @@ -65,13 +66,81 @@ cy_rslt_t cy_rtos_join_thread(cy_thread_t *thread) { thr_join_semaphore = pvTaskGetThreadLocalStoragePointer((TaskHandle_t)*thread, CY_RTOS_JOIN_SEMPHR_TLS_ID); /* Wait until the target task exit */ - if(xSemaphoreTake(thr_join_semaphore, portMAX_DELAY) != pdPASS) { + if (xSemaphoreTake(thr_join_semaphore, portMAX_DELAY) != pdPASS) { /* Really unexpected */ return CY_RTOS_GENERAL_ERROR; } - /* Delete the semaphore here. */ + /* Delete the semaphore here. See the comments of `cy_rtos_terminate_thread` above! */ vSemaphoreDelete(thr_join_semaphore); + return CY_RSLT_SUCCESS; +} + +cy_rslt_t cy_rtos_init_semaphore(cy_semaphore_t *semaphore, uint32_t maxcount, uint32_t initcount) { + *semaphore = (cy_semaphore_t)xSemaphoreCreateCounting(maxcount, initcount); + if (*semaphore == NULL) { + return CY_RTOS_NO_MEMORY; + } + + return CY_RSLT_SUCCESS; +} + +cy_rslt_t cy_rtos_get_semaphore(cy_semaphore_t *semaphore, cy_time_t timeout_ms, bool in_isr) { + BaseType_t higher_priority_woken = pdFALSE; + + if(!in_isr) { + if(xSemaphoreTake(*semaphore, pdMS_TO_TICKS(timeout_ms)) != pdPASS) { + return CY_RTOS_TIMEOUT; + } + } + else { /* Currently is not used */ + if(xSemaphoreTakeFromISR(*semaphore, &higher_priority_woken) != pdPASS) { + return CY_RTOS_TIMEOUT; + } + if(higher_priority_woken != pdFALSE) { + taskYIELD(); + } + } + + return CY_RSLT_SUCCESS; +} + +cy_rslt_t cy_rtos_set_semaphore(cy_semaphore_t *semaphore, bool in_isr) { + BaseType_t higher_priority_woken = pdFALSE; + + if(!in_isr) { + /* + * Since the semaphores are implemented using queues, this call will also fail if the queue is full. + * So do not check return values here. + */ + xSemaphoreGive(*semaphore); + } + else { + /* For the same reason as above, do not check return values here. */ + xSemaphoreGiveFromISR(*semaphore, &higher_priority_woken); + if(higher_priority_woken != pdFALSE) { + taskYIELD(); + } + } + + return CY_RSLT_SUCCESS; +} + +cy_rslt_t cy_rtos_deinit_semaphore(cy_semaphore_t *semaphore) { + vSemaphoreDelete(*semaphore); + + return CY_RSLT_SUCCESS; +} + +cy_rslt_t cy_rtos_get_time(cy_time_t *tval) { + *tval = xTaskGetTickCount(); + + return CY_RSLT_SUCCESS; +} + +cy_rslt_t cy_rtos_delay_milliseconds(cy_time_t num_ms) { + vTaskDelay(pdMS_TO_TICKS(num_ms)); + return CY_RSLT_SUCCESS; } \ No newline at end of file