1 /*
2 * Copyright (c) 2021 Chipsea Technologies (Shenzhen) Corp., Ltd. All rights reserved.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 /**
16 ****************************************************************************************
17 *
18 * @file rtos_al.c
19 *
20 * @brief Implementation of the FreeRTOS abstraction layer.
21 *
22 ****************************************************************************************
23 */
24
25 /*
26 * INCLUDE FILES
27 ****************************************************************************************
28 */
29 #include "rtos_ohos_def.h"
30 #include "al_rtos.h"
31 #include "rtos_ohos_al.h"
32 #include <string.h>
33 #include <stdio.h>
34 #include "cmsis_os2.h"
35 #include "los_task.h"
36 #include "dbg.h"
37
38 TickType_t rtos_timeout_2_tickcount(int timeout_ms);
39
rtos_now(bool isr)40 uint32_t rtos_now(bool isr)
41 {
42 return osKernelGetTickCount();
43 }
44
rtos_malloc(uint32_t size)45 void *rtos_malloc(uint32_t size)
46 {
47 return LOS_MemAlloc(OS_SYS_MEM_ADDR, size);
48 }
49
rtos_calloc(uint32_t nb_elt,uint32_t size)50 void *rtos_calloc(uint32_t nb_elt, uint32_t size)
51 {
52 void * res = LOS_MemAlloc(OS_SYS_MEM_ADDR, nb_elt * size);
53 if (res)
54 memset(res, 0, nb_elt * size);
55
56 return res;
57 }
58
rtos_free(void * ptr)59 void rtos_free(void *ptr)
60 {
61 LOS_MemFree(OS_SYS_MEM_ADDR, ptr);
62 }
63
rtos_heap_info(int * total_size,int * free_size,int * min_free_size)64 void rtos_heap_info(int *total_size, int *free_size, int *min_free_size)
65 {
66 *total_size = LOS_MemPoolSizeGet(OS_SYS_MEM_ADDR);
67 *free_size = LOS_MemTotalUsedGet(OS_SYS_MEM_ADDR);
68 *min_free_size = LOS_MemPoolSizeGet(OS_SYS_MEM_ADDR);
69 }
70
rtos_get_idle_task_handle(void)71 rtos_task_handle rtos_get_idle_task_handle(void)
72 {
73 return g_idleTaskID;
74 }
75
rtos_get_task_handle(void)76 rtos_task_handle rtos_get_task_handle(void)
77 {
78 return osThreadGetId();
79 }
80
rtos_task_create(rtos_task_fct func,const char * const name,enum rtos_task_id task_id,const uint16_t stack_depth,void * const params,rtos_prio prio,rtos_task_handle * const task_handle)81 int rtos_task_create(rtos_task_fct func,
82 const char * const name,
83 enum rtos_task_id task_id,
84 const uint16_t stack_depth,
85 void * const params,
86 rtos_prio prio,
87 rtos_task_handle * const task_handle)
88 {
89 osThreadId_t tid;
90 osThreadAttr_t attr = {0};
91 attr.stack_size = stack_depth;
92 if (prio < osPriorityNormal) {
93 dbg("rtos_task_create prio err! task:%s,prio = %d\r\n", attr.name, prio);
94 prio = osPriorityNormal;
95 }
96 attr.priority = prio;
97 attr.name = name;
98 tid = osThreadNew((osThreadFunc_t)func, params, &attr);
99 if (tid == NULL) {
100 dbg("rtos_task_create err! task:%s\r\n",attr.name);
101 return 1;
102 }
103 if (task_handle) {
104 *task_handle = tid;
105 }
106 return 0;
107 }
108
rtos_task_delete(rtos_task_handle task_handle)109 void rtos_task_delete(rtos_task_handle task_handle)
110 {
111 if (!task_handle) {
112 task_handle = osThreadGetId();
113 }
114 osThreadTerminate(task_handle);
115 }
116
rtos_task_suspend(int duration)117 void rtos_task_suspend(int duration)
118 {
119 if (duration <= 0)
120 return;
121 osDelay(LOS_MS2Tick(duration));
122 }
123
rtos_task_set_priority(rtos_task_handle task_handle,uint32_t priority)124 void rtos_task_set_priority(rtos_task_handle task_handle, uint32_t priority)
125 {
126 osThreadSetPriority(task_handle, priority);
127 }
128
129 #define TASK_NOTICE_MAX_VALUE (0x00FFFFFF)
130 #define TASK_NOTICE_ZERO_BIT (0x01000000)
rtos_task_init_notification(rtos_task_handle task)131 int rtos_task_init_notification(rtos_task_handle task)
132 {
133 LosTaskCB *taskCB = NULL;
134 UINT32 intSave;
135 UINT32 ret = LOS_OK;
136
137 intSave = LOS_IntLock();
138 taskCB = (LosTaskCB*)task;
139 LOS_IntRestore(intSave);
140
141 if (NULL == taskCB){
142 ret = LOS_ERRNO_TSK_NOT_CREATED;
143 }
144 #if 0
145 if (LOS_OK == ret){
146 if (taskCB->taskFlags & OS_TASK_FLAG_SYSTEM){
147 ret = LOS_ERRNO_TSK_OPERATE_SYSTEM_TASK;
148 }
149 }
150 #endif
151 if (LOS_OK == ret){
152 ret = LOS_EventInit(&taskCB->event);
153 }
154
155 if (ret){
156 dbg("rtos_task_init_notifi: err code %d\r\n", ret);
157 return -1;
158 }
159 else{
160 return 0;
161 }
162 }
163
rtos_task_wait_notification(int timeout)164 uint32_t rtos_task_wait_notification(int timeout)
165 {
166 UINT32 intSave;
167 rtos_task_handle task;
168 UINT32 notifi_value = 0;
169 LosTaskCB *taskCB = NULL;
170
171 intSave = LOS_IntLock();
172 taskCB = OS_TCB_FROM_TID(LOS_CurTaskIDGet());
173 LOS_IntRestore(intSave);
174
175 if (NULL == taskCB){
176 dbg("rtos_task_wait_notifi: task null\r\n");
177 }
178 else{
179 notifi_value = LOS_EventRead(&taskCB->event, TASK_NOTICE_MAX_VALUE|TASK_NOTICE_ZERO_BIT, LOS_WAITMODE_OR|LOS_WAITMODE_CLR, rtos_timeout_2_tickcount(timeout));
180
181 if (notifi_value & 0x02000000){ //means error
182 notifi_value = 0;
183 }
184 notifi_value &= TASK_NOTICE_MAX_VALUE;
185 }
186
187 return notifi_value;
188 }
189
rtos_task_notify(rtos_task_handle task_handle,uint32_t value,bool isr)190 void rtos_task_notify(rtos_task_handle task_handle, uint32_t value, bool isr)
191 {
192 UINT32 intSave;
193 UINT32 ret;
194 LosTaskCB *taskCB = NULL;
195
196 intSave = LOS_IntLock();
197 taskCB = (LosTaskCB*)task_handle;
198 LOS_IntRestore(intSave);
199 if (NULL == taskCB){
200 dbg("rtos_task_wait_notifi: task null\r\n");
201 }
202
203 if (value > TASK_NOTICE_MAX_VALUE){
204 dbg("rtos_task_notify:value=0x%x, too big\r\n", value);
205 return;
206 }
207
208 if (0 == value){
209 value = TASK_NOTICE_ZERO_BIT; //0 convert to special bit set
210 }
211
212 ret = LOS_EventClear(&taskCB->event, 0UL); //clear old value
213 if (ret != LOS_OK){
214 dbg("rtos_task_notify:clear err code is %d\r\n", ret);
215 }
216
217 ret = LOS_EventWrite(&taskCB->event, value);
218 if (ret != LOS_OK){
219 dbg("rtos_task_notify:write err code is %d\r\n", ret);
220 }
221 return;
222 }
223
rtos_queue_create(int elt_size,int nb_elt,rtos_queue * queue)224 int rtos_queue_create(int elt_size, int nb_elt, rtos_queue *queue)
225 {
226 *queue = osMessageQueueNew(nb_elt, elt_size, NULL);
227 if (*queue == NULL) {
228 dbg("rtos_queue_create err!\r\n");
229 return -1;
230 }
231 return 0;
232 }
233
rtos_queue_delete(rtos_queue queue)234 void rtos_queue_delete(rtos_queue queue)
235 {
236 osMessageQueueDelete(queue);
237 }
238
rtos_queue_is_empty(rtos_queue queue)239 bool rtos_queue_is_empty(rtos_queue queue)
240 {
241 uint32_t cnt;
242 cnt = osMessageQueueGetCount(queue);
243 return (cnt == 0) ? true : false;
244 }
245
rtos_queue_cnt(rtos_queue queue)246 int rtos_queue_cnt(rtos_queue queue)
247 {
248 return osMessageQueueGetCount(queue);
249 }
250
rtos_queue_write(rtos_queue queue,void * msg,int timeout,bool isr)251 int rtos_queue_write(rtos_queue queue, void *msg, int timeout, bool isr)
252 {
253 osStatus_t ret = osMessageQueuePut(queue, msg, 0, timeout);
254 return (ret == 0) ? 0 : 1;
255 }
256
rtos_queue_read(rtos_queue queue,void * msg,int timeout,bool isr)257 int rtos_queue_read(rtos_queue queue, void *msg, int timeout, bool isr)
258 {
259 osStatus_t ret = osMessageQueueGet(queue, msg, NULL, rtos_timeout_2_tickcount(timeout));
260 return (ret == 0) ? 0 : 1;
261 }
262
rtos_semaphore_create(rtos_semaphore * semaphore,int max_count,int init_count)263 int rtos_semaphore_create(rtos_semaphore *semaphore, int max_count, int init_count)
264 {
265 *semaphore = osSemaphoreNew(max_count, init_count, NULL);
266 if (*semaphore == NULL) {
267 dbg("rtos_semaphore_create err!\r\n");
268 return -1;
269 }
270 return 0;
271 }
272
rtos_semaphore_delete(rtos_semaphore semaphore)273 void rtos_semaphore_delete(rtos_semaphore semaphore)
274 {
275 osSemaphoreDelete(semaphore);
276 }
277
rtos_semaphore_get_count(rtos_semaphore semaphore)278 int rtos_semaphore_get_count(rtos_semaphore semaphore)
279 {
280 return osSemaphoreGetCount(semaphore);
281 }
282
rtos_semaphore_wait(rtos_semaphore semaphore,int timeout)283 int rtos_semaphore_wait(rtos_semaphore semaphore, int timeout)
284 {
285 osStatus_t ret = osSemaphoreAcquire(semaphore, LOS_MS2Tick(timeout));
286 return (ret == osOK) ? 0 : 1;
287 }
288
rtos_semaphore_signal(rtos_semaphore semaphore,bool isr)289 int rtos_semaphore_signal(rtos_semaphore semaphore, bool isr)
290 {
291 osStatus_t ret = osSemaphoreRelease(semaphore);
292 return (ret == osOK) ? 0 : 1;
293 }
294
rtos_timer_create(const char * const pcTimerName,const TickType_t xTimerPeriodInTicks,const UBaseType_t uxAutoReload,void * const pvTimerID,TimerCallbackFunction_t pxCallbackFunction)295 TimerHandle_t rtos_timer_create( const char * const pcTimerName,
296 const TickType_t xTimerPeriodInTicks,
297 const UBaseType_t uxAutoReload,
298 void * const pvTimerID,
299 TimerCallbackFunction_t pxCallbackFunction )
300 {
301 (void)pcTimerName;
302 uint8_t mode;
303 uint32_t usSwTmrID;
304 uint32_t uwRet;
305 mode = ((uxAutoReload == 0) ? LOS_SWTMR_MODE_NO_SELFDELETE : LOS_SWTMR_MODE_PERIOD);
306
307 uwRet = LOS_SwtmrCreate(xTimerPeriodInTicks, mode, (SWTMR_PROC_FUNC)pxCallbackFunction, &usSwTmrID, 0);
308 if (uwRet != LOS_OK) {
309 return (osTimerId_t)NULL;
310 }
311 return (osTimerId_t)OS_SWT_FROM_SID(usSwTmrID);
312 }
313
rtos_timer_start(TimerHandle_t xTimer,TickType_t xTicksToWait,bool isr)314 int rtos_timer_start(TimerHandle_t xTimer,TickType_t xTicksToWait, bool isr)
315 {
316 SWTMR_CTRL_S *pstSwtmr;
317 uint32_t uwRet;
318
319 pstSwtmr = (SWTMR_CTRL_S *)xTimer;
320
321 uwRet = LOS_SwtmrStart(pstSwtmr->usTimerID);
322
323 return (uwRet == LOS_OK) ? 0 : 1;
324 }
325
rtos_timer_stop(TimerHandle_t xTimer,TickType_t xTicksToWait)326 int rtos_timer_stop(TimerHandle_t xTimer,TickType_t xTicksToWait)
327 {
328 (void)xTicksToWait;
329 uint32_t uwRet;
330 SWTMR_CTRL_S *pstSwtmr = (SWTMR_CTRL_S *)xTimer;
331
332 uwRet = LOS_SwtmrStop(pstSwtmr->usTimerID);
333 return (uwRet == LOS_OK) ? 0 : 1;
334 }
rtos_timer_delete(TimerHandle_t xTimer,TickType_t xTicksToWait)335 int rtos_timer_delete(TimerHandle_t xTimer,TickType_t xTicksToWait)
336 {
337 (void)xTicksToWait;
338 uint32_t uwRet;
339 SWTMR_CTRL_S *pstSwtmr = (SWTMR_CTRL_S *)xTimer;
340 uwRet = LOS_SwtmrDelete(pstSwtmr->usTimerID);
341 return (uwRet == LOS_OK) ? 0 : 1;
342 }
343
rtos_timer_change_period(TimerHandle_t xTimer,TickType_t xNewPeriod,TickType_t xTicksToWait)344 int rtos_timer_change_period(TimerHandle_t xTimer, TickType_t xNewPeriod,TickType_t xTicksToWait)
345 {
346 uint32_t uwRet;
347 SWTMR_CTRL_S *pstSwtmr = (SWTMR_CTRL_S *)xTimer;
348
349 uwRet = LOS_SwtmrStop(pstSwtmr->usTimerID);
350 if (uwRet != LOS_OK) {
351 return 1;
352 }
353 pstSwtmr->uwInterval = xNewPeriod;
354 uwRet = LOS_SwtmrStart(pstSwtmr->usTimerID);
355
356 return (uwRet == LOS_OK) ? 0 : 1;
357 }
358
rtos_timer_restart(TimerHandle_t xTimer,TickType_t xTicksToWait,bool isr)359 int rtos_timer_restart(TimerHandle_t xTimer,TickType_t xTicksToWait, bool isr)
360 {
361 (void)xTicksToWait;
362 uint32_t uwRet;
363 SWTMR_CTRL_S *pstSwtmr = (SWTMR_CTRL_S *)xTimer;
364
365 uwRet = LOS_SwtmrStop(pstSwtmr->usTimerID);
366 if (uwRet != LOS_OK) {
367 return 1;
368 }
369 uwRet = LOS_SwtmrStart(pstSwtmr->usTimerID);
370
371 return (uwRet == LOS_OK) ? 0 : 1;
372 }
373
rtos_timeout_2_tickcount(int timeout_ms)374 TickType_t rtos_timeout_2_tickcount(int timeout_ms)
375 {
376 if (timeout_ms < 0)
377 {
378 return portMAX_DELAY;
379 }
380 else
381 {
382 return pdMS_TO_TICKS(timeout_ms);
383 }
384 }
385
rtos_mutex_create(rtos_mutex * mutex)386 int rtos_mutex_create(rtos_mutex *mutex)
387 {
388 *mutex = osMutexNew(NULL);
389 if (*mutex == 0) {
390 dbg("rtos_mutex_create err!\r\n");
391 return -1;
392 }
393
394 return 0;
395 }
396
rtos_mutex_delete(rtos_mutex mutex)397 void rtos_mutex_delete(rtos_mutex mutex)
398 {
399 osMutexDelete(mutex);
400 }
401
rtos_mutex_lock(rtos_mutex mutex,int timeout)402 int rtos_mutex_lock(rtos_mutex mutex, int timeout)
403 {
404 return osMutexAcquire(mutex, timeout);
405 }
406
rtos_mutex_unlock(rtos_mutex mutex)407 int rtos_mutex_unlock(rtos_mutex mutex)
408 {
409 return osMutexRelease(mutex);
410 }
411
rtos_mutex_recursive_create(rtos_mutex * mutex)412 int rtos_mutex_recursive_create(rtos_mutex *mutex)
413 {
414 *mutex = osMutexNew(NULL);
415 return (*mutex == 0) ? -1 : 0;
416 }
rtos_mutex_recursive_lock(rtos_mutex mutex)417 int rtos_mutex_recursive_lock(rtos_mutex mutex)
418 {
419 return osMutexAcquire(mutex, 0);
420 }
421
rtos_mutex_recursive_unlock(rtos_mutex mutex)422 int rtos_mutex_recursive_unlock(rtos_mutex mutex)
423 {
424 return osMutexRelease(mutex);
425 }
426
rtos_protect(void)427 uint32_t rtos_protect(void)
428 {
429 return osKernelLock();
430 }
431
rtos_unprotect(uint32_t protect)432 void rtos_unprotect(uint32_t protect)
433 {
434 osKernelRestoreLock(protect);
435 }
436