• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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