1 /*
2 * Copyright (c) 2009-2022 Huawei Technologies Co., Ltd. All rights reserved.
3 *
4 * UniProton is licensed under Mulan PSL v2.
5 * You can use this software according to the terms and conditions of the Mulan PSL v2.
6 * You may obtain a copy of Mulan PSL v2 at:
7 * http://license.coscl.org.cn/MulanPSL2
8 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
9 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
10 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
11 * See the Mulan PSL v2 for more details.
12 * Create: 2009-12-22
13 * Description: Hardware interrupt implementation
14 */
15 #include "rtt_viewer.h"
16 #include "prt_typedef.h"
17 #include "prt_mem.h"
18 #include "securec.h"
19
20 TagRttViewerCb _SEGGER_RTT;
21
22 /*
23 * 描述: rtt viewer加锁
24 */
RttViewerLock()25 static unsigned int RttViewerLock()
26 {
27 unsigned int lockState;
28 OS_EMBED_ASM("mrs %0, basepri \n\t"
29 "mov r1, %1 \n\t"
30 "msr basepri, r1 \n\t"
31 : "=r" (lockState) \
32 : "i"(RTT_VIEWER_MAX_INT_PRI)
33 : "r1", "cc"
34 );
35
36 return lockState;
37 }
38
39 /*
40 * 描述: rtt viewer释放锁
41 */
RttViewerUnlock(unsigned int lockSave)42 static void RttViewerUnlock(unsigned int lockSave)
43 {
44 OS_EMBED_ASM("msr basepri, %0 \n\t"
45 :
46 : "r" (lockSave)
47 :
48 );
49 }
50
51 /*
52 * 描述: rtt viewer初始化
53 */
RttViewerInit(void)54 void RttViewerInit(void)
55 {
56 unsigned int idx;
57 unsigned int size;
58 unsigned char *wbuffer;
59 unsigned char *rbuffer;
60
61 g_rttViewerCb.wbMaxNum = RTT_VIEWER_WB_MAX_NUM;
62 g_rttViewerCb.rbMaxNum = RTT_VIEWER_RB_MAX_NUM;
63
64 /* rtt viewer写缓冲区资源申请 */
65 size = RTT_VIEWER_WB_MAX_NUM * RTT_VIEWER_WB_BUFFER_SIZE;
66 wbuffer = (unsigned char *)PRT_MemAlloc(0, OS_MEM_DEFAULT_FSC_PT, size);
67 if ((wbuffer == NULL) || (memset_s(wbuffer, size, 0, size) != EOK)) {
68 return;
69 }
70
71 /* rtt viewer写缓冲区初始化 */
72 for (idx = 0; idx < RTT_VIEWER_WB_MAX_NUM; idx++) {
73 g_rttViewerCb.aUp[idx].sName = "Terminal";
74 g_rttViewerCb.aUp[idx].pBuffer = &wbuffer[idx * RTT_VIEWER_WB_BUFFER_SIZE];
75 g_rttViewerCb.aUp[idx].size = RTT_VIEWER_WB_BUFFER_SIZE;
76 g_rttViewerCb.aUp[idx].rIdx = 0;
77 g_rttViewerCb.aUp[idx].wIdx = 0;
78 g_rttViewerCb.aUp[idx].flags = RTT_VIEWER_MODE_DEFAULT;
79 }
80
81 /* rtt viewer读缓冲区资源申请 */
82 size = RTT_VIEWER_RB_MAX_NUM * RTT_VIEWER_RB_BUFFER_SIZE;
83 rbuffer = (unsigned char *)PRT_MemAlloc(0, OS_MEM_DEFAULT_FSC_PT, size);
84 if ((rbuffer == NULL) || (memset_s(rbuffer, size, 0, size) != EOK)) {
85 return;
86 }
87
88 /* rtt viewer读缓冲区初始化 */
89 for (idx = 0; idx < RTT_VIEWER_RB_MAX_NUM; idx++) {
90 g_rttViewerCb.aDown[idx].sName = "Terminal";
91 g_rttViewerCb.aDown[idx].pBuffer = &rbuffer[idx * RTT_VIEWER_RB_BUFFER_SIZE];
92 g_rttViewerCb.aDown[idx].size = RTT_VIEWER_RB_BUFFER_SIZE;
93 g_rttViewerCb.aDown[idx].rIdx = 0;
94 g_rttViewerCb.aDown[idx].wIdx = 0;
95 g_rttViewerCb.aDown[idx].flags = RTT_VIEWER_MODE_DEFAULT;
96 }
97
98 /* 设置rtt viewer的id */
99 strcpy((char *)&g_rttViewerCb.acID[0], "SEGGER");
100 RTT_DMB();
101 g_rttViewerCb.acID[6] = ' ';
102 RTT_DMB();
103 strcpy((char *)&g_rttViewerCb.acID[7], "RTT");
104 RTT_DMB();
105
106 return;
107 }
108
109 /*
110 * 描述: rtt viewer写模式配置
111 */
RttViewerModeSet(unsigned int chn,unsigned int mode)112 unsigned int RttViewerModeSet(unsigned int chn, unsigned int mode)
113 {
114 if ((mode > RTT_VIEWER_MODE_MASK) || (chn >= RTT_VIEWER_WB_MAX_NUM)) {
115 return OS_ERROR;
116 }
117
118 /* 设置模式 */
119 g_rttViewerCb.aUp[chn].flags = mode;
120 }
121
122 /*
123 * 描述: 参数校验
124 */
RttViewerWriteParaCheck(unsigned int chn,const void * buffer,unsigned int numBytes)125 static unsigned int RttViewerWriteParaCheck(unsigned int chn, const void *buffer, unsigned int numBytes)
126 {
127 if (chn >= RTT_VIEWER_WB_MAX_NUM) {
128 return OS_ERROR;
129 }
130
131 if (buffer == NULL) {
132 return OS_ERROR;
133 }
134
135 if ((numBytes == 0) || (numBytes > RTT_VIEWER_WB_BUFFER_SIZE)) {
136 return OS_ERROR;
137 }
138
139 return OS_OK;
140 }
141
142 /*
143 * 描述: 获取可以写入环形缓冲区而不阻塞的字节数
144 */
GetAvailWriteSpace(RTT_VIEWER_RING_BUFFER * ringBuffer)145 static unsigned int GetAvailWriteSpace(RTT_VIEWER_RING_BUFFER *ringBuffer) {
146 unsigned int freeSize;
147
148 if (ringBuffer->rIdx <= ringBuffer->wIdx) {
149 freeSize = ringBuffer->size - 1 - ringBuffer->wIdx + ringBuffer->rIdx;
150 } else {
151 freeSize = ringBuffer->rIdx - ringBuffer->wIdx - 1;
152 }
153
154 return freeSize;
155 }
156
157 /*
158 * 描述: 环缓冲区中存储指定数量的字符
159 */
RingBufferPush(RTT_VIEWER_RING_BUFFER * ringBuffer,const char * data,unsigned int numBytes)160 static void RingBufferPush(RTT_VIEWER_RING_BUFFER *ringBuffer, const char *data, unsigned int numBytes)
161 {
162 unsigned int numBytesAtOnce;
163 unsigned int wIdx;
164 unsigned int rem;
165 volatile char *dst;
166
167 wIdx = ringBuffer->wIdx;
168 rem = ringBuffer->size - wIdx;
169 dst = ringBuffer->pBuffer + wIdx;
170 if (rem > numBytes) {
171 memcpy_s((void*)dst, numBytes, data, numBytes);
172 RTT_DMB();
173 ringBuffer->wIdx = wIdx + numBytes;
174 } else {
175 numBytesAtOnce = rem;
176 memcpy_s((void*)dst, numBytesAtOnce, data, numBytesAtOnce);
177 numBytesAtOnce = numBytes - rem;
178
179 if (numBytesAtOnce > 0) {
180 dst = ringBuffer->pBuffer;
181 memcpy_s((void*)dst, numBytesAtOnce, data + rem, numBytesAtOnce);
182 RTT_DMB();
183 }
184 ringBuffer->wIdx = numBytesAtOnce;
185 }
186
187 return;
188 }
189
190 /*
191 * 描述: 环缓冲区中存储指定数量的字符,数据长度可以
192 */
RingBufferBlockPush(RTT_VIEWER_RING_BUFFER * ringBuffer,const char * buffer,unsigned int numBytes)193 static unsigned int RingBufferBlockPush(RTT_VIEWER_RING_BUFFER *ringBuffer, const char *buffer, unsigned int numBytes) {
194 unsigned int numBytesToWrite;
195 unsigned int numBytesWritten;
196 unsigned int rIdx;
197 unsigned int wIdx;
198 volatile char *dst;
199
200 numBytesWritten = 0;
201 wIdx = ringBuffer->wIdx;
202 do {
203 rIdx = ringBuffer->rIdx;
204 if (rIdx > wIdx) {
205 numBytesToWrite = rIdx - wIdx - 1u;
206 } else {
207 numBytesToWrite = ringBuffer->size - (wIdx - rIdx + 1u);
208 }
209
210 numBytesToWrite = MIN(numBytesToWrite, (ringBuffer->size - wIdx));
211 numBytesToWrite = MIN(numBytesToWrite, numBytes);
212 dst = ringBuffer->pBuffer + wIdx;
213 memcpy_s((void*)dst, numBytesToWrite, buffer, numBytesToWrite);
214
215 numBytesWritten += numBytesToWrite;
216 buffer += numBytesToWrite;
217 numBytes -= numBytesToWrite;
218 wIdx += numBytesToWrite;
219 if (wIdx == ringBuffer->size) {
220 wIdx = 0;
221 }
222 RTT_DMB();
223 ringBuffer->wIdx = wIdx;
224 } while (numBytes);
225
226 return numBytesWritten;
227 }
228
229 /*
230 * 描述: rtt viewer写数据
231 */
RttViewerWrite(unsigned int chn,const void * buffer,unsigned int numBytes)232 unsigned int RttViewerWrite(unsigned int chn, const void *buffer, unsigned int numBytes)
233 {
234 unsigned int ret;
235 unsigned int intSave;
236 unsigned int freeSize;
237 unsigned int writeBytes;
238 RTT_VIEWER_RING_BUFFER *wRingBuffer;
239
240 if (memcmp(g_rttViewerCb.acID, "SEGGER RTT", sizeof("SEGGER RTT")) != 0) {
241 return OS_ERROR;
242 }
243
244 /* 校验入参 */
245 ret = RttViewerWriteParaCheck(chn, buffer, numBytes);
246 if (ret != OS_OK) {
247 return ret;
248 }
249
250 intSave = RttViewerLock();
251
252 wRingBuffer = &g_rttViewerCb.aUp[chn];
253
254 switch (wRingBuffer->flags) {
255 case RTT_VIEWER_MODE_NO_BLOCK_SKIP:
256 freeSize = GetAvailWriteSpace(wRingBuffer);
257 if (freeSize >= numBytes) {
258 RingBufferPush(wRingBuffer, buffer, numBytes);
259 }
260 break;
261
262 case RTT_VIEWER_MODE_NO_BLOCK_TRIM:
263 freeSize = GetAvailWriteSpace(wRingBuffer);
264 RingBufferPush(wRingBuffer, buffer, MIN(freeSize, numBytes));
265 break;
266
267 case RTT_VIEWER_MODE_BLOCK_IF_FIFO_FULL:
268 writeBytes = RingBufferBlockPush(wRingBuffer, buffer, numBytes);
269 break;
270
271 default:
272 break;
273 }
274
275 RttViewerUnlock(intSave);
276
277 return OS_OK;
278 }
279
280 /*
281 * 描述: 参数校验
282 */
RttViewerReadParaCheck(unsigned int chn,const void * buffer,unsigned int numBytes)283 unsigned int RttViewerReadParaCheck(unsigned int chn, const void *buffer, unsigned int numBytes)
284 {
285 if (chn >= RTT_VIEWER_RB_MAX_NUM) {
286 return OS_ERROR;
287 }
288
289 if (buffer == NULL) {
290 return OS_ERROR;
291 }
292
293 if ((numBytes == 0) || (numBytes > RTT_VIEWER_RB_BUFFER_SIZE)) {
294 return OS_ERROR;
295 }
296
297 return OS_OK;
298 }
299
300 /*
301 * 描述: rtt viewer读数据
302 */
RttViewerRead(unsigned int chn,void * buffer,unsigned int numBytes)303 unsigned int RttViewerRead(unsigned int chn, void *buffer, unsigned int numBytes)
304 {
305 unsigned int ret;
306 unsigned int intSave;
307 unsigned int numBytesRem;
308 unsigned int numBytesRead;
309 unsigned int rIdx;
310 unsigned int wIdx;
311 volatile char *src;
312 RTT_VIEWER_RING_BUFFER *rRingBuffer;
313
314 if (memcmp(g_rttViewerCb.acID, "SEGGER RTT", sizeof("SEGGER RTT")) != 0) {
315 return OS_ERROR;
316 }
317
318 /* 校验入参 */
319 ret = RttViewerReadParaCheck(chn, buffer, numBytes);
320 if (ret != OS_OK) {
321 return 0;
322 }
323
324 intSave = RttViewerLock();
325
326 rRingBuffer = &g_rttViewerCb.aDown[chn];
327 rIdx = rRingBuffer->rIdx;
328 wIdx = rRingBuffer->wIdx;
329 numBytesRead = 0u;
330
331 if (rIdx > wIdx) {
332 numBytesRem = rRingBuffer->size - rIdx;
333 numBytesRem = MIN(numBytesRem, numBytes);
334 src = rRingBuffer->pBuffer + rIdx;
335 memcpy_s(buffer, numBytesRem, (void*)src, numBytesRem);
336
337 numBytesRead += numBytesRem;
338 buffer += numBytesRem;
339 numBytes -= numBytesRem;
340 rIdx += numBytesRem;
341 if (rIdx == rRingBuffer->size) {
342 rIdx = 0u;
343 }
344 }
345
346 numBytesRem = wIdx - rIdx;
347 numBytesRem = MIN(numBytesRem, numBytes);
348 if (numBytesRem > 0) {
349 src = rRingBuffer->pBuffer + rIdx;
350 memcpy_s(buffer, numBytesRem, (void*)src, numBytesRem);
351
352 numBytesRead += numBytesRem;
353 buffer += numBytesRem;
354 numBytes -= numBytesRem;
355 rIdx += numBytesRem;
356 }
357
358 if (numBytesRead) {
359 rRingBuffer->rIdx = rIdx;
360 }
361
362 RttViewerUnlock(intSave);
363
364 return numBytesRead;
365 }
366
367 /*
368 * 描述: rtt viewer输出单个字符
369 */
RttViewerPutChar(unsigned int chn,char c)370 unsigned int RttViewerPutChar(unsigned int chn, char c)
371 {
372 unsigned int ret;
373
374 if (chn >= RTT_VIEWER_WB_MAX_NUM) {
375 return OS_ERROR;
376 }
377
378 ret = RttViewerWrite(chn, &c, 1);
379
380 return ret;
381 }
382
383 char g_rttViewerShowBuffer[RTT_VIEWER_MAX_SHOW_LEN];
384
385 /*
386 * 描述: rtt viewer打印函数
387 */
RttViewerPrintf(unsigned int chn,const char * format,...)388 unsigned int RttViewerPrintf(unsigned int chn, const char *format, ...)
389 {
390 unsigned int ret;
391 int len;
392 char *str = g_rttViewerShowBuffer;
393 va_list vaList;
394
395 if (chn >= RTT_VIEWER_WB_MAX_NUM) {
396 return OS_ERROR;
397 }
398
399 va_start(vaList, format);
400 len = vsnprintf_s(str, RTT_VIEWER_MAX_SHOW_LEN, RTT_VIEWER_MAX_SHOW_LEN, format, vaList);
401 va_end(vaList);
402 if (len == -1) {
403 return len;
404 }
405
406 ret = RttViewerWrite(chn, str, len);
407
408 return ret;
409 }
410