Skip to content

Commit

Permalink
lib/cmsis_rtos_v1: Implement support for semaphore APIs
Browse files Browse the repository at this point in the history
These APIs allow creating, acquiring, releasing and deleting
of semaphores.

Signed-off-by: Rajavardhan Gundi <rajavardhan.gundi@intel.com>
  • Loading branch information
rgundi authored and nashif committed Aug 13, 2018
1 parent a76556a commit 45e6715
Show file tree
Hide file tree
Showing 3 changed files with 130 additions and 0 deletions.
1 change: 1 addition & 0 deletions lib/cmsis_rtos_v1/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ zephyr_library_sources_ifdef(
cmsis_kernel.c
cmsis_timer.c
cmsis_mutex.c
cmsis_semaphore.c
)

zephyr_library_link_libraries(CMSIS)
Expand Down
8 changes: 8 additions & 0 deletions lib/cmsis_rtos_v1/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,14 @@ config CMSIS_MUTEX_MAX_COUNT
help
Mention maximum number of mutexes in CMSIS compliant application.

config CMSIS_SEMAPHORE_MAX_COUNT
int
prompt "Maximum semaphore count in CMSIS application"
default 5
range 0 255
help
Mention maximum number of semaphores in CMSIS compliant application.

config NUM_PREEMPT_PRIORITIES
int
default 7
Expand Down
121 changes: 121 additions & 0 deletions lib/cmsis_rtos_v1/cmsis_semaphore.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
/*
* Copyright (c) 2018 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <kernel_structs.h>
#include <cmsis_os.h>

K_MEM_SLAB_DEFINE(cmsis_semaphore_slab, sizeof(struct k_sem),
CONFIG_CMSIS_SEMAPHORE_MAX_COUNT, 4);

/**
* @brief Create and Initialize a semaphore object.
*/
osSemaphoreId osSemaphoreCreate(const osSemaphoreDef_t *semaphore_def,
int32_t count)
{
struct k_sem *semaphore;

if (semaphore_def == NULL) {
return NULL;
}

if (_is_in_isr()) {
return NULL;
}

if (k_mem_slab_alloc(&cmsis_semaphore_slab,
(void **)&semaphore, 100) == 0) {
memset(semaphore, 0, sizeof(struct k_sem));
} else {
return NULL;
}

k_sem_init(semaphore, count, count);

return (osSemaphoreId)semaphore;
}

/**
* @brief Wait until a semaphore becomes available.
*/
int32_t osSemaphoreWait(osSemaphoreId semaphore_id, uint32_t timeout)
{
struct k_sem *semaphore = (struct k_sem *) semaphore_id;
int status;

if (semaphore_id == NULL) {
return -1;
}

if (_is_in_isr()) {
return -1;
}

if (timeout == osWaitForever) {
status = k_sem_take(semaphore, K_FOREVER);
} else if (timeout == 0) {
status = k_sem_take(semaphore, K_NO_WAIT);
} else {
status = k_sem_take(semaphore, timeout);
}

/* If k_sem_take is successful, return the number of available
* tokens + 1. +1 is for accounting the currently acquired token.
* If it has timed out, return 0 (no tokens available).
*/
if (status == 0) {
return k_sem_count_get(semaphore) + 1;
} else if (status == -EAGAIN) {
return 0;
}

return -1;
}

/**
* @brief Release a semaphore that was obtained by osSemaphoreWait.
*/
osStatus osSemaphoreRelease(osSemaphoreId semaphore_id)
{
struct k_sem *semaphore = (struct k_sem *) semaphore_id;

if (semaphore_id == NULL) {
return osErrorParameter;
}

/* All tokens have already been released */
if (k_sem_count_get(semaphore) == semaphore->limit) {
return osErrorResource;
}

k_sem_give(semaphore);

return osOK;
}

/**
* @brief Delete a semaphore that was created by osSemaphoreCreate.
*/
osStatus osSemaphoreDelete(osSemaphoreId semaphore_id)
{
struct k_sem *semaphore = (struct k_sem *) semaphore_id;

if (semaphore_id == NULL) {
return osErrorParameter;
}

if (_is_in_isr()) {
return osErrorISR;
}

/* The status code "osErrorResource" (the semaphore object
* could not be deleted) is not supported in Zephyr.
*/

k_mem_slab_free(&cmsis_semaphore_slab, (void *) &semaphore);

return osOK;
}

0 comments on commit 45e6715

Please sign in to comment.