embkernel
 All Classes Functions Variables Typedefs Groups Pages
RtosBuffer.cpp
1 //------------------------------------------------------------------------------
2 //This file is part of embKernel.
3 //See license.txt for the full license governing this code.
4 //------------------------------------------------------------------------------
8 #include "RtosBuffer.hpp"
9 #include "RtosHeap.hpp"
10 
16  RtosSyncObject(size, 0) {
17  mBuffer = (uint8_t*) RtosHeap::alloc(size);
18  if (!mBuffer) {
19  mMaxCount = size;
20  }
21  mIdxIn = 0;
22  mIdxOut = 0;
23 }
24 
28 RtosBuffer::~RtosBuffer() {
29  if (mBuffer) {
30  RtosHeap::free(mBuffer);
31  }
32 }
33 
41 int RtosBuffer::write(const void* buffer, int len, Rtos::TICK tick) {
42  uint8_t* src = (uint8_t*) buffer;
43  int left = len;
44  while (true) {
45  int written = writeChunk(src, left, tick);
46  if (written <= 0) {
47  break;
48  }
49  src += written;
50  left -= written;
51  if (left <= 0) {
52  break;
53  }
54  Rtos::sleep(1);
55  }
56  return (len - left);
57 }
58 
66 int RtosBuffer::writeChunk(const void* buffer, int len, Rtos::TICK tick) {
67  int count = internalGive(tick, len);
68  if (count) {
69  writeBuffer(buffer, count);
70  internalWakeUpWaitingToTake();
71  }
72  exitCritical();
73  return count;
74 }
75 
82 int RtosBuffer::writeFromInt(const void* buffer, int len) {
83  int count = mMaxCount - mCurrentCount;
84  if (count < len) {
85  len = count;
86  }
87  if (len > 0) {
88  mCurrentCount += len;
89  writeBuffer(buffer, len);
90  internalWakeUpWaitingToTake();
91  }
92  return len;
93 }
94 
102 int RtosBuffer::read(void* buffer, int len, Rtos::TICK tick) {
103  uint8_t* dst = (uint8_t*) buffer;
104  int left = len;
105  while (true) {
106  int read = readChunk(dst, left, tick);
107  if (read <= 0) {
108  break;
109  }
110  dst += read;
111  left -= read;
112  if (left <= 0) {
113  break;
114  }
115  Rtos::sleep(1);
116  }
117  return (len - left);
118 }
119 
127 int RtosBuffer::readChunk(void* buffer, int len, Rtos::TICK tick) {
128  int count = internalTake(tick, len);
129  if (count) {
130  readBuffer(buffer, count);
131  internalWakeUpWaitingToGive();
132  }
133  exitCritical();
134  return count;
135 }
136 
143 int RtosBuffer::readFromInt(void* buffer, int len) {
144  if (len > mCurrentCount) {
145  len = mCurrentCount;
146  }
147  if (len >= 0) {
148  mCurrentCount -= len;
149  readBuffer(buffer, len);
150  internalWakeUpWaitingToGive();
151  }
152  return len;
153 }
154 
160 void RtosBuffer::writeBuffer(const void* buffer, int len) {
161  const uint8_t* src = (const uint8_t*) buffer;
162  if (mIdxIn + len > mMaxCount) {
163  int left = mMaxCount - mIdxIn;
164  memcpy(&mBuffer[mIdxIn], src, left);
165  src += left;
166  left = len - left;
167  memcpy(&mBuffer[0], src, left);
168  mIdxIn = left;
169  }
170  else {
171  memcpy(&mBuffer[mIdxIn], src, len);
172  mIdxIn += len;
173  }
174 }
175 
181 void RtosBuffer::readBuffer(void* buffer, int len) {
182  uint8_t* dst = (uint8_t*) buffer;
183  if (mIdxOut + len > mMaxCount) {
184  int left = mMaxCount - mIdxOut;
185  memcpy(dst, &mBuffer[mIdxOut], left);
186  dst += left;
187  left = len - left;
188  memcpy(dst, &mBuffer[0], left);
189  mIdxOut = left;
190  }
191  else {
192  memcpy(dst, &mBuffer[mIdxOut], len);
193  mIdxOut += len;
194  }
195 }