1 /*
2 * Copyright (c) 2022 Winner Microelectronics Co., 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 #include <string.h>
17 #include "wm_mem.h"
18 #include "wm_wl_timers.h"
19 #include "wm_wl_task.h"
20
21 static tls_mbox_t task_mbox[TLS_MBOX_ALL_COUNT];
22 struct task_msg wl_msg[TLS_MSG_ALL_COUONT];
23
task_thread(void * arg)24 static void task_thread(void *arg)
25 {
26 struct task_msg *msg;
27 start_routine fun;
28 void *argu;
29 struct task_parameter *task_param = (struct task_parameter *)arg;
30
31 /* MAIN Loop */
32 while (1) {
33 /* wait for a message, timeouts are processed while waiting */
34 tls_timeouts_mbox_fetch_p(task_param->timeo_id, task_mbox[task_param->mbox_id], (void **)&msg);
35 switch (msg->type) {
36 case TASK_MSG_CALLBACK:
37 msg->msg.cb.function(msg->msg.cb.ctx);
38 tls_mem_free(msg);
39 break;
40 case TASK_MSG_CALLBACK_STATIC:
41 fun = msg->msg.cbs.function;
42 argu = msg->msg.cbs.ctx;
43 msg->msg.cbs.cnt--;
44 fun(argu);
45 break;
46 case TASK_MSG_TIMEOUT:
47 tls_timeout_p(task_param->timeo_id, msg->msg.tmo.msecs, msg->msg.tmo.h, msg->msg.tmo.arg);
48 tls_mem_free(msg);
49 break;
50 case TASK_MSG_UNTIMEOUT:
51 tls_untimeout_p(task_param->timeo_id, msg->msg.tmo.h, msg->msg.tmo.arg);
52 tls_mem_free(msg);
53 break;
54 default:
55 break;
56 }
57 }
58 }
59
tls_wl_task_run(struct task_parameter * task_param)60 s8 tls_wl_task_run(struct task_parameter *task_param)
61 {
62 if (tls_mbox_new(&task_mbox[task_param->mbox_id], task_param->mbox_size) != TLS_OS_SUCCESS) {
63 return -1;
64 }
65
66 tls_os_task_create(NULL,
67 task_param->name,
68 task_thread,
69 (void *)task_param,
70 (void *)(task_param->stk_start),
71 task_param->stk_size * sizeof(u32),
72 TLS_TASK_START_PRIO+task_param->task_id,
73 0);
74 return 0;
75 }
76
tls_wl_task_callback_static(struct task_parameter * task_param,start_routine function,void * ctx,u8 block,u8 msg_id)77 s8 tls_wl_task_callback_static(struct task_parameter *task_param,
78 start_routine function, void *ctx, u8 block, u8 msg_id)
79 {
80 struct task_msg *msg = &wl_msg[msg_id];
81
82 if (msg->msg.cbs.cnt > 0) {
83 return TLS_OS_ERROR;
84 }
85
86 if (tls_mbox_valid(task_mbox[task_param->mbox_id])) {
87 msg->type = TASK_MSG_CALLBACK_STATIC;
88 msg->msg.cbs.function = function;
89 msg->msg.cbs.ctx = ctx;
90 if (block) {
91 tls_mbox_post(task_mbox[task_param->mbox_id], (void *)msg);
92 } else {
93 if (tls_mbox_trypost(task_mbox[task_param->mbox_id], (void *)msg) != TLS_OS_SUCCESS)
94 return TLS_OS_ERROR;
95 }
96 msg->msg.cbs.cnt++;
97 return TLS_OS_SUCCESS;
98 }
99 return TLS_OS_ERROR;
100 }
101
tls_wl_task_callback(struct task_parameter * task_param,start_routine function,void * ctx,u8 block)102 s8 tls_wl_task_callback(struct task_parameter *task_param, start_routine function, void *ctx, u8 block)
103 {
104 struct task_msg *msg;
105
106 if (tls_mbox_valid(task_mbox[task_param->mbox_id])) {
107 msg = (struct task_msg *)tls_mem_alloc(sizeof(struct task_msg));
108 if (msg == NULL) {
109 return TLS_OS_ERROR;
110 }
111
112 msg->type = TASK_MSG_CALLBACK;
113 msg->msg.cb.function = function;
114 msg->msg.cb.ctx = ctx;
115 if (block) {
116 tls_mbox_post(task_mbox[task_param->mbox_id], msg);
117 } else {
118 if (tls_mbox_trypost(task_mbox[task_param->mbox_id], msg) != TLS_OS_SUCCESS) {
119 tls_mem_free(msg);
120 return TLS_OS_ERROR;
121 }
122 }
123 return TLS_OS_SUCCESS;
124 }
125 return TLS_OS_ERROR;
126 }
127
tls_wl_task_add_timeout(struct task_parameter * task_param,u32 msecs,tls_timeout_handler h,void * arg)128 s8 tls_wl_task_add_timeout(struct task_parameter *task_param, u32 msecs, tls_timeout_handler h, void *arg)
129 {
130 struct task_msg *msg;
131
132 if (tls_mbox_valid(task_mbox[task_param->mbox_id])) {
133 msg = (struct task_msg *)tls_mem_alloc(sizeof(struct task_msg));
134 if (msg == NULL) {
135 return TLS_OS_ERROR;
136 }
137
138 msg->type = TASK_MSG_TIMEOUT;
139 msg->msg.tmo.msecs = msecs;
140 msg->msg.tmo.h = h;
141 msg->msg.tmo.arg = arg;
142 tls_mbox_post(task_mbox[task_param->mbox_id], msg);
143 return TLS_OS_SUCCESS;
144 }
145 return TLS_OS_ERROR;
146 }
147
tls_wl_task_untimeout(struct task_parameter * task_param,tls_timeout_handler h,void * arg)148 s8 tls_wl_task_untimeout(struct task_parameter *task_param, tls_timeout_handler h, void *arg)
149 {
150 struct task_msg *msg;
151
152 if (tls_mbox_valid(task_mbox[task_param->mbox_id])) {
153 msg = (struct task_msg *)tls_mem_alloc(sizeof(struct task_msg));
154 if (msg == NULL) {
155 return TLS_OS_ERROR;
156 }
157
158 msg->type = TASK_MSG_UNTIMEOUT;
159 msg->msg.tmo.h = h;
160 msg->msg.tmo.arg = arg;
161 tls_mbox_post(task_mbox[task_param->mbox_id], msg);
162 return TLS_OS_SUCCESS;
163 }
164 return TLS_OS_ERROR;
165 }
166
tls_wl_task_init(void)167 s8 tls_wl_task_init(void)
168 {
169 memset(wl_msg, 0, sizeof(struct task_msg));
170 return 0;
171 }
172
173