更新日期: 2022/06/01 来源: https://gitee.com/weharmony/kernel_liteos_a_note
los_cir_buf.c
浏览该文件的文档.
1/*
2 * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
3 * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice, this list of
9 * conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
12 * of conditions and the following disclaimer in the documentation and/or other materials
13 * provided with the distribution.
14 *
15 * 3. Neither the name of the copyright holder nor the names of its contributors may be used
16 * to endorse or promote products derived from this software without specific prior written
17 * permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32#include "los_cir_buf.h"
33#include "los_spinlock.h"
34
35
36/// 返回循环buf已使用的大小
38{
39 UINT32 size;
40 UINT32 intSave;
41
42 LOS_SpinLockSave(&cirbufCB->lock, &intSave);
43 size = cirbufCB->size - cirbufCB->remain; //得到已使用大小
44 LOS_SpinUnlockRestore(&cirbufCB->lock, intSave);
45
46 return size;
47}
48
49/* 图形表示写循环buf linear 模式 ,图表示 写之前的样子 @note_pic
50 * startIdx
51 * |
52 * 0 0 0 0 0 0 0 0 X X X X X X X X 0 0 0 0 0 0
53 * |
54 * endIdx
55 *///写操作的是endIdx | X 表示剩余size index 从左到右递减
56STATIC UINT32 OsCirBufWriteLinear(CirBuf *cirbufCB, const CHAR *buf, UINT32 size)
57{
58 UINT32 cpSize;
59 errno_t err;
60
61 cpSize = (cirbufCB->remain < size) ? cirbufCB->remain : size;//得到cp的大小
62
63 if (cpSize == 0) {
64 return 0;
65 }
66
67 err = memcpy_s(cirbufCB->fifo + cirbufCB->endIdx, cirbufCB->remain, buf, cpSize);//完成拷贝
68 if (err != EOK) {
69 return 0;
70 }
71
72 cirbufCB->remain -= cpSize;//写完了那总剩余size肯定是要减少的
73 cirbufCB->endIdx += cpSize;//结尾变大
74
75 return cpSize;
76}
77/* 图形表示写循环buf loop 模式 ,图表示 写之前的样子 @note_pic
78 * endIdx 第二阶段拷贝
79 * | | |
80 * X X X X X X X X 0 0 0 0 0 0 0 0 X X X X X X X X
81 * | | |
82 * 第一阶段拷贝 startIdx
83 *///写操作的是endIdx | X 表示剩余size index 从左到右递减
84STATIC UINT32 OsCirBufWriteLoop(CirBuf *cirbufCB, const CHAR *buf, UINT32 size)
85{
86 UINT32 right, cpSize;
87 errno_t err;
88
89 right = cirbufCB->size - cirbufCB->endIdx;//先计算右边部分
90 cpSize = (right < size) ? right : size;//算出cpSize,很可能要分两次
91
92 err = memcpy_s(cirbufCB->fifo + cirbufCB->endIdx, right, buf, cpSize);//先拷贝一部分
93 if (err != EOK) {
94 return 0;
95 }
96
97 cirbufCB->remain -= cpSize;//写完了那总剩余size肯定是要减少的
98 cirbufCB->endIdx += cpSize;//endIdx 增加,一直往后移
99 if (cirbufCB->endIdx == cirbufCB->size) {//这个相当于移到最后一个了
100 cirbufCB->endIdx = 0;//循环从这里开始
101 }
102
103 if (cpSize == size) {//拷贝完了的情况
104 return size;//返回size
105 } else {
106 cpSize += OsCirBufWriteLinear(cirbufCB, buf + cpSize, size - cpSize);//需第二次拷贝
107 }
108
109 return cpSize;
110}
111///写入数据到循环buf区
112UINT32 LOS_CirBufWrite(CirBuf *cirbufCB, const CHAR *buf, UINT32 size)
113{
114 UINT32 cpSize = 0;
115 UINT32 intSave;
116
117 if ((cirbufCB == NULL) || (buf == NULL) || (size == 0) || (cirbufCB->status != CBUF_USED)) {
118 return 0;
119 }
120
121 LOS_SpinLockSave(&cirbufCB->lock, &intSave);
122
123 if ((cirbufCB->fifo == NULL) || (cirbufCB->remain == 0)) {
124 goto EXIT;;
125 }
126
127 if (cirbufCB->startIdx <= cirbufCB->endIdx) {//开始位置在前面
128 cpSize = OsCirBufWriteLoop(cirbufCB, buf, size);//循环方式写入,分两次拷贝
129 } else {
130 cpSize = OsCirBufWriteLinear(cirbufCB, buf, size);//线性方式写入,分一次拷贝
131 }
132
133EXIT:
134 LOS_SpinUnlockRestore(&cirbufCB->lock, intSave);
135 return cpSize;
136}
137/* 图形表示读线性buf linear 模式 ,图表示 读之前的样子 @note_pic
138 * endIdx
139 * |
140 * X X X X X X X X 0 0 0 0 0 0 0 0 X X X X X X X X
141 * |
142 * startIdx
143 *///读操作的是startIdx | X 表示剩余size index 从左到右递减
144STATIC UINT32 OsCirBufReadLinear(CirBuf *cirbufCB, CHAR *buf, UINT32 size)
145{
146 UINT32 cpSize, remain;
147 errno_t err;
148
149 remain = cirbufCB->endIdx - cirbufCB->startIdx;//这里表示剩余可读区
150 cpSize = (remain < size) ? remain : size;
151
152 if (cpSize == 0) {
153 return 0;
154 }
155
156 err = memcpy_s(buf, size, cirbufCB->fifo + cirbufCB->startIdx, cpSize);//完成拷贝
157 if (err != EOK) {
158 return 0;
159 }
160
161 cirbufCB->remain += cpSize;//读完了那总剩余size肯定是要增加的
162 cirbufCB->startIdx += cpSize;//startIdx也要往前移动
163
164 return cpSize;
165}
166/* 图形表示读循环buf loop 模式 ,图表示 读之前的样子 @note_pic
167 * startIdx
168 * |
169 * 0 0 0 0 0 0 0 0 X X X X X X X X 0 0 0 0 0 0
170 * |
171 * endIdx
172 *///读操作的是startIdx | X 表示剩余size index 从左到右递减
173STATIC UINT32 OsCirBufReadLoop(CirBuf *cirbufCB, CHAR *buf, UINT32 size)
174{
175 UINT32 right, cpSize;
176 errno_t err;
177
178 right = cirbufCB->size - cirbufCB->startIdx;//先算出要读取的部分
179 cpSize = (right < size) ? right : size;
180
181 err = memcpy_s(buf, size, cirbufCB->fifo + cirbufCB->startIdx, cpSize);//先读第一部分数据
182 if (err != EOK) {
183 return 0;
184 }
185
186 cirbufCB->remain += cpSize;//读完了那总剩余size肯定是要增加的
187 cirbufCB->startIdx += cpSize;//startIdx也要往前移动
188 if (cirbufCB->startIdx == cirbufCB->size) {//如果移动到头了
189 cirbufCB->startIdx = 0;//循环buf的关键,新的循环开始了
190 }
191
192 if (cpSize < size) {
193 cpSize += OsCirBufReadLinear(cirbufCB, buf + cpSize, size - cpSize);//剩余的就交给线性方式读取了
194 }
195
196 return cpSize;
197}
198///读取循环buf的数据
199UINT32 LOS_CirBufRead(CirBuf *cirbufCB, CHAR *buf, UINT32 size)
200{
201 UINT32 cpSize = 0;
202 UINT32 intSave;
203
204 if ((cirbufCB == NULL) || (buf == NULL) || (size == 0) || (cirbufCB->status != CBUF_USED)) {
205 return 0;
206 }
207
208 LOS_SpinLockSave(&cirbufCB->lock, &intSave);
209
210 if ((cirbufCB->fifo == NULL) || (cirbufCB->remain == cirbufCB->size)) {
211 goto EXIT;
212 }
213
214 if (cirbufCB->startIdx >= cirbufCB->endIdx) {//开始位置大于结束位置的情况怎么读
215 cpSize = OsCirBufReadLoop(cirbufCB, buf, size);//循环读取buf
216 } else {//开始位置小于结束位置的情况怎么读
217 cpSize = OsCirBufReadLinear(cirbufCB, buf, size);//线性读取,读取 endIdx - startIdx 部分就行了,所以是线性读取
218 }
219
220EXIT:
221 LOS_SpinUnlockRestore(&cirbufCB->lock, intSave);
222 return cpSize;
223}
224///初始化循环buf
225UINT32 LOS_CirBufInit(CirBuf *cirbufCB, CHAR *fifo, UINT32 size)
226{
227 if ((cirbufCB == NULL) || (fifo == NULL)) {
228 return LOS_NOK;
229 }
230
231 (VOID)memset_s(cirbufCB, sizeof(CirBuf), 0, sizeof(CirBuf));//清0
232 LOS_SpinInit(&cirbufCB->lock);//自旋锁初始化
233 cirbufCB->size = size; //记录size
234 cirbufCB->remain = size;//剩余size
235 cirbufCB->status = CBUF_USED;//标记为已使用
236 cirbufCB->fifo = fifo; //顺序buf ,这1K buf 是循环利用
237
238 return LOS_OK;
239}
240///删除初始化操作,其实就是清0
242{
243 (VOID)memset_s(cirbufCB, sizeof(CirBuf), 0, sizeof(CirBuf));
244}
245
STATIC UINT32 OsCirBufReadLoop(CirBuf *cirbufCB, CHAR *buf, UINT32 size)
Definition: los_cir_buf.c:173
UINT32 LOS_CirBufRead(CirBuf *cirbufCB, CHAR *buf, UINT32 size)
读取循环buf的数据
Definition: los_cir_buf.c:199
UINT32 LOS_CirBufWrite(CirBuf *cirbufCB, const CHAR *buf, UINT32 size)
写入数据到循环buf区
Definition: los_cir_buf.c:112
UINT32 LOS_CirBufInit(CirBuf *cirbufCB, CHAR *fifo, UINT32 size)
初始化循环buf
Definition: los_cir_buf.c:225
STATIC UINT32 OsCirBufWriteLinear(CirBuf *cirbufCB, const CHAR *buf, UINT32 size)
Definition: los_cir_buf.c:56
STATIC UINT32 OsCirBufReadLinear(CirBuf *cirbufCB, CHAR *buf, UINT32 size)
Definition: los_cir_buf.c:144
UINT32 LOS_CirBufUsedSize(CirBuf *cirbufCB)
返回循环buf已使用的大小
Definition: los_cir_buf.c:37
STATIC UINT32 OsCirBufWriteLoop(CirBuf *cirbufCB, const CHAR *buf, UINT32 size)
Definition: los_cir_buf.c:84
VOID LOS_CirBufDeinit(CirBuf *cirbufCB)
删除初始化操作,其实就是清0
Definition: los_cir_buf.c:241
@ CBUF_USED
Definition: los_cir_buf.h:47
VOID LOS_SpinUnlockRestore(SPIN_LOCK_S *lock, UINT32 intSave)
Definition: los_spinlock.c:108
VOID LOS_SpinLockSave(SPIN_LOCK_S *lock, UINT32 *intSave)
Definition: los_spinlock.c:98
VOID LOS_SpinInit(SPIN_LOCK_S *lock)
Definition: los_spinlock.c:37
unsigned int UINT32
Definition: los_typedef.h:57
char CHAR
Definition: los_typedef.h:63
SPIN_LOCK_S lock
Definition: los_cir_buf.h:55
UINT32 endIdx
Definition: los_cir_buf.h:52
UINT32 size
Definition: los_cir_buf.h:53
UINT32 startIdx
Definition: los_cir_buf.h:51
CirBufStatus status
Definition: los_cir_buf.h:56
UINT32 remain
Definition: los_cir_buf.h:54
CHAR * fifo
Definition: los_cir_buf.h:57
if(tv==NULL)
Definition: time.c:430