mirror of
https://github.com/zephyrproject-rtos/zephyr
synced 2025-08-09 16:40:08 +00:00
Fixed an issue whereby if an attribute structure was passed into a CMSIS RTOS v2 'new' function with an invalid address i.e. NULL assigned to the name (char*) member the memcpy at the end of each new function would cause a segmentation fault i.e. read from an invalid address. This has been fixed by checking if the name is NULL and using the default name from the init struct if it is. This is the same name that would be used if not passing in the optional attr function argument. Changed the memcpy to strncpy to ensure that the copy does not read beyond the end of the source string and changed the length from 16 to 15 (by means of a `sizeof(...)-1`) of the destination buffer to ensure that it will always be nul-terminated. Signed-off-by: Carlos Stuart <carlosstuart1970@gmail.com>
177 lines
3.3 KiB
C
177 lines
3.3 KiB
C
/*
|
|
* Copyright (c) 2018 Intel Corporation
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
#include <kernel_structs.h>
|
|
#include "wrapper.h"
|
|
|
|
#define ACTIVE 1
|
|
#define NOT_ACTIVE 0
|
|
|
|
static void zephyr_timer_wrapper(struct k_timer *timer);
|
|
|
|
K_MEM_SLAB_DEFINE(cv2_timer_slab, sizeof(struct cv2_timer),
|
|
CONFIG_CMSIS_V2_TIMER_MAX_COUNT, 4);
|
|
|
|
static const osTimerAttr_t init_timer_attrs = {
|
|
.name = "ZephyrTimer",
|
|
.attr_bits = 0,
|
|
.cb_mem = NULL,
|
|
.cb_size = 0,
|
|
};
|
|
|
|
static void zephyr_timer_wrapper(struct k_timer *timer)
|
|
{
|
|
struct cv2_timer *cm_timer;
|
|
|
|
cm_timer = CONTAINER_OF(timer, struct cv2_timer, z_timer);
|
|
(cm_timer->callback_function)(cm_timer->arg);
|
|
}
|
|
|
|
/**
|
|
* @brief Create a Timer
|
|
*/
|
|
osTimerId_t osTimerNew(osTimerFunc_t func, osTimerType_t type,
|
|
void *argument, const osTimerAttr_t *attr)
|
|
{
|
|
struct cv2_timer *timer;
|
|
|
|
if (type != osTimerOnce && type != osTimerPeriodic) {
|
|
return NULL;
|
|
}
|
|
|
|
if (k_is_in_isr()) {
|
|
return NULL;
|
|
}
|
|
|
|
if (attr == NULL) {
|
|
attr = &init_timer_attrs;
|
|
}
|
|
|
|
if (k_mem_slab_alloc(&cv2_timer_slab, (void **)&timer, 100) == 0) {
|
|
(void)memset(timer, 0, sizeof(struct cv2_timer));
|
|
} else {
|
|
return NULL;
|
|
}
|
|
|
|
timer->callback_function = func;
|
|
timer->arg = argument;
|
|
timer->type = type;
|
|
timer->status = NOT_ACTIVE;
|
|
|
|
k_timer_init(&timer->z_timer, zephyr_timer_wrapper, NULL);
|
|
|
|
if (attr->name == NULL) {
|
|
strncpy(timer->name, init_timer_attrs.name,
|
|
sizeof(timer->name) - 1);
|
|
} else {
|
|
strncpy(timer->name, attr->name, sizeof(timer->name) - 1);
|
|
}
|
|
|
|
return (osTimerId_t)timer;
|
|
}
|
|
|
|
/**
|
|
* @brief Start or restart a Timer
|
|
*/
|
|
osStatus_t osTimerStart(osTimerId_t timer_id, uint32_t ticks)
|
|
{
|
|
struct cv2_timer *timer = (struct cv2_timer *)timer_id;
|
|
u32_t millisec = __ticks_to_ms(ticks);
|
|
|
|
if (timer == NULL) {
|
|
return osErrorParameter;
|
|
}
|
|
|
|
if (k_is_in_isr()) {
|
|
return osErrorISR;
|
|
}
|
|
|
|
if (timer->type == osTimerOnce) {
|
|
k_timer_start(&timer->z_timer, millisec, 0);
|
|
} else if (timer->type == osTimerPeriodic) {
|
|
k_timer_start(&timer->z_timer, 0, millisec);
|
|
}
|
|
|
|
timer->status = ACTIVE;
|
|
return osOK;
|
|
}
|
|
|
|
/**
|
|
* @brief Stop the Timer
|
|
*/
|
|
osStatus_t osTimerStop(osTimerId_t timer_id)
|
|
{
|
|
struct cv2_timer *timer = (struct cv2_timer *)timer_id;
|
|
|
|
if (timer == NULL) {
|
|
return osErrorParameter;
|
|
}
|
|
|
|
if (k_is_in_isr()) {
|
|
return osErrorISR;
|
|
}
|
|
|
|
if (timer->status == NOT_ACTIVE) {
|
|
return osErrorResource;
|
|
}
|
|
|
|
k_timer_stop(&timer->z_timer);
|
|
timer->status = NOT_ACTIVE;
|
|
return osOK;
|
|
}
|
|
|
|
/**
|
|
* @brief Delete the timer that was created by osTimerCreate
|
|
*/
|
|
osStatus_t osTimerDelete(osTimerId_t timer_id)
|
|
{
|
|
struct cv2_timer *timer = (struct cv2_timer *) timer_id;
|
|
|
|
if (timer == NULL) {
|
|
return osErrorParameter;
|
|
}
|
|
|
|
if (k_is_in_isr()) {
|
|
return osErrorISR;
|
|
}
|
|
|
|
if (timer->status == ACTIVE) {
|
|
k_timer_stop(&timer->z_timer);
|
|
timer->status = NOT_ACTIVE;
|
|
}
|
|
|
|
k_mem_slab_free(&cv2_timer_slab, (void *) &timer);
|
|
return osOK;
|
|
}
|
|
|
|
/**
|
|
* @brief Get name of a timer.
|
|
*/
|
|
const char *osTimerGetName(osTimerId_t timer_id)
|
|
{
|
|
struct cv2_timer *timer = (struct cv2_timer *)timer_id;
|
|
|
|
if (k_is_in_isr() || (timer == NULL)) {
|
|
return NULL;
|
|
}
|
|
|
|
return timer->name;
|
|
}
|
|
|
|
/**
|
|
* @brief Check if a timer is running.
|
|
*/
|
|
uint32_t osTimerIsRunning(osTimerId_t timer_id)
|
|
{
|
|
struct cv2_timer *timer = (struct cv2_timer *)timer_id;
|
|
|
|
if (k_is_in_isr() || (timer == NULL)) {
|
|
return 0;
|
|
}
|
|
|
|
return !(!(k_timer_remaining_get(&timer->z_timer)));
|
|
}
|