1 /*
2 * Copyright 2020 NXP
3 * All rights reserved.
4 *
5 *
6 * SPDX-License-Identifier: BSD-3-Clause
7 *
8 */
9
10 #include "fsl_common.h"
11
12 #include "fsl_component_log.h"
13
14 #include "fsl_component_log_backend_ringbuffer.h"
15
16 /*******************************************************************************
17 * Definitions
18 ******************************************************************************/
19
20 /* Weak function. */
21 #if defined(__GNUC__)
22 #define __WEAK_FUNC __attribute__((weak))
23 #elif defined(__ICCARM__)
24 #define __WEAK_FUNC __weak
25 #elif defined(__CC_ARM) || defined(__ARMCC_VERSION)
26 #define __WEAK_FUNC __attribute__((weak))
27 #endif
28
29 typedef struct log_backend_ring_buffer
30 {
31 uint8_t *ringBuffer;
32 size_t ringBufferLength;
33 size_t ringBufferHead;
34 size_t ringBufferTail;
35 uint8_t initialized;
36 } log_backend_ring_buffer_t;
37
38 /*******************************************************************************
39 * Prototypes
40 ******************************************************************************/
41 __WEAK_FUNC void log_backend_ringbuffer_update(uint8_t *buffer, size_t head, size_t tail);
log_backend_ringbuffer_update(uint8_t * buffer,size_t head,size_t tail)42 __WEAK_FUNC void log_backend_ringbuffer_update(uint8_t *buffer, size_t head, size_t tail)
43 {
44 (void)buffer;
45 (void)head;
46 (void)tail;
47 }
48
49 static void log_init_backend_ringbuffer_puts(uint8_t *buffer, size_t length);
50
51 /*******************************************************************************
52 * Variables
53 ******************************************************************************/
54
55 static log_backend_ring_buffer_t s_logBackendRingBuffer;
56
57 LOG_BACKEND_DEFINE(backend_ring_buffer, log_init_backend_ringbuffer_puts);
58
59 /*******************************************************************************
60 * Code
61 ******************************************************************************/
62
log_init_backend_ringbuffer_puts(uint8_t * buffer,size_t length)63 static void log_init_backend_ringbuffer_puts(uint8_t *buffer, size_t length)
64 {
65 uint32_t remainingBufferLength;
66 uint32_t copyLength;
67 uint32_t primask;
68
69 if ((0U == s_logBackendRingBuffer.initialized) || (0U == length))
70 {
71 return;
72 }
73
74 primask = DisableGlobalIRQ();
75 remainingBufferLength = (s_logBackendRingBuffer.ringBufferHead + s_logBackendRingBuffer.ringBufferLength -
76 s_logBackendRingBuffer.ringBufferTail) %
77 s_logBackendRingBuffer.ringBufferLength;
78 remainingBufferLength = s_logBackendRingBuffer.ringBufferLength - remainingBufferLength - 1U;
79
80 if (length >= s_logBackendRingBuffer.ringBufferLength)
81 {
82 buffer = &buffer[length - s_logBackendRingBuffer.ringBufferLength + 1U];
83 length = s_logBackendRingBuffer.ringBufferLength - 1U;
84 }
85 copyLength = length;
86
87 if ((s_logBackendRingBuffer.ringBufferHead + copyLength) > s_logBackendRingBuffer.ringBufferLength)
88 {
89 copyLength = s_logBackendRingBuffer.ringBufferLength - s_logBackendRingBuffer.ringBufferHead;
90 }
91 (void)memcpy(&s_logBackendRingBuffer.ringBuffer[s_logBackendRingBuffer.ringBufferHead], &buffer[0], copyLength);
92 if (copyLength < length)
93 {
94 (void)memcpy(&s_logBackendRingBuffer.ringBuffer[0], &buffer[copyLength], length - copyLength);
95 }
96
97 if (length >= remainingBufferLength)
98 {
99 s_logBackendRingBuffer.ringBufferHead += length;
100 s_logBackendRingBuffer.ringBufferHead =
101 s_logBackendRingBuffer.ringBufferHead % s_logBackendRingBuffer.ringBufferLength;
102 s_logBackendRingBuffer.ringBufferTail =
103 s_logBackendRingBuffer.ringBufferHead + s_logBackendRingBuffer.ringBufferLength + 1U;
104 s_logBackendRingBuffer.ringBufferTail =
105 s_logBackendRingBuffer.ringBufferTail % s_logBackendRingBuffer.ringBufferLength;
106 }
107 else
108 {
109 s_logBackendRingBuffer.ringBufferHead += length;
110 s_logBackendRingBuffer.ringBufferHead =
111 s_logBackendRingBuffer.ringBufferHead % s_logBackendRingBuffer.ringBufferLength;
112 }
113 EnableGlobalIRQ(primask);
114
115 log_backend_ringbuffer_update(s_logBackendRingBuffer.ringBuffer, s_logBackendRingBuffer.ringBufferHead,
116 s_logBackendRingBuffer.ringBufferTail);
117 }
118
LOG_InitBackendRingbuffer(log_backend_ring_buffer_config_t * config)119 void LOG_InitBackendRingbuffer(log_backend_ring_buffer_config_t *config)
120 {
121 log_status_t ret;
122 assert((NULL != config) && (NULL != config->ringBuffer) && (0U != config->ringBufferLength));
123
124 if (0U != s_logBackendRingBuffer.initialized)
125 {
126 return;
127 }
128
129 (void)memset(&s_logBackendRingBuffer, 0, sizeof(s_logBackendRingBuffer));
130
131 s_logBackendRingBuffer.ringBuffer = config->ringBuffer;
132 s_logBackendRingBuffer.ringBufferLength = config->ringBufferLength;
133
134 ret = LOG_BackendRegister(&backend_ring_buffer);
135 if (kStatus_LOG_Success == ret)
136 {
137 s_logBackendRingBuffer.initialized = 1U;
138 }
139 assert(kStatus_LOG_Success == ret);
140 return;
141 }
142
LOG_DeinitBackendRingbuffer(void)143 void LOG_DeinitBackendRingbuffer(void)
144 {
145 log_status_t ret;
146
147 ret = LOG_BackendUnregister(&backend_ring_buffer);
148 if (kStatus_LOG_Success == ret)
149 {
150 s_logBackendRingBuffer.initialized = 0U;
151 }
152 assert(kStatus_LOG_Success == ret);
153 return;
154 }
155