/* * Copyright (c) 2018 Intel Corporation * * SPDX-License-Identifier: Apache-2.0 */ #include #include #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; } }