Choco OS  V.0.16.9.0
Join to the chocolate world
oc_queue.c
Go to the documentation of this file.
1 
27 #include <oc_object.h>
28 #include <oc_queue.h>
29 #include <oc_list.h>
30 #include <oc_stdlib.h>
31 #include <oc_null.h>
32 #include <oc_thread.h>
33 #include <oc_semaphore.h>
34 #include <oc_intman.h>
35 
41 #define _________________________________________TYPES_SECTION______________________________________________________________________________
42 
43 typedef struct Queue_t
44 {
45  oC_ObjectControl_t ObjectControl;
46  oC_MemorySize_t GetIndex;
47  oC_MemorySize_t PutIndex;
48  oC_Semaphore_t UsedSlotsSemaphore;
49  oC_Semaphore_t FreeSlotsSemaphore;
50  oC_MemorySize_t BufferSize;
51  uint8_t Buffer[1];
52 } * Queue_t;
53 
54 #undef _________________________________________TYPES_SECTION______________________________________________________________________________
55 
61 #define _________________________________________LOCAL_PROTOTYPES_SECTION___________________________________________________________________
62 
63 
64 #undef _________________________________________LOCAL_PROTOTYPES_SECTION___________________________________________________________________
65 
66 
72 #define _________________________________________FUNCTIONS_SECTION__________________________________________________________________________
73 
78 //==========================================================================================================================================
88 //==========================================================================================================================================
89 oC_Queue_t oC_Queue_New( Allocator_t Allocator , oC_MemorySize_t BufferSize )
90 {
91  Queue_t queue = NULL;
92 
93  if(
94  oC_SaveIfFalse( "Allocator" , isaddresscorrect(Allocator), oC_ErrorCode_WrongAddress )
95  && oC_SaveIfFalse( "BufferSize", BufferSize > 0 , oC_ErrorCode_SizeNotCorrect )
96  )
97  {
98  queue = kmalloc( sizeof(struct Queue_t) + BufferSize, Allocator, AllocationFlags_ZeroFill );
99 
100  if( oC_SaveIfFalse( "queue" , queue != NULL, oC_ErrorCode_AllocationError ) )
101  {
102  queue->UsedSlotsSemaphore = oC_Semaphore_New(BufferSize, 0, Allocator, AllocationFlags_Default);
103  queue->FreeSlotsSemaphore = oC_Semaphore_New(BufferSize, BufferSize, Allocator, AllocationFlags_Default);
104 
105  if(
106  oC_SaveIfFalse( "used slots semaphore", queue->UsedSlotsSemaphore != NULL, oC_ErrorCode_AllocationError )
107  && oC_SaveIfFalse( "free slots semaphore", queue->FreeSlotsSemaphore != NULL, oC_ErrorCode_AllocationError )
108  )
109  {
110  queue->ObjectControl = oC_CountObjectControl( queue, oC_ObjectId_Queue );
111  queue->BufferSize = BufferSize;
112  queue->GetIndex = 0;
113  queue->PutIndex = 0;
114  }
115  else
116  {
117  if(queue->UsedSlotsSemaphore != NULL)
118  {
119  oC_SaveIfFalse( "used slots", oC_Semaphore_Delete(&queue->UsedSlotsSemaphore,0), oC_ErrorCode_ReleaseError );
120  }
121  if(queue->FreeSlotsSemaphore != NULL)
122  {
123  oC_SaveIfFalse( "free slots", oC_Semaphore_Delete(&queue->FreeSlotsSemaphore,0), oC_ErrorCode_ReleaseError );
124  }
125  oC_SaveIfFalse( "queue" , kfree(queue,AllocationFlags_Default), oC_ErrorCode_ReleaseError );
126  queue = NULL;
127  }
128  }
129  }
130 
131  return queue;
132 }
133 
134 //==========================================================================================================================================
135 //==========================================================================================================================================
136 bool oC_Queue_Delete( oC_Queue_t * Queue )
137 {
138  bool deleted = false;
139 
140  if(
141  oC_SaveIfFalse("Queue", isram(Queue) , oC_ErrorCode_AddressNotInRam )
142  && oC_SaveIfFalse("Queue", oC_Queue_IsCorrect(*Queue) , oC_ErrorCode_ObjectNotCorrect )
143  )
144  {
145  Queue_t queue = *Queue;
146  bool semaphore1deleted = oC_Semaphore_Delete(&queue->FreeSlotsSemaphore, 0);
147  bool semaphore2deleted = oC_Semaphore_Delete(&queue->UsedSlotsSemaphore, 0);
148  bool mainReleased = kfree( queue, AllocationFlags_Default );
149 
150  deleted = oC_SaveIfFalse("Free slots semaphore", semaphore1deleted , oC_ErrorCode_ReleaseError)
151  && oC_SaveIfFalse("Used slots semaphore", semaphore2deleted , oC_ErrorCode_ReleaseError)
152  && oC_SaveIfFalse("Main object memory" , mainReleased , oC_ErrorCode_ReleaseError);
153  }
154 
155  return deleted;
156 }
157 
158 //==========================================================================================================================================
159 //==========================================================================================================================================
160 bool oC_Queue_IsCorrect( oC_Queue_t Queue )
161 {
162  return isram(Queue) && oC_CheckObjectControl(Queue, oC_ObjectId_Queue, ((Queue_t)Queue)->ObjectControl);
163 }
164 //==========================================================================================================================================
165 //==========================================================================================================================================
166 bool oC_Queue_Put( oC_Queue_t Queue , const void * Data , uint32_t Size , oC_Time_t Timeout )
167 {
168  bool dataPushed = false;
169  Queue_t queue = Queue;
170 
171  if(
172  oC_SaveIfFalse( "Queue" , oC_Queue_IsCorrect(Queue), oC_ErrorCode_ObjectNotCorrect )
173  && oC_SaveIfFalse( "data" , isaddresscorrect(Data) , oC_ErrorCode_WrongAddress )
174  && oC_SaveIfFalse( "Size" , Size > 0 , oC_ErrorCode_SizeNotCorrect )
175  && oC_SaveIfFalse( "Timeout", Timeout >= 0 , oC_ErrorCode_TimeNotCorrect )
176  )
177  {
178  const uint8_t * buffer = Data;
179 
180  if(oC_Semaphore_TakeCounting(queue->FreeSlotsSemaphore,Size,Timeout))
181  {
182  oC_IntMan_EnterCriticalSection();
183 
184  for(oC_MemorySize_t i = 0; i < Size; i++)
185  {
186  queue->Buffer[queue->PutIndex++] = buffer[i];
187  if(queue->PutIndex >= queue->BufferSize)
188  {
189  queue->PutIndex = 0;
190  }
191  }
192  oC_Semaphore_GiveCounting(queue->UsedSlotsSemaphore,Size);
193 
194  oC_IntMan_ExitCriticalSection();
195  dataPushed = true;
196  }
197  }
198 
199  return dataPushed;
200 }
201 //==========================================================================================================================================
202 //==========================================================================================================================================
203 bool oC_Queue_Get( oC_Queue_t Queue , void * outData , uint32_t Size , oC_Time_t Timeout )
204 {
205  bool dataReady = false;
206  Queue_t queue = Queue;
207 
208  if(
209  oC_SaveIfFalse( "Queue" , oC_Queue_IsCorrect(Queue) , oC_ErrorCode_ObjectNotCorrect )
210  && oC_SaveIfFalse( "outData", isram(outData) || outData == NULL , oC_ErrorCode_OutputAddressNotInRAM )
211  && oC_SaveIfFalse( "Size" , Size > 0 , oC_ErrorCode_SizeNotCorrect )
212  && oC_SaveIfFalse( "Timeout", Timeout >= 0 , oC_ErrorCode_TimeNotCorrect )
213  )
214  {
215  uint8_t * outBuffer = outData;
216 
217  if(oC_Semaphore_TakeCounting(queue->UsedSlotsSemaphore,Size,Timeout))
218  {
219  oC_IntMan_EnterCriticalSection();
220 
221  for(oC_MemorySize_t i = 0; i < Size; i++)
222  {
223  if(outBuffer != NULL)
224  {
225  outBuffer[i] = queue->Buffer[queue->GetIndex];
226  }
227  queue->GetIndex++;
228  if(queue->GetIndex >= queue->BufferSize)
229  {
230  queue->GetIndex = 0;
231  }
232  }
233  oC_Semaphore_GiveCounting(queue->FreeSlotsSemaphore,Size);
234 
235  oC_IntMan_ExitCriticalSection();
236  dataReady = true;
237  }
238  }
239 
240  return dataReady;
241 }
242 
244 #undef _________________________________________FUNCTIONS_SECTION__________________________________________________________________________
The file with interface for thread managing.
identifier for allocations
Definition: oc_stdlib.h:159
The file with helper macros for managing objects.
uint32_t oC_ObjectControl_t
stores object control value
Definition: oc_object.h:141
oC_Queue_t oC_Queue_New(Allocator_t Allocator, oC_MemorySize_t BufferSize)
allocates memory for a queue
Definition: oc_queue.c:89
The file with list library.
The file with interface for interrupt manager.
static oC_ObjectControl_t oC_CountObjectControl(void *ObjectPointer, oC_ObjectId_t ObjectId)
counts object control for object
Definition: oc_object.h:168
static bool oC_CheckObjectControl(void *ObjectPointer, oC_ObjectId_t ObjectId, oC_ObjectControl_t ObjectControl)
checks if object control is correct
Definition: oc_object.h:203
The file with interface for Queue module.
Definition of the null pointer.
static const oC_Allocator_t Allocator
Definition: oc_eth.c:152
The file with interface for semaphores.
#define NULL
pointer to a zero
Definition: oc_null.h:37