forked from zephyrproject-rtos/zephyr
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtimer.c
177 lines (140 loc) · 3.33 KB
/
timer.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
/*
* Copyright (c) 2018 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <kernel.h>
#include <string.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, K_MSEC(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;
if (timer == NULL) {
return osErrorParameter;
}
if (k_is_in_isr()) {
return osErrorISR;
}
if (timer->type == osTimerOnce) {
k_timer_start(&timer->z_timer, K_TICKS(ticks), K_NO_WAIT);
} else if (timer->type == osTimerPeriodic) {
k_timer_start(&timer->z_timer,
K_TICKS(ticks), K_TICKS(ticks));
}
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)));
}