• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (C) 2022 Beken Corporation
2 //
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 #include <stdarg.h>
16 #include <string.h>
17 #include <driver/uart.h>
18 #include "bk_uart.h"
19 #include <common/sys_config.h>
20 #include <common/bk_compiler.h>
21 #include <os/mem.h>
22 #include "printf_impl.h"
23 #if CONFIG_SHELL_ASYNCLOG
24 #include "bk_api_cli.h"
25 #endif
26 
27 #if (CONFIG_SHELL_ASYNCLOG && CONFIG_SLAVE_CORE)
28 #define CPU1_TAG "cpu1"
29 #endif
30 
31 #ifndef CONFIG_PRINTF_BUF_SIZE
32 #define CONFIG_PRINTF_BUF_SIZE    (128)
33 #endif
34 
35 static char s_exception_mode_printf_buf[CONFIG_PRINTF_BUF_SIZE] = {0};
36 // static char s_task_mode_printf_buf[CONFIG_PRINTF_BUF_SIZE] = {0};
37 
38 static uint8_t s_printf_enable = 1;
39 #if CONFIG_SHELL_ASYNCLOG
40 static volatile uint8_t s_printf_sync = 0;
41 
42 typedef  struct
43 {
44 	char	mod_name[15];
45 	u8		disabled;
46 } __bk_packed mod_disable_list_t;
47 
48 static mod_disable_list_t mod_tag_list[20];
49 
50 #endif
51 
52 static beken_mutex_t s_printf_lock = NULL;
53 
printf_lock(void)54 void printf_lock(void)
55 {
56     rtos_lock_mutex(&s_printf_lock);
57 }
58 
printf_unlock(void)59 void printf_unlock(void)
60 {
61     rtos_unlock_mutex(&s_printf_lock);
62 }
63 
printf_lock_init(void)64 int printf_lock_init(void)
65 {
66 	int ret = rtos_init_mutex(&s_printf_lock);
67 	if (kNoErr != ret) {
68 		return BK_ERR_NO_MEM;
69 	}
70 
71 #if CONFIG_SHELL_ASYNCLOG
72 	memset(&mod_tag_list[0], 0, sizeof(mod_tag_list));
73 	shell_set_log_level(LOG_LEVEL);
74 #endif
75 
76 	return BK_OK;
77 }
78 
printf_lock_deinit(void)79 int printf_lock_deinit(void)
80 {
81 	if (s_printf_lock)
82 		rtos_deinit_mutex(&s_printf_lock);
83 
84 	s_printf_lock = NULL;
85 	return BK_OK;
86 }
87 
exception_mode_printf(const char * fmt,va_list ap)88 static void exception_mode_printf(const char *fmt, va_list ap)
89 {
90 	vsnprintf(s_exception_mode_printf_buf, sizeof(s_exception_mode_printf_buf) - 1, fmt, ap);
91 	s_exception_mode_printf_buf[CONFIG_PRINTF_BUF_SIZE - 1] = 0;
92 	uart_write_string(bk_get_printf_port(), s_exception_mode_printf_buf);
93 }
94 
95 #if (!CONFIG_ARCH_RISCV)
irq_printf(const char * fmt,va_list ap)96 static void irq_printf(const char *fmt, va_list ap)
97 {
98 	char string[CONFIG_PRINTF_BUF_SIZE];
99 
100 	vsnprintf(string, sizeof(string) - 1, fmt, ap);
101 	string[CONFIG_PRINTF_BUF_SIZE - 1] = 0;
102 	uart_write_string(bk_get_printf_port(), string);
103 }
104 #endif
105 
106 
task_printf(const char * fmt,va_list ap)107 static void task_printf(const char *fmt, va_list ap)
108 {
109 	char string[CONFIG_PRINTF_BUF_SIZE];
110 
111 	vsnprintf(string, sizeof(string) - 1, fmt, ap);
112 	string[CONFIG_PRINTF_BUF_SIZE - 1] = 0;
113 	uart_write_string(bk_get_printf_port(), string);
114 
115 }
116 
117 
bk_printf_sync(const char * fmt,va_list args)118 static void bk_printf_sync(const char *fmt, va_list args)
119 {
120 	if(!printf_is_init())
121 		return;
122 
123 #if (CONFIG_ARCH_RISCV)
124 
125 	if (rtos_is_in_interrupt_context() || (!rtos_is_scheduler_started()))
126 		exception_mode_printf(fmt, args);
127 	else
128 		task_printf(fmt, args);
129 
130 #else // #if CONFIG_ARCH_RISCV
131 
132 	uint32_t cpsr_val = rtos_get_cpsr();
133 	uint32_t arm_mode = cpsr_val & /*ARM968_MODE_MASK*/0x1f;
134 
135 	if ((/*ARM_MODE_FIQ*/17 == arm_mode)
136 		|| (/*ARM_MODE_ABT*/23 == arm_mode)
137 		|| (/*ARM_MODE_UND*/27 == arm_mode)
138 		|| (!rtos_is_scheduler_started()))
139 		exception_mode_printf(fmt, args);
140 	else if (/*ARM_MODE_IRQ*/18 == arm_mode)
141 		irq_printf(fmt, args);
142 	else
143 		task_printf(fmt, args);
144 
145 #endif // #if CONFIG_ARCH_RISCV
146 }
147 
bk_printf_port(int level,char * tag,const char * fmt,va_list args)148 void bk_printf_port(int level, char *tag, const char *fmt, va_list args)
149 {
150 	if (!rtos_is_scheduler_started()) {
151 		exception_mode_printf(fmt, args);
152 		return;
153 	}
154 
155 #if CONFIG_SHELL_ASYNCLOG
156 
157 	if(s_printf_sync == 0)
158 	{
159 	#if (CONFIG_SLAVE_CORE)
160 		shell_log_out_port(level, CPU1_TAG, fmt, args);
161 	#else
162 		shell_log_out_port(level, NULL, fmt, args);
163 	#endif
164 	}
165 	else
166 	{
167 		bk_printf_sync(fmt, args);
168 	}
169 
170 #else
171 	bk_printf_sync(fmt, args);
172 #endif // #if CONFIG_SHELL_ASYNCLOG
173 }
174 
bk_printf(const char * fmt,...)175 void bk_printf(const char *fmt, ...)
176 {
177 	va_list args;
178 
179 	if(!printf_is_init())
180 		return;
181 
182 	if(!s_printf_enable)
183 	    return;
184 
185 	va_start(args, fmt);
186 
187 	bk_printf_port(BK_LOG_ERROR, NULL, fmt, args);
188 
189 	va_end(args);
190 
191 	return;
192 }
193 
194 #if CONFIG_SHELL_ASYNCLOG
bk_mod_printf_disbled(char * tag)195 static int bk_mod_printf_disbled(char * tag)
196 {
197 	int		i, result;
198 
199 	for(i = 0; i < ARRAY_SIZE(mod_tag_list); i++)
200 	{
201 		if(mod_tag_list[i].disabled)
202 		{
203 			result = strncmp(mod_tag_list[i].mod_name, tag, sizeof(mod_tag_list[i].mod_name) - 1);
204 
205 			if(result == 0)
206 				return 1;
207 		}
208 	}
209 
210 	return 0;
211 }
212 #endif // #if CONFIG_SHELL_ASYNCLOG
213 
bk_buf_printf_sync(char * buf,int buf_len)214 void bk_buf_printf_sync(char *buf, int buf_len)
215 {
216 	if (!printf_is_init())
217 		return;
218 
219 	if (!s_printf_enable) {
220 	    return;
221 	}
222 
223 	if (NULL == buf || buf_len <= 0)
224 		return;
225 
226 	buf[buf_len -1] = '\0';
227 
228 	uart_write_string(bk_get_printf_port(), buf);
229 }
230 
231 
232 
bk_printf_ex(int level,char * tag,const char * fmt,...)233 void bk_printf_ex(int level, char *tag, const char *fmt, ...)
234 {
235 #if CONFIG_SHELL_ASYNCLOG
236 
237 	va_list args;
238 
239 	if(!printf_is_init())
240 		return;
241 
242 	if(level > shell_get_log_level())  /* check here instead of in shell_log_out to reduce API instructions. */
243 		return;
244 
245 	if(bk_mod_printf_disbled(tag))
246 		return;
247 
248 	va_start(args, fmt);
249 
250 	bk_printf_port(level, tag, fmt, args);
251 
252 	va_end(args);
253 
254 #endif
255 	return;
256 }
257 
bk_set_printf_enable(uint8_t enable)258 void bk_set_printf_enable(uint8_t enable)
259 {
260 #if CONFIG_SHELL_ASYNCLOG
261 	if(0 == enable) {
262 		shell_echo_set(0);
263 		shell_set_log_level(0);
264 	} else {
265 		shell_echo_set(1);
266 		shell_set_log_level(LOG_LEVEL);
267 	}
268 #endif
269 	s_printf_enable = enable;
270 }
271 
bk_set_printf_sync(uint8_t enable)272 void bk_set_printf_sync(uint8_t enable)
273 {
274 #if CONFIG_SHELL_ASYNCLOG
275 #if CONFIG_SLAVE_CORE
276 	s_printf_sync = 0;
277 #else
278 	s_printf_sync = enable;
279 #endif
280 #endif
281 }
282 
bk_get_printf_sync(void)283 int bk_get_printf_sync(void)
284 {
285 #if CONFIG_SHELL_ASYNCLOG
286 	return s_printf_sync;
287 #endif
288 
289 	return 1;
290 }
291 
bk_disable_mod_printf(char * mod_name,uint8_t disable)292 void bk_disable_mod_printf(char *mod_name, uint8_t disable)
293 {
294 #if CONFIG_SHELL_ASYNCLOG
295 
296 	int		i, j, result;
297 
298 	if(disable == 0)
299 	{
300 		for(i = 0; i < ARRAY_SIZE(mod_tag_list); i++)
301 		{
302 			if(mod_tag_list[i].disabled)
303 			{
304 				result = strncmp(mod_tag_list[i].mod_name, mod_name, sizeof(mod_tag_list[i].mod_name) - 1);
305 
306 				if(result == 0)
307 				{
308 					mod_tag_list[i].disabled = 0;
309 				}
310 			}
311 		}
312 	}
313 	else
314 	{
315 		j = ARRAY_SIZE(mod_tag_list);
316 
317 		for(i = 0; i < ARRAY_SIZE(mod_tag_list); i++)
318 		{
319 			if(mod_tag_list[i].disabled)
320 			{
321 				result = strncmp(mod_tag_list[i].mod_name, mod_name, sizeof(mod_tag_list[i].mod_name) - 1);
322 
323 				if(result == 0)
324 				{
325 					return;
326 				}
327 			}
328 			else
329 				j = i;
330 		}
331 
332 		if(j >= ARRAY_SIZE(mod_tag_list)) /* no free slot to record this module name. */
333 			return;
334 		else
335 		{
336 			strncpy(mod_tag_list[j].mod_name, mod_name, sizeof(mod_tag_list[j].mod_name) - 1);
337 			mod_tag_list[j].mod_name[sizeof(mod_tag_list[j].mod_name) - 1] = 0;
338 			mod_tag_list[j].disabled = 1;
339 		}
340 	}
341 
342 	return;
343 
344 #endif
345 }
346 
bk_get_disable_mod(int * idx)347 char * bk_get_disable_mod(int * idx)
348 {
349 #if CONFIG_SHELL_ASYNCLOG
350 
351 	int 	i;
352 
353 	for(i = *idx; i < ARRAY_SIZE(mod_tag_list); i++)
354 	{
355 		(*idx)++;
356 		if(mod_tag_list[i].disabled)
357 		{
358 			return &mod_tag_list[i].mod_name[0];
359 		}
360 	}
361 
362 	return NULL;
363 
364 #endif
365 
366 	return NULL;
367 }
368 
369