• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements.  See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership.  The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the
7  * "License"); you may not use this file except in compliance
8  * with the License.  You may obtain a copy of the License at
9  *
10  *  http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing,
13  * software distributed under the License is distributed on an
14  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15  * KIND, either express or implied.  See the License for the
16  * specific language governing permissions and limitations
17  * under the License.
18  */
19 
20 #include <assert.h>
21 #include <stddef.h>
22 #include <string.h>
23 #include "securec.h"
24 #include "nimble/nimble_npl.h"
25 #include "wm_osal.h"
26 
npl_freertos_eventq_get(struct ble_npl_eventq * evq,ble_npl_time_t tmo)27 struct ble_npl_event *npl_freertos_eventq_get(struct ble_npl_eventq *evq, ble_npl_time_t tmo)
28 {
29     struct ble_npl_event *ev = NULL;
30     tls_os_status_t status;
31     status = tls_os_queue_receive(evq->q, (void **)&ev, sizeof(ev), tmo);
32     if (status == TLS_OS_SUCCESS) {
33     if (ev) {
34         ev->queued = false;
35     }
36     }
37 
38     return ev;
39 }
40 
npl_freertos_eventq_put(struct ble_npl_eventq * evq,struct ble_npl_event * ev)41 void npl_freertos_eventq_put(struct ble_npl_eventq *evq, struct ble_npl_event *ev)
42 {
43     tls_os_status_t status;
44 
45     if (ev->queued) {
46         return;
47     }
48 
49     ev->queued = true;
50     status = tls_os_queue_send(evq->q, ev, sizeof(ev));
51     assert(status == TLS_OS_SUCCESS);
52 }
53 
npl_freertos_eventq_remove(struct ble_npl_eventq * evq,struct ble_npl_event * ev)54 void npl_freertos_eventq_remove(struct ble_npl_eventq *evq, struct ble_npl_event *ev)
55 {
56     tls_os_status_t status;
57 
58     if (!ev->queued) {
59         return;
60     }
61 
62     status = tls_os_queue_remove(evq->q, ev, sizeof(ev));
63     assert(status == TLS_OS_SUCCESS);
64     ev->queued = 0;
65 }
66 
npl_freertos_mutex_init(struct ble_npl_mutex * mu)67 ble_npl_error_t npl_freertos_mutex_init(struct ble_npl_mutex *mu)
68 {
69     tls_os_status_t status;
70 
71     if (!mu) {
72         return BLE_NPL_INVALID_PARAM;
73     }
74 
75     status = tls_os_mutex_create(0, &mu->handle);
76     assert(status == TLS_OS_SUCCESS);
77     assert(mu->handle);
78     return BLE_NPL_OK;
79 }
80 
npl_freertos_mutex_deinit(struct ble_npl_mutex * mu)81 ble_npl_error_t npl_freertos_mutex_deinit(struct ble_npl_mutex *mu)
82 {
83     tls_os_status_t status;
84 
85     if (!mu) {
86         return BLE_NPL_INVALID_PARAM;
87     }
88 
89     if (mu->handle) {
90         status = tls_os_mutex_delete(mu->handle);
91         assert(status == TLS_OS_SUCCESS);
92     }
93 
94     return BLE_NPL_OK;
95 }
96 
npl_freertos_mutex_pend(struct ble_npl_mutex * mu,ble_npl_time_t timeout)97 ble_npl_error_t npl_freertos_mutex_pend(struct ble_npl_mutex *mu, ble_npl_time_t timeout)
98 {
99     tls_os_status_t status;
100 
101     if (!mu) {
102         return BLE_NPL_INVALID_PARAM;
103     }
104 
105     assert(mu->handle);
106 
107     if (tls_get_isr_count() > 0) {
108         status = TLS_OS_ERROR;
109         assert(0);
110     } else {
111         status = tls_os_mutex_acquire(mu->handle, timeout);
112     }
113 
114     return status == TLS_OS_SUCCESS ? BLE_NPL_OK : BLE_NPL_TIMEOUT;
115 }
116 
npl_freertos_mutex_release(struct ble_npl_mutex * mu)117 ble_npl_error_t npl_freertos_mutex_release(struct ble_npl_mutex *mu)
118 {
119     tls_os_status_t status;
120 
121     if (!mu) {
122         return BLE_NPL_INVALID_PARAM;
123     }
124 
125     assert(mu->handle);
126 
127     if (tls_get_isr_count() > 0) {
128         assert(0);
129     } else {
130         status = tls_os_mutex_release(mu->handle);
131         if (status != TLS_OS_SUCCESS) {
132             return BLE_NPL_BAD_MUTEX;
133         }
134     }
135 
136     return BLE_NPL_OK;
137 }
138 
npl_freertos_sem_init(struct ble_npl_sem * sem,uint16_t tokens)139 ble_npl_error_t npl_freertos_sem_init(struct ble_npl_sem *sem, uint16_t tokens)
140 {
141     tls_os_status_t status;
142 
143     if (!sem) {
144         return BLE_NPL_INVALID_PARAM;
145     }
146 
147     status = tls_os_sem_create(&sem->handle, tokens);
148     assert(status == TLS_OS_SUCCESS);
149     assert(sem->handle);
150     return BLE_NPL_OK;
151 }
npl_freertos_sem_deinit(struct ble_npl_sem * sem)152 ble_npl_error_t npl_freertos_sem_deinit(struct ble_npl_sem *sem)
153 {
154     tls_os_status_t status;
155 
156     if (!sem) {
157         return BLE_NPL_INVALID_PARAM;
158     }
159 
160     if (sem->handle) {
161         status = tls_os_sem_delete(sem->handle);
162         assert(status == TLS_OS_SUCCESS);
163     }
164 
165     return BLE_NPL_OK;
166 }
167 
npl_freertos_sem_pend(struct ble_npl_sem * sem,ble_npl_time_t timeout)168 ble_npl_error_t npl_freertos_sem_pend(struct ble_npl_sem *sem, ble_npl_time_t timeout)
169 {
170     tls_os_status_t status;
171 
172     if (!sem) {
173         return BLE_NPL_INVALID_PARAM;
174     }
175 
176     assert(sem->handle);
177     status = tls_os_sem_acquire(sem->handle, timeout);
178     return status == TLS_OS_SUCCESS ? BLE_NPL_OK : BLE_NPL_TIMEOUT;
179 }
npl_freertos_get_sem_count(struct ble_npl_sem * sem)180 uint16_t npl_freertos_get_sem_count(struct ble_npl_sem *sem)
181 {
182     if (!sem) {
183         return BLE_NPL_INVALID_PARAM;
184     }
185 
186     assert(sem->handle);
187     return (uint16_t)tls_os_sem_get_count(sem->handle);
188 }
189 
npl_freertos_sem_release(struct ble_npl_sem * sem)190 ble_npl_error_t npl_freertos_sem_release(struct ble_npl_sem *sem)
191 {
192     tls_os_status_t status;
193 
194     if (!sem) {
195         return BLE_NPL_INVALID_PARAM;
196     }
197 
198     assert(sem->handle);
199     status = tls_os_sem_release(sem->handle);
200     assert(status == TLS_OS_SUCCESS);
201     return BLE_NPL_OK;
202 }
os_callout_timer_cb(void * ptmr,void * parg)203 static void os_callout_timer_cb(void *ptmr, void *parg)
204 {
205     struct ble_npl_callout *co;
206     co = (struct ble_npl_callout *)parg;
207     if (co->evq) {
208         ble_npl_eventq_put(co->evq, &co->ev);
209     } else {
210         co->ev.fn(&co->ev);
211     }
212 }
213 
npl_freertos_callout_init(struct ble_npl_callout * co,struct ble_npl_eventq * evq,ble_npl_event_fn * ev_cb,void * ev_arg)214 void npl_freertos_callout_init(struct ble_npl_callout *co, struct ble_npl_eventq *evq,
215                                ble_npl_event_fn *ev_cb, void *ev_arg)
216 {
217     tls_os_status_t status;
218     memset_s(co, sizeof(*co), 0, sizeof(*co));
219     status = tls_os_timer_create(&co->handle, os_callout_timer_cb, (void *)co, 1, 0, (u8 *)"co");
220     assert(status == TLS_OS_SUCCESS);
221     co->evq = evq;
222     ble_npl_event_init(&co->ev, ev_cb, ev_arg);
223 }
224 
npl_freertos_callout_reset(struct ble_npl_callout * co,ble_npl_time_t ticks)225 ble_npl_error_t npl_freertos_callout_reset(struct ble_npl_callout *co, ble_npl_time_t ticks)
226 {
227     tls_os_timer_change(co->handle, ticks);
228     return BLE_NPL_OK;
229 }
230 
npl_freertos_callout_remaining_ticks(struct ble_npl_callout * co,ble_npl_time_t now)231 ble_npl_time_t npl_freertos_callout_remaining_ticks(struct ble_npl_callout *co, ble_npl_time_t now)
232 {
233     ble_npl_time_t rt;
234     uint32_t exp;
235     exp = tls_os_timer_expirytime(co->handle);
236     if (exp > now) {
237         rt = exp - now;
238     } else {
239         rt = 0;
240     }
241 
242     return rt;
243 }
244 
npl_freertos_time_ms_to_ticks(uint32_t ms,ble_npl_time_t * out_ticks)245 ble_npl_error_t npl_freertos_time_ms_to_ticks(uint32_t ms, ble_npl_time_t *out_ticks)
246 {
247     uint64_t ticks;
248     ticks = ((uint64_t)ms * HZ) / 1000; // 1000:time unit
249     if (ticks > UINT32_MAX) {
250         return BLE_NPL_EINVAL;
251     }
252 
253     *out_ticks = ticks;
254     return 0;
255 }
256 
npl_freertos_time_ticks_to_ms(ble_npl_time_t ticks,uint32_t * out_ms)257 ble_npl_error_t npl_freertos_time_ticks_to_ms(ble_npl_time_t ticks, uint32_t *out_ms)
258 {
259     uint64_t ms;
260     ms = ((uint64_t)ticks * 1000) / HZ; // 1000:time unit
261     if (ms > UINT32_MAX) {
262         return BLE_NPL_EINVAL;
263     }
264 
265     *out_ms = ms;
266     return 0;
267 }