185 lines
3.8 KiB
C
185 lines
3.8 KiB
C
/*
|
|
* Copyright (c) 2018 Intel Corporation
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
#include <kernel_structs.h>
|
|
#include "wrapper.h"
|
|
|
|
K_MEM_SLAB_DEFINE(cv2_mutex_slab, sizeof(struct cv2_mutex),
|
|
CONFIG_CMSIS_V2_MUTEX_MAX_COUNT, 4);
|
|
|
|
static const osMutexAttr_t init_mutex_attrs = {
|
|
.name = "ZephyrMutex",
|
|
.attr_bits = osMutexPrioInherit,
|
|
.cb_mem = NULL,
|
|
.cb_size = 0,
|
|
};
|
|
|
|
/**
|
|
* @brief Create and Initialize a Mutex object.
|
|
*/
|
|
osMutexId_t osMutexNew(const osMutexAttr_t *attr)
|
|
{
|
|
struct cv2_mutex *mutex;
|
|
|
|
if (k_is_in_isr()) {
|
|
return NULL;
|
|
}
|
|
|
|
if (attr == NULL) {
|
|
attr = &init_mutex_attrs;
|
|
}
|
|
|
|
__ASSERT(attr->attr_bits & osMutexPrioInherit,
|
|
"Zephyr supports osMutexPrioInherit by default. Do not unselect it\n");
|
|
|
|
__ASSERT(!(attr->attr_bits & osMutexRobust),
|
|
"Zephyr does not support osMutexRobust.\n");
|
|
|
|
if (k_mem_slab_alloc(&cv2_mutex_slab, (void **)&mutex, 100) == 0) {
|
|
memset(mutex, 0, sizeof(struct cv2_mutex));
|
|
} else {
|
|
return NULL;
|
|
}
|
|
|
|
k_mutex_init(&mutex->z_mutex);
|
|
mutex->state = attr->attr_bits;
|
|
|
|
if (attr->name == NULL) {
|
|
strncpy(mutex->name, init_mutex_attrs.name,
|
|
sizeof(mutex->name) - 1);
|
|
} else {
|
|
strncpy(mutex->name, attr->name, sizeof(mutex->name) - 1);
|
|
}
|
|
|
|
return (osMutexId_t)mutex;
|
|
}
|
|
|
|
/**
|
|
* @brief Wait until a Mutex becomes available.
|
|
*/
|
|
osStatus_t osMutexAcquire(osMutexId_t mutex_id, uint32_t timeout)
|
|
{
|
|
struct cv2_mutex *mutex = (struct cv2_mutex *) mutex_id;
|
|
int status;
|
|
|
|
if (mutex_id == NULL) {
|
|
return osErrorParameter;
|
|
}
|
|
|
|
if (k_is_in_isr()) {
|
|
return osErrorISR;
|
|
}
|
|
|
|
if (mutex->z_mutex.lock_count == 0U ||
|
|
mutex->z_mutex.owner == _current) {
|
|
}
|
|
|
|
/* Throw an error if the mutex is not configured to be recursive and
|
|
* the current thread is trying to acquire the mutex again.
|
|
*/
|
|
if ((mutex->state & osMutexRecursive) == 0U) {
|
|
if ((mutex->z_mutex.owner == _current) &&
|
|
(mutex->z_mutex.lock_count != 0U)) {
|
|
return osErrorResource;
|
|
}
|
|
}
|
|
|
|
if (timeout == osWaitForever) {
|
|
status = k_mutex_lock(&mutex->z_mutex, K_FOREVER);
|
|
} else if (timeout == 0U) {
|
|
status = k_mutex_lock(&mutex->z_mutex, K_NO_WAIT);
|
|
} else {
|
|
status = k_mutex_lock(&mutex->z_mutex,
|
|
__ticks_to_ms(timeout));
|
|
}
|
|
|
|
if (status == -EBUSY) {
|
|
return osErrorResource;
|
|
} else if (status == -EAGAIN) {
|
|
return osErrorTimeout;
|
|
} else {
|
|
return osOK;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief Release a Mutex that was obtained by osMutexWait.
|
|
*/
|
|
osStatus_t osMutexRelease(osMutexId_t mutex_id)
|
|
{
|
|
struct cv2_mutex *mutex = (struct cv2_mutex *) mutex_id;
|
|
|
|
if (mutex_id == NULL) {
|
|
return osErrorParameter;
|
|
}
|
|
|
|
if (k_is_in_isr()) {
|
|
return osErrorISR;
|
|
}
|
|
|
|
/* Mutex was not obtained before or was not owned by current thread */
|
|
if ((mutex->z_mutex.lock_count == 0U) ||
|
|
(mutex->z_mutex.owner != _current)) {
|
|
return osErrorResource;
|
|
}
|
|
|
|
k_mutex_unlock(&mutex->z_mutex);
|
|
|
|
return osOK;
|
|
}
|
|
|
|
/**
|
|
* @brief Delete a Mutex that was created by osMutexCreate.
|
|
*/
|
|
osStatus_t osMutexDelete(osMutexId_t mutex_id)
|
|
{
|
|
struct cv2_mutex *mutex = (struct cv2_mutex *)mutex_id;
|
|
|
|
if (mutex_id == NULL) {
|
|
return osErrorParameter;
|
|
}
|
|
|
|
if (k_is_in_isr()) {
|
|
return osErrorISR;
|
|
}
|
|
|
|
/* The status code "osErrorResource" (mutex specified by parameter
|
|
* mutex_id is in an invalid mutex state) is not supported in Zephyr.
|
|
*/
|
|
|
|
k_mem_slab_free(&cv2_mutex_slab, (void *) &mutex);
|
|
|
|
return osOK;
|
|
}
|
|
|
|
|
|
osThreadId_t osMutexGetOwner(osMutexId_t mutex_id)
|
|
{
|
|
struct cv2_mutex *mutex = (struct cv2_mutex *)mutex_id;
|
|
|
|
if (k_is_in_isr() || (mutex == NULL)) {
|
|
return NULL;
|
|
}
|
|
|
|
/* Mutex was not obtained before */
|
|
if (mutex->z_mutex.lock_count == 0U) {
|
|
return NULL;
|
|
}
|
|
|
|
return get_cmsis_thread_id(mutex->z_mutex.owner);
|
|
}
|
|
|
|
const char *osMutexGetName(osMutexId_t mutex_id)
|
|
{
|
|
struct cv2_mutex *mutex = (struct cv2_mutex *)mutex_id;
|
|
|
|
if (k_is_in_isr() || (mutex == NULL)) {
|
|
return NULL;
|
|
}
|
|
|
|
return mutex->name;
|
|
}
|