NetBurner 3.5.0
PDF Version
 
buffers.h
Go to the documentation of this file.
1/*NB_REVISION*/
2
3/*NB_COPYRIGHT*/
4
18/* This file provides the definitions for handling Buffers */
19
20#include <constants.h> // Added 3-22-12, dciliske
21
22#ifndef _NB_BUFFERS_H
23#define _NB_BUFFERS_H
24
25#ifdef _DEBUG
26#define BUFFER_DIAG
27#endif
28
29#include <basictypes.h>
30#include <nbrtos.h>
31
32struct pool_buffer; /*Forward declaration*/
33typedef struct pool_buffer *PoolPtr;
34typedef volatile PoolPtr VPoolPtr;
35
36/*The buffer states that define the ownership of the buffer */
37#define BO_UNUSED 0 /*The buffer is free*/
38#define BO_SOFTWARE 1 /*The buffer belongs to some software function.*/
39#define BO_PRX 2 /*The buffer is to be used for the RX function.*/
40#define BO_PTXF 3 /*The buffer is to be TXed and then freeded*/
41#define BO_PTXS 4 /*The buffer is to be TXed and then set to S/W owns.*/
42
43/*The buffer state flags */
44#define BS_PHY_BCAST 1 /*The underlying packet is to/from a physical layer broadcast address.*/
45#define BS_IP_BCAST 2 /*The underlying packet is to/from a layer 3 broadcast address.*/
46#define BS_IP_LOCAL_NET 4 /*The underlying packet is to/from the local subnet.*/
47#define BS_TCP_PUSH 8 /*The push flag was set on RX.*/
48#define BS_PHY_802_3 0x10 /*The network wants 802_3 encapsulation*/
49#define BS_VLAN 0x20 /*The network wants 802_3 encapsulation*/
50#define BS_DBG_LOG 0x80 /*This is a debug log buffer. Do *not* log operations on it.*/
51
52#ifdef BUFFER_DIAG
53#define BUFFER_DIAG_WORD_COUNT 4
54#else
55#define BUFFER_DIAG_WORD_COUNT 0
56#endif
57#ifdef NET_SHIFT16
58#define BUF_PREDATA_SENTINAL_LEN (8)
59#define BUF_PREDATA_PADLEN 8
60#define BUF_POSTDATA_PADLEN 3
61#define BUF_POSTDATA_SENTINAL_LEN (11 - BUFFER_DIAG_WORD_COUNT)
62#else
63#define BUF_PREDATA_SENTINAL_LEN (8)
64#define BUF_PREDATA_PADLEN 6
65#define BUF_POSTDATA_PADLEN 3
66#define BUF_POSTDATA_SENTINAL_LEN (12 - BUFFER_DIAG_WORD_COUNT)
67#endif
68
69struct pool_buffer : public OS_FIFO_EL
70{
71 // puint8_t pBufQueuePointer; /* For the OS FIFO list stuff */
72 uint32_t PreSentinal[BUF_PREDATA_SENTINAL_LEN];
73
74 VPoolPtr pPoolNext; /*A pointer to the next buffer in pool*/
75 VPoolPtr pPoolPrev; /*A pointer to the prev buffer in pool*/
76 vuint32_t dwTime;
77 vuint32_t dwTimeFraction;
78 vuint16_t usedsize;
79 uint8_t bBuffer_state; /*Unused,PRx,PtxF,PtxS,RxC*/
80 uint8_t bBufferFlag;
81 uint8_t bUsageCount;
82 uint8_t bInterfaceNumber;
83 uint8_t bAlignmentPad[BUF_PREDATA_PADLEN];
84 uint8_t pData[ETHER_BUFFER_SIZE]; /*The buffer data*/
85 uint8_t bPostAlignmentPad[BUF_POSTDATA_PADLEN];
86 uint32_t PostSentinal[BUF_POSTDATA_SENTINAL_LEN];
87
88#ifdef BUFFER_DIAG
89 PCSTR m_fAlloc;
90 uint32_t m_fline;
91 uint32_t m_fill;
92 uint32_t m_fill2;
93#endif /* BUFFER_DIAG */
94};
95
96inline uint8_t OSPoolFifoPost(OS_FIFO *pFifo, PoolPtr pToPost)
97{
98 return pFifo->Post(pToPost);
99}
100
101inline uint8_t OSPoolFifoPostFirst(OS_FIFO *pFifo, PoolPtr pToPost)
102{
103 return pFifo->PostFirst(pToPost);
104}
105
106inline PoolPtr OSPoolFifoPend(OS_FIFO *pFifo, uint16_t timeout)
107{
108 return static_cast<PoolPtr>(pFifo->Pend(timeout));
109}
110
111inline PoolPtr OSPoolFifoPend(OS_FIFO *pFifo, TickTimeout timeout)
112{
113 return static_cast<PoolPtr>(pFifo->Pend(timeout));
114}
115
116
117inline PoolPtr OSPoolFifoPendNoWait(OS_FIFO *pFifo)
118{
119 return static_cast<PoolPtr>(pFifo->PendNoWait());
120}
121
122/*Buffer operations*/
123
124#ifdef BUFFER_DIAG
125void ShowBuffers();
126void ShowBuffers_Web(int sockfd);
127PoolPtr GetBufferX(PCSTR file, int line); /*Alocates a Software buffer and returns the buffer number.*/
128#define GetBuffer() GetBufferX(__FILE__, __LINE__)
129#ifdef FAST_BUFFERS
130PoolPtr GetFastBufferX(PCSTR file, int line); /*Alocates a Software buffer and returns the buffer number.*/
131#define GetFastBuffer() GetFastBufferX(__FILE__, __LINE__)
132#else /* #ifdef FAST_BUFFERS */
133#define GetFastBuffer() GetBufferX(__FILE__, __LINE__)
134#endif /* #ifdef FAST_BUFFERS */
135void FreeBufferX(PoolPtr nbuf, PCSTR file, int line); /*Frees a buffer and places it in the unused state.*/
136#define FreeBuffer(x) FreeBufferX(x, __FILE__, __LINE__)
137
138void ChangeOwnerX(PoolPtr nbuf, PCSTR file, int line); /*Frees a buffer and places it in the unused state.*/
139#define ChangeOwner(x) ChangeOwnerX(x, __FILE__, __LINE__)
140#else
141PoolPtr GetBuffer(); /*Alocates a Software buffer and returns the buffer number.*/
142#ifdef FAST_BUFFERS
143PoolPtr GetFastBuffer(); /*Alocates a Software buffer (potentially from the fast pool) pool and returns the buffer number.*/
144#else /* #ifdef FAST_BUFFERS */
145#define GetFastBuffer() GetBuffer()
146#endif /* #ifdef FAST_BUFFERS */
147void FreeBuffer(PoolPtr nbuf); /*Frees a buffer and places it in the unused state.*/
148#define ChangeOwner(x)
149#endif
150
151#ifdef BUFFER_DIAG_LOG
152#include <syslog.h>
153extern uint32_t bufLogID;
154#define LOG_DEST AsciiToIp("10.1.1.3")
155#define SET_LOG_DEST \
156 { \
157 extern IPADDR SysLogAddress; \
158 SysLogAddress = LOG_DEST; \
159 }
160#define LOG_INTF 2
161#define BuffLog_GetFmt "%0.8lu) GET - P: %p, L: %0.4d, F: %s\r\n"
162#define BuffLog_FreeFmt "%0.8lu) FREE - P: %p, L: %0.4d, F: %s\r\n"
163#define BuffLog_GetLF(p, l, f) SysLogVia(LOG_INTF, BuffLog_GetFmt, bufLogID++, p, l, f)
164#define BuffLog_FreeLF(p, l, f) SysLogVia(LOG_INTF, BuffLog_FreeFmt, bufLogID++, p, l, f)
165#define BuffLog_Get(p) BuffLog_GetLF(p, __LINE__, __FILE__)
166#define BuffLog_Free(p) BuffLog_FreeLF(p, __LINE__, __FILE__)
167#define BuffLog_Write(p) SysLogVia(LOG_INTF, "WRITE - P: %p, L: %0.4d, F: %s\r\n", p, __LINE__, __FILE__)
168#define BuffLog_Read(p) SysLogVia(LOG_INTF, "READ - P: %p, L: %0.4d, F: %s\r\n", p, __LINE__, __FILE__)
169#else
170#define BuffLog_Get(p)
171#define BuffLog_Free(p)
172#define BuffLog_Write(p)
173#define BuffLog_Read(p)
174#endif
175/*Frees a linked list of buffers and places them in the unused state.*/
176void FreeBufferList(PoolPtr nbuf);
177
178void IncUsageCount(PoolPtr pp);
179
204uint16_t GetFreeCount();
205
206#ifdef BUFFER_WATERMARK
207uint16_t GetMinFreeCount();
208uint16_t GetMaxFreeCount();
209#endif
210
211void InitBuffers(); /* Initializes the buffer system*/
212
217void ShowBuffer(PoolPtr p);
218
219class buffer_list
220{
221 public:
222 PoolPtr m_Head;
223 PoolPtr m_Tail;
224#ifdef BUFFER_WATERMARK
225 uint16_t m_wMaxElements;
226 uint16_t m_wMinElements;
227#endif
228 uint16_t m_wElements;
229 void InsertHead(PoolPtr buffer);
230 void InsertTail(PoolPtr buffer);
231 void InsertBefore(PoolPtr buf2insert, PoolPtr b4buffer);
232 void InsertAfter(PoolPtr buf2insert, PoolPtr after_buffer);
233 void Remove(PoolPtr buffer);
234 PoolPtr RemoveHead();
235 PoolPtr RemoveTail();
236 buffer_list()
237 {
238 m_Head = 0;
239 m_Tail = 0;
240 m_wElements = 0;
241#ifdef BUFFER_WATERMARK
242 m_wMaxElements=0;
243 m_wMinElements=0;
244#endif
245
246 }
247 uint16_t GetCount() { return m_wElements; };
248#ifdef BUFFER_WATERMARK
249 uint16_t GetMaxCount() { return m_wMaxElements; };
250 uint16_t GetMinCount() { return m_wMinElements; };
251#endif
252};
253
254/*
255This defines a class for storing an array of bytes in a list of buffers.
256It is used for I/O buffers
257*/
258class fifo_buffer_storage
259{
260 private:
261 PoolPtr m_Head;
262 PoolPtr m_Tail;
263 OS_CRIT m_critical_section;
264 int m_BytesStored;
265 uint32_t m_startOffset;
266 uint32_t m_maxChunkLen;
267 uint8_t m_Segments_Stored;
268 uint8_t m_MaxSegments; /*Stores the max number of segments allowed fore this buffer*/
269 bool m_checksumWrites;
270 uint8_t m_buffer_pool;
271
272 // storage access/update functions to be used by BufPtr.
273 // DO NOT CALL WITHOUT LOCKING STRUCT FIRST
274 uint8_t *GetWritePtr(uint32_t *remLen);
275 void WriteDone(uint32_t bytesCopied);
276
277 uint8_t *GetReadPtr(uint32_t *remLen);
278 void ReadDone(uint32_t bytesCopied);
279
280 public:
281 /* Accessor for internal struct buffer pointers. NOT IRQ SAFE */
282 class WriteBufPtr
283 {
284 WriteBufPtr();
285 fifo_buffer_storage &m_fifo;
286 uint8_t *pBuf;
287 uint32_t bufLen;
288 uint32_t copied;
289
290 public:
291 WriteBufPtr(fifo_buffer_storage &fifo) : m_fifo(fifo), copied(0)
292 {
293 m_fifo.m_critical_section.Enter();
294 pBuf = m_fifo.GetWritePtr(&bufLen);
295 }
296 ~WriteBufPtr()
297 {
298 m_fifo.WriteDone(copied);
299 m_fifo.m_critical_section.Leave();
300 }
301
302 inline uint8_t *buf() { return pBuf + copied; }
303 inline uint32_t len() { return bufLen - copied; }
304 void ByteCopyDone(uint32_t bytesCopied) { copied += (bytesCopied <= (bufLen - copied)) ? bytesCopied : (bufLen - copied); }
305 };
306 /* Accessor for internal struct buffer pointers. NOT IRQ SAFE */
307 class ReadBufPtr
308 {
309 ReadBufPtr();
310 fifo_buffer_storage &m_fifo;
311 uint8_t *pBuf;
312 uint32_t bufLen;
313 uint32_t copied;
314
315 public:
316 ReadBufPtr(fifo_buffer_storage &fifo) : m_fifo(fifo), copied(0)
317 {
318 m_fifo.m_critical_section.Enter();
319 pBuf = m_fifo.GetReadPtr(&bufLen);
320 }
321 ~ReadBufPtr()
322 {
323 m_fifo.ReadDone(copied);
324 m_fifo.m_critical_section.Leave();
325 }
326
327 inline uint8_t *buf() { return pBuf + copied; }
328 inline uint32_t len() { return bufLen - copied; }
329 void ByteCopyDone(uint32_t bytesCopied) { copied += (bytesCopied <= (bufLen - copied)) ? bytesCopied : (bufLen - copied); }
330 };
331 class PeekIterator
332 {
333 PeekIterator();
334 fifo_buffer_storage &m_fifo;
335 PoolPtr pCurrPP;
336 uint8_t *peekPtr;
337 bool locked;
338
339 PeekIterator(const PeekIterator &rhs)
340 : m_fifo(rhs.m_fifo), pCurrPP(rhs.pCurrPP), peekPtr(rhs.peekPtr), locked(false)
341 {
342 if (pCurrPP)
343 {
344 m_fifo.m_critical_section.Enter();
345 locked = true;
346 }
347 }
348
349 public:
350 PeekIterator(fifo_buffer_storage &fifo, bool begin = true) : m_fifo(fifo), pCurrPP(NULL), peekPtr(NULL), locked(false)
351 {
352 if (begin)
353 {
354 m_fifo.m_critical_section.Enter();
355 locked = true;
356 pCurrPP = m_fifo.m_Head;
357 if (pCurrPP) { peekPtr = pCurrPP->pAsBytePtr; }
358 }
359 }
360 ~PeekIterator() { if (locked) m_fifo.m_critical_section.Leave(); }
361
362 PeekIterator &operator++(); // preincrement
363 PeekIterator operator++(int); // postincrement
364 uint8_t operator*(); // dereference
365 int32_t operator-(const PeekIterator &rhs);
366 PeekIterator &operator+=(int);
367
368 operator uint16_t() const;
369 operator uint32_t() const;
370
371 inline bool operator==(const PeekIterator &rhs)
372 {
373 return ((&m_fifo == &(rhs.m_fifo)) && (pCurrPP == rhs.pCurrPP) && (peekPtr == rhs.peekPtr));
374 }
375 bool operator!=(const PeekIterator &rhs) { return !(*this == rhs); }
376 };
377
378 friend class WriteBufPtr;
379 friend class ReadBufPtr;
380 friend class PeekIterator;
381
382 uint32_t LongSpaceAvail();
383
384 /*The number of available bytes of storage*/
385 uint16_t SpaceAvail();
386 /*The number of bytes used.*/
387 uint16_t SpaceUsed();
388
389 /*Read data from the buffer*/
390 /*REturns the number of bytes read*/
391 int ReadData(puint8_t pCopyTo, int max_bytes);
392
393 /* Peek at the next data byte */
394 uint8_t PeekData(int idx = -1);
395
396 int ReadDatawSum(puint8_t pCopyTo, int max_bytes, uint32_t &csum);
397
398 // Returns number of bytes skipped
399 int SkipData(int skip);
400
401 int ReadTerminatedData(puint8_t pCopyTo, int max_bytes, uint8_t term_char);
402
403 /* Advanced functions for no-copy buffer usage */
404 int PushBuffer(PoolPtr pp, int dataLen, int startOffset);
405 PoolPtr PullBuffer();
406 PoolPtr PullBuffer(uint32_t &csum);
407 inline PoolPtr PeekBuffer() { return m_Head; }
408 void SetFifoLock(bool locked);
409
410 /*Write Data to the buffer*/
411 /*Returns the number of bytes read*/
412 int WriteData(puint8_t pCopyFrom, int num_bytes);
413
414 void RemoveLast(); // Remove last char
415
416 /*Peek Iterator methods for looking at queued data*/
417 PeekIterator Peek_Begin();
418 PeekIterator Peek_End();
419
420 /*Returns true if empty*/
421 BOOL Empty();
422
423 /*Returns True if Full*/
424 BOOL Full();
425
426 /*Build one */
427 fifo_buffer_storage(uint8_t max_buffers = 0, uint8_t use_fromisr = 1, uint8_t use_fast_buffs = 1);
428 ~fifo_buffer_storage();
429
430 /*Reset frees the storage*/
431 void Reset(uint8_t max_buffers);
432
433 void SetMaxBuffers(uint8_t max_buffers);
434 inline void SetMaxChunkLen(uint32_t maxStorage)
435 {
436 m_maxChunkLen = (maxStorage > (ETHER_BUFFER_SIZE - m_startOffset)) ? (ETHER_BUFFER_SIZE - m_startOffset) : maxStorage;
437 }
438 inline void SetStartOffset(uint32_t offset)
439 {
440 m_startOffset = offset;
441 SetMaxChunkLen(m_maxChunkLen);
442 }
443 inline uint32_t GetMaxBuffers() { return m_MaxSegments; }
444 inline uint32_t GetMaxChunkLen() { return m_maxChunkLen; }
445 inline uint32_t GetStartOffset() { return m_startOffset; }
446 inline void SetWriteChecksum(bool summingOn) { m_checksumWrites = summingOn; }
447 inline uint32_t GetMinimumFullSize(int maxSegments = -1)
448 {
449 if (maxSegments < 0)
450 maxSegments = m_MaxSegments;
451 return (m_maxChunkLen * (maxSegments-1))+1;
452 }
453
454 /*Init initializes it to zero*/
455 void Init(uint8_t max_buffers, uint8_t use_fromisr = 1, uint8_t use_fast_buffs = 1);
456} __attribute__((packed));
457
458class SMPoolPtr
459{
460 PoolPtr m_pp;
461
462 public:
463 SMPoolPtr()
464 {
465 m_pp = GetBuffer();
466 BuffLog_Get(m_pp);
467 }
468 SMPoolPtr(const PoolPtr pp) { m_pp = pp; }
469 SMPoolPtr(const SMPoolPtr &pp) { m_pp = pp.m_pp; }
470 ~SMPoolPtr()
471 {
472 if (m_pp)
473 {
474 FreeBuffer(m_pp);
475 BuffLog_Free(m_pp);
476 }
477 }
478
479 inline const SMPoolPtr &operator=(const PoolPtr pp)
480 {
481 m_pp = pp;
482 return *this;
483 }
484 inline const SMPoolPtr &operator=(const SMPoolPtr &pp)
485 {
486 m_pp = pp.m_pp;
487 return *this;
488 }
489 inline pool_buffer &operator*() { return *m_pp; }
490 inline PoolPtr &operator->() { return m_pp; }
491 explicit operator PoolPtr() { return m_pp; }
492};
493
494#endif
495
void WriteData(int fd, const char *c, int siz)
Definition JSON/DemoNetBurner/src/gifCompress.cpp:142
TickTimeout objects are used to facilitate sequential function calls with timeout parameters that nee...
Definition nbrtos.h:157
void ShowBuffer(PoolPtr p)
Prints a pool buffer to stdout.
uint16_t GetFreeCount()
Returns the number of free buffers in the system. Buffers are used for both serial and network interf...
#define ETHER_BUFFER_SIZE
Definition nbrtos/include/constants.h:54
NetBurner System Constants.
NetBurner Real-Time Operating System (NBRTOS) API.
An OS_CRIT object is used to establish critical sections of code that can only be run by one task at ...
Definition nbrtos.h:1084
uint8_t Enter(TickTimeout &t)
Request to Enter/Claim the critical section.
uint8_t Leave()
Release the critical section.
Definition nbrtos.h:907
OS_FIFO_EL * PendNoWait(uint8_t &result)
Attempts to pend a structure to the FIFO, but does not wait.
uint8_t PostFirst(OS_FIFO_EL *pToPost)
Post a message to the head of the FIFO.
OS_FIFO_EL * Pend(uint32_t timeoutTicks, uint8_t &result)
Wait the specified number of time ticks for some other task to post to the FIFO.
Definition nbrtos.h:968
uint8_t Post(OS_FIFO_EL *pToPost)
Post a message to the next available location in the FIFO.
OS_FIFO element definition.
Definition nbrtos.h:884
puint8_t pAsBytePtr
Next OS_FIFO element data byte pointer.
Definition nbrtos.h:893