NetBurner 3.1
buffers.h
Go to the documentation of this file.
1 /*NB_REVISION*/
2 
3 /*NB_COPYRIGHT*/
4 
13 /* This file provides the definitions for handling Buffers */
14 
15 #include <constants.h> // Added 3-22-12, dciliske
16 
17 #ifndef _NB_BUFFERS_H
18 #define _NB_BUFFERS_H
19 
20 #ifdef _DEBUG
21 #define BUFFER_DIAG
22 #endif
23 
24 #include <basictypes.h>
25 #include <nbrtos.h>
26 
27 struct pool_buffer; /*Forward declaration*/
28 typedef struct pool_buffer *PoolPtr;
29 typedef volatile PoolPtr VPoolPtr;
30 
31 /*The buffer states that define the ownership of the buffer */
32 #define BO_UNUSED 0 /*The buffer is free*/
33 #define BO_SOFTWARE 1 /*The buffer belongs to some software function.*/
34 #define BO_PRX 2 /*The buffer is to be used for the RX function.*/
35 #define BO_PTXF 3 /*The buffer is to be TXed and then freeded*/
36 #define BO_PTXS 4 /*The buffer is to be TXed and then set to S/W owns.*/
37 
38 /*The buffer state flags */
39 #define BS_PHY_BCAST 1 /*The underlying packet is to/from a physical layer broadcast address.*/
40 #define BS_IP_BCAST 2 /*The underlying packet is to/from a layer 3 broadcast address.*/
41 #define BS_IP_LOCAL_NET 4 /*The underlying packet is to/from the local subnet.*/
42 #define BS_TCP_PUSH 8 /*The push flag was set on RX.*/
43 #define BS_PHY_802_3 0x10 /*The network wants 802_3 encapsulation*/
44 #define BS_VLAN 0x20 /*The network wants 802_3 encapsulation*/
45 
46 struct pool_buffer : public OS_FIFO_EL
47 {
48  // puint8_t pBufQueuePointer; /* For the OS FIFO list stuff */
49  uint32_t PreSentinal[16];
50 
51  VPoolPtr pPoolNext; /*A pointer to the next buffer in pool*/
52  VPoolPtr pPoolPrev; /*A pointer to the prev buffer in pool*/
53  vuint32_t dwTime;
54  vuint32_t dwTimeFraction;
55  vuint16_t usedsize;
56  uint8_t bBuffer_state; /*Unused,PRx,PtxF,PtxS,RxC*/
57  uint8_t bBufferFlag;
58  uint8_t bUsageCount;
59  uint8_t bInterfaceNumber;
60  uint8_t bAlignmentPad[6];
61  uint8_t pData[ETHER_BUFFER_SIZE]; /*The buffer data*/
62  uint8_t bPostAlignmentPad[3];
63  uint32_t PostSentinal[16];
64 
65 #ifdef BUFFER_DIAG
66  PCSTR m_fAlloc;
67  uint32_t m_fline;
68  uint32_t m_fill;
69  uint32_t m_fill2;
70 #endif /* BUFFER_DIAG */
71 };
72 
73 inline uint8_t OSPoolFifoPost(OS_FIFO *pFifo, PoolPtr pToPost)
74 {
75  return pFifo->Post(pToPost);
76 }
77 
78 inline uint8_t OSPoolFifoPostFirst(OS_FIFO *pFifo, PoolPtr pToPost)
79 {
80  return pFifo->PostFirst(pToPost);
81 }
82 
83 inline PoolPtr OSPoolFifoPend(OS_FIFO *pFifo, uint16_t timeout)
84 {
85  return static_cast<PoolPtr>(pFifo->Pend(timeout));
86 }
87 
88 inline PoolPtr OSPoolFifoPendNoWait(OS_FIFO *pFifo)
89 {
90  return static_cast<PoolPtr>(pFifo->PendNoWait());
91 }
92 
93 /*Buffer operations*/
94 
95 #ifdef BUFFER_DIAG
96 void ShowBuffers();
97 void ShowBuffers_Web(int sockfd);
98 PoolPtr GetBufferX(PCSTR file, int line); /*Alocates a Software buffer and returns the buffer number.*/
99 #define GetBuffer() GetBufferX(__FILE__, __LINE__)
100 #ifdef FAST_BUFFERS
101 PoolPtr GetFastBufferX(PCSTR file, int line); /*Alocates a Software buffer and returns the buffer number.*/
102 #define GetFastBuffer() GetFastBufferX(__FILE__, __LINE__)
103 #else /* #ifdef FAST_BUFFERS */
104 #define GetFastBuffer() GetBufferX(__FILE__, __LINE__)
105 #endif /* #ifdef FAST_BUFFERS */
106 void FreeBufferX(PoolPtr nbuf, PCSTR file, int line); /*Frees a buffer and places it in the unused state.*/
107 #define FreeBuffer(x) FreeBufferX(x, __FILE__, __LINE__)
108 
109 void ChangeOwnerX(PoolPtr nbuf, PCSTR file, int line); /*Frees a buffer and places it in the unused state.*/
110 #define ChangeOwner(x) ChangeOwnerX(x, __FILE__, __LINE__)
111 #else
112 PoolPtr GetBuffer(); /*Alocates a Software buffer and returns the buffer number.*/
113 #ifdef FAST_BUFFERS
114 PoolPtr GetFastBuffer(); /*Alocates a Software buffer (potentially from the fast pool) pool and returns the buffer number.*/
115 #else /* #ifdef FAST_BUFFERS */
116 #define GetFastBuffer() GetBuffer()
117 #endif /* #ifdef FAST_BUFFERS */
118 void FreeBuffer(PoolPtr nbuf); /*Frees a buffer and places it in the unused state.*/
119 #define ChangeOwner(x)
120 #endif
121 
122 #ifdef BUFFER_DIAG_LOG
123 #include <syslog.h>
124 #define LOG_DEST 0x0A010103 // 10.1.1.3
125 #define SET_LOG_DEST \
126  { \
127  extern IPADDR4 SysLogAddress; \
128  SysLogAddress = LOG_DEST; \
129  }
130 #define LOG_INTF 1
131 #define BuffLog_Get(p) SysLogVia(LOG_INTF, "GET - P: %p, L: %0.4d, F: %s\r\n", p, __LINE__, __FILE__)
132 #define BuffLog_Free(p) SysLogVia(LOG_INTF, "FREE - P: %p, L: %0.4d, F: %s\r\n", p, __LINE__, __FILE__)
133 #define BuffLog_Write(p) SysLogVia(LOG_INTF, "WRITE - P: %p, L: %0.4d, F: %s\r\n", p, __LINE__, __FILE__)
134 #define BuffLog_Read(p) SysLogVia(LOG_INTF, "READ - P: %p, L: %0.4d, F: %s\r\n", p, __LINE__, __FILE__)
135 #else
136 #define BuffLog_Get(p)
137 #define BuffLog_Free(p)
138 #define BuffLog_Write(p)
139 #define BuffLog_Read(p)
140 #endif
141 /*Frees a linked list of buffers and places them in the unused state.*/
142 void FreeBufferList(PoolPtr nbuf);
143 
144 void IncUsageCount(PoolPtr pp);
145 
168 uint16_t GetFreeCount();
169 
170 void InitBuffers(); /* Initializes the buffer system*/
171 
176 void ShowBuffer(PoolPtr p);
177 
178 class buffer_list
179 {
180  public:
181  PoolPtr m_Head;
182  PoolPtr m_Tail;
183  uint16_t m_wElements;
184  void InsertHead(PoolPtr buffer);
185  void InsertTail(PoolPtr buffer);
186  void InsertBefore(PoolPtr buf2insert, PoolPtr b4buffer);
187  void InsertAfter(PoolPtr buf2insert, PoolPtr after_buffer);
188  void Remove(PoolPtr buffer);
189  PoolPtr RemoveHead();
190  PoolPtr RemoveTail();
191  buffer_list()
192  {
193  m_Head = 0;
194  m_Tail = 0;
195  m_wElements = 0;
196  }
197  uint16_t GetCount() { return m_wElements; };
198 };
199 
200 /*
201 This defines a class for storing an array of bytes in a list of buffers.
202 It is used for I/O buffers
203 */
204 class fifo_buffer_storage
205 {
206  private:
207  PoolPtr m_Head;
208  PoolPtr m_Tail;
209  OS_CRIT m_critical_section;
210  int m_BytesStored;
211  uint8_t m_Segments_Stored;
212  uint8_t m_MaxSegments; /*Stores the max number of segments allowed fore this buffer*/
213  uint32_t m_startOffset;
214  uint32_t m_maxChunkLen;
215  bool m_checksumWrites;
216 
217  // storage access/update functions to be used by BufPtr.
218  // DO NOT CALL WITHOUT LOCKING STRUCT FIRST
219  uint8_t *GetWritePtr(uint32_t *remLen);
220  void WriteDone(uint32_t bytesCopied);
221 
222  uint8_t *GetReadPtr(uint32_t *remLen);
223  void ReadDone(uint32_t bytesCopied);
224 
225  public:
226  /* Accessor for internal struct buffer pointers. NOT IRQ SAFE */
227  class WriteBufPtr
228  {
229  WriteBufPtr();
230  fifo_buffer_storage &m_fifo;
231  uint8_t *pBuf;
232  uint32_t bufLen;
233  uint32_t copied;
234 
235  public:
236  WriteBufPtr(fifo_buffer_storage &fifo) : m_fifo(fifo), copied(0)
237  {
238  m_fifo.m_critical_section.Enter();
239  pBuf = m_fifo.GetWritePtr(&bufLen);
240  }
241  ~WriteBufPtr()
242  {
243  m_fifo.WriteDone(copied);
244  m_fifo.m_critical_section.Leave();
245  }
246 
247  inline uint8_t *buf() { return pBuf + copied; }
248  inline uint32_t len() { return bufLen - copied; }
249  void ByteCopyDone(uint32_t bytesCopied) { copied += (bytesCopied <= (bufLen - copied)) ? bytesCopied : (bufLen - copied); }
250  };
251  /* Accessor for internal struct buffer pointers. NOT IRQ SAFE */
252  class ReadBufPtr
253  {
254  ReadBufPtr();
255  fifo_buffer_storage &m_fifo;
256  uint8_t *pBuf;
257  uint32_t bufLen;
258  uint32_t copied;
259 
260  public:
261  ReadBufPtr(fifo_buffer_storage &fifo) : m_fifo(fifo), copied(0)
262  {
263  m_fifo.m_critical_section.Enter();
264  pBuf = m_fifo.GetReadPtr(&bufLen);
265  }
266  ~ReadBufPtr()
267  {
268  m_fifo.ReadDone(copied);
269  m_fifo.m_critical_section.Leave();
270  }
271 
272  inline uint8_t *buf() { return pBuf + copied; }
273  inline uint32_t len() { return bufLen - copied; }
274  void ByteCopyDone(uint32_t bytesCopied) { copied += (bytesCopied <= (bufLen - copied)) ? bytesCopied : (bufLen - copied); }
275  };
276 
277  friend class WriteBufPtr;
278  friend class ReadBufPtr;
279 
280  uint32_t LongSpaceAvail();
281 
282  /*The number of available bytes of storage*/
283  uint16_t SpaceAvail();
284  /*The number of bytes used.*/
285  uint16_t SpaceUsed();
286 
287  /*Read data from the buffer*/
288  /*REturns the number of bytes read*/
289  int ReadData(puint8_t pCopyTo, int max_bytes);
290 
291  /* Peek at the next data byte */
292  uint8_t PeekData();
293 
294  int ReadDatawSum(puint8_t pCopyTo, int max_bytes, uint32_t &csum);
295 
296  // Returns number of bytes skipped
297  int SkipData(int skip);
298 
299  int ReadTerminatedData(puint8_t pCopyTo, int max_bytes, uint8_t term_char);
300 
301  /* Advanced functions for no-copy buffer usage */
302  int PushBuffer(PoolPtr pp, int dataLen, int startOffset);
303  PoolPtr PullBuffer(uint32_t &csum);
304  inline PoolPtr PeekBuffer() { return m_Head; }
305  void SetFifoLock(bool locked);
306 
307  /*Write Data to the buffer*/
308  /*Returns the number of bytes read*/
309  int WriteData(puint8_t pCopyFrom, int num_bytes);
310 
311  void RemoveLast(); // Remove last char
312 
313  /*Returns true if empty*/
314  BOOL Empty();
315 
316  /*Returns True if Full*/
317  BOOL Full();
318 
319  /*Build one */
320  fifo_buffer_storage(uint8_t max_buffers = 0, uint8_t use_fromisr = 1);
321  ~fifo_buffer_storage();
322 
323  /*Reset frees the storage*/
324  void Reset(uint8_t max_buffers);
325 
326  void SetMaxBuffers(uint8_t max_buffers);
327  inline void SetMaxChunkLen(uint32_t maxStorage)
328  {
329  m_maxChunkLen = (maxStorage > (ETHER_BUFFER_SIZE - m_startOffset)) ? (ETHER_BUFFER_SIZE - m_startOffset) : maxStorage;
330  }
331  inline void SetStartOffset(uint32_t offset)
332  {
333  m_startOffset = offset;
334  SetMaxChunkLen(m_maxChunkLen);
335  }
336  inline void SetWriteChecksum(bool summingOn) { m_checksumWrites = summingOn; }
337 
338  /*Init initializes it to zero*/
339  void Init(uint8_t max_buffers, uint8_t use_fromisr = 1);
340 } __attribute__((packed));
341 
342 class SMPoolPtr
343 {
344  PoolPtr m_pp;
345 
346  public:
347  SMPoolPtr() { m_pp = GetBuffer(); }
348  SMPoolPtr(const PoolPtr pp) { m_pp = pp; }
349  SMPoolPtr(const SMPoolPtr &pp) { m_pp = pp.m_pp; }
350  ~SMPoolPtr()
351  {
352  if (m_pp) { FreeBuffer(m_pp); }
353  }
354 
355  inline const SMPoolPtr &operator=(const PoolPtr pp)
356  {
357  m_pp = pp;
358  return *this;
359  }
360  inline const SMPoolPtr &operator=(const SMPoolPtr &pp)
361  {
362  m_pp = pp.m_pp;
363  return *this;
364  }
365  inline pool_buffer &operator*() { return *m_pp; }
366  inline PoolPtr &operator->() { return m_pp; }
367 };
368 
369 #endif
NetBurner Real-Time Operating System API.
A FIFO is used to pass structures from one task to another. Note: Structures to be passed must have a...
Definition: nbrtos.h:736
OS_FIFO_EL * PendNoWait(uint8_t &result)
Checks to see if a structure has been posted to a FIFO, but does not wait.
Definition: nbrtos.cpp:1294
OS_FIFO_EL * Pend(uint32_t timeoutTicks, uint8_t &result)
This function pends on a FIFO for a specified number of ticks.
Definition: nbrtos.cpp:1254
uint8_t Post(OS_FIFO_EL *pToPost)
This function posts to a FIFO object.
Definition: nbrtos.cpp:1318
uint8_t PostFirst(OS_FIFO_EL *pToPost)
This function is identical to Post(), but the element posted is put on the beginning of the FIFO list...
Definition: nbrtos.cpp:1341
uint16_t GetFreeCount()
Returns the number of free buffers in the system. Buffers are used for both serial and network interf...
Definition: buffers.cpp:519
void FreeBufferList(PoolPtr nbuf)
FreeBufferList Frees a linked list of pool buffers. The buffers must be linked by the pNextFifo_El Po...
Definition: buffers.cpp:433
An OS_CRIT object is used to establish critical sections of code that can only be run by one task at ...
Definition: nbrtos.h:893
void WriteData(int fd, const char *c, int siz)
Definition: gifCompress.cpp:142
void ShowBuffer(PoolPtr p)
Prints a pool buffer to stdout.
Definition: buffers.cpp:705