| /* |
| * Copyright (c) 2018 Intel Corporation |
| * |
| * SPDX-License-Identifier: Apache-2.0 |
| */ |
| |
| #include <kernel.h> |
| #include <string.h> |
| #include "wrapper.h" |
| |
| K_MEM_SLAB_DEFINE(cv2_semaphore_slab, sizeof(struct cv2_sem), |
| CONFIG_CMSIS_V2_SEMAPHORE_MAX_COUNT, 4); |
| |
| static const osSemaphoreAttr_t init_sema_attrs = { |
| .name = "ZephyrSem", |
| .attr_bits = 0, |
| .cb_mem = NULL, |
| .cb_size = 0, |
| }; |
| |
| /** |
| * @brief Create and Initialize a semaphore object. |
| */ |
| osSemaphoreId_t osSemaphoreNew(uint32_t max_count, uint32_t initial_count, |
| const osSemaphoreAttr_t *attr) |
| { |
| struct cv2_sem *semaphore; |
| |
| if (k_is_in_isr()) { |
| return NULL; |
| } |
| |
| if (attr == NULL) { |
| attr = &init_sema_attrs; |
| } |
| |
| if (k_mem_slab_alloc(&cv2_semaphore_slab, |
| (void **)&semaphore, K_MSEC(100)) == 0) { |
| (void)memset(semaphore, 0, sizeof(struct cv2_sem)); |
| } else { |
| return NULL; |
| } |
| |
| k_sem_init(&semaphore->z_semaphore, initial_count, max_count); |
| |
| if (attr->name == NULL) { |
| strncpy(semaphore->name, init_sema_attrs.name, |
| sizeof(semaphore->name) - 1); |
| } else { |
| strncpy(semaphore->name, attr->name, |
| sizeof(semaphore->name) - 1); |
| } |
| |
| return (osSemaphoreId_t)semaphore; |
| } |
| |
| /** |
| * @brief Wait until a semaphore becomes available. |
| */ |
| osStatus_t osSemaphoreAcquire(osSemaphoreId_t semaphore_id, uint32_t timeout) |
| { |
| struct cv2_sem *semaphore = (struct cv2_sem *) semaphore_id; |
| int status; |
| |
| if (semaphore_id == NULL) { |
| return osErrorParameter; |
| } |
| |
| /* Can be called from ISRs only if timeout is set to 0 */ |
| if (timeout > 0 && k_is_in_isr()) { |
| return osErrorParameter; |
| } |
| |
| if (timeout == osWaitForever) { |
| status = k_sem_take(&semaphore->z_semaphore, K_FOREVER); |
| } else if (timeout == 0U) { |
| status = k_sem_take(&semaphore->z_semaphore, K_NO_WAIT); |
| } else { |
| status = k_sem_take(&semaphore->z_semaphore, |
| K_TICKS(timeout)); |
| } |
| |
| if (status == -EBUSY) { |
| return osErrorResource; |
| } else if (status == -EAGAIN) { |
| return osErrorTimeout; |
| } else { |
| return osOK; |
| } |
| } |
| |
| uint32_t osSemaphoreGetCount(osSemaphoreId_t semaphore_id) |
| { |
| struct cv2_sem *semaphore = (struct cv2_sem *)semaphore_id; |
| |
| if (semaphore_id == NULL) { |
| return 0; |
| } |
| |
| return k_sem_count_get(&semaphore->z_semaphore); |
| } |
| |
| /** |
| * @brief Release a semaphore that was obtained by osSemaphoreWait. |
| */ |
| osStatus_t osSemaphoreRelease(osSemaphoreId_t semaphore_id) |
| { |
| struct cv2_sem *semaphore = (struct cv2_sem *) semaphore_id; |
| |
| if (semaphore_id == NULL) { |
| return osErrorParameter; |
| } |
| |
| /* All tokens have already been released */ |
| if (k_sem_count_get(&semaphore->z_semaphore) == |
| semaphore->z_semaphore.limit) { |
| return osErrorResource; |
| } |
| |
| k_sem_give(&semaphore->z_semaphore); |
| |
| return osOK; |
| } |
| |
| /** |
| * @brief Delete a semaphore that was created by osSemaphoreCreate. |
| */ |
| osStatus_t osSemaphoreDelete(osSemaphoreId_t semaphore_id) |
| { |
| struct cv2_sem *semaphore = (struct cv2_sem *)semaphore_id; |
| |
| if (semaphore_id == NULL) { |
| return osErrorParameter; |
| } |
| |
| if (k_is_in_isr()) { |
| return osErrorISR; |
| } |
| |
| /* The status code "osErrorResource" (the semaphore specified by |
| * parameter semaphore_id is in an invalid semaphore state) is not |
| * supported in Zephyr. |
| */ |
| |
| k_mem_slab_free(&cv2_semaphore_slab, (void *) &semaphore); |
| |
| return osOK; |
| } |
| |
| const char *osSemaphoreGetName(osSemaphoreId_t semaphore_id) |
| { |
| struct cv2_sem *semaphore = (struct cv2_sem *)semaphore_id; |
| |
| if (!k_is_in_isr() && (semaphore_id != NULL)) { |
| return semaphore->name; |
| } else { |
| return NULL; |
| } |
| } |