Implemented semaphore API.

Signed-off-by: Yilin Sun <imi415@imi.moe>
This commit is contained in:
Yilin Sun 2022-12-10 22:57:33 +08:00
parent 291629b05d
commit ece0f2abfb
Signed by: imi415
GPG Key ID: 17F01E106F9F5E0A
1 changed files with 74 additions and 5 deletions

View File

@ -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;
}