ME 405 Romi
Loading...
Searching...
No Matches
task_share.py
Go to the documentation of this file.
23
24import array
25import gc
26import pyb
27import micropython
28
29
30
32share_list = []
33
34
35type_code_strings = {'b' : "int8", 'B' : "uint8",
36 'h' : "int16", 'H' : "uint16",
37 'i' : "int(?)", 'I' : "uint(?)",
38 'l' : "int32", 'L' : "uint32",
39 'q' : "int64", 'Q' : "uint64",
40 'f' : "float", 'd' : "double"}
41
42
43
46def show_all ():
47 gen = (str (item) for item in share_list)
48 return '\n'.join (gen)
49
50
51
57
58
61 def __init__ (self, type_code, thread_protect = True, name = None):
62 self._type_code = type_code
63 self._thread_protect = thread_protect
64
65 # Add this queue to the global share and queue list
66 share_list.append (self)
67
68
69
91
92
93 ser_num = 0
94
95
120 def __init__ (self, type_code, size, thread_protect = False,
121 overwrite = False, name = None):
122 # First call the parent class initializer
123 super ().__init__ (type_code, thread_protect, name)
124
125 self._size = size
126 self._overwrite = overwrite
127 self._name = str (name) if name != None \
128 else 'Queue' + str (Queue.ser_num)
129 Queue.ser_num += 1
130
131 # Allocate memory in which the queue's data will be stored
132 try:
133 self._buffer = array.array (type_code, range (size))
134 except MemoryError:
135 self._buffer = None
136 raise
137 except ValueError:
138 self._buffer = None
139 raise
140
141 # Initialize pointers to be used for reading and writing data
142 self.clear ()
143
144 # Since we may have allocated a bunch of memory, call the garbage
145 # collector to neaten up what memory is left for future use
146 gc.collect ()
147
148
149
167 @micropython.native
168 def put (self, item, in_ISR = False):
169 # If we're in an ISR and the queue is full and we're not allowed to
170 # overwrite data, we have to give up and exit
171 if self.full ():
172 if in_ISR:
173 return
174
175 # Wait (if needed) until there's room in the buffer for the data
176 if not self._overwrite:
177 while self.full ():
178 pass
179
180 # Prevent data corruption by blocking interrupts during data transfer
181 if self._thread_protect and not in_ISR:
182 _irq_state = pyb.disable_irq ()
183
184 # Write the data and advance the counts and pointers
185 self._buffer[self._wr_idx] = item
186 self._wr_idx += 1
187 if self._wr_idx >= self._size:
188 self._wr_idx = 0
189 self._num_items += 1
190 if self._num_items >= self._size: # Can't be fuller than full
191 self._num_items = self._size
192 if self._num_items > self._max_full: # Record maximum fillage
193 self._max_full = self._num_items
194
195 # Re-enable interrupts
196 if self._thread_protect and not in_ISR:
197 pyb.enable_irq (_irq_state)
198
199
200
217 @micropython.native
218 def get (self, in_ISR = False):
219 # Wait until there's something in the queue to be returned
220 while self.empty ():
221 pass
222
223 # Prevent data corruption by blocking interrupts during data transfer
224 if self._thread_protect and not in_ISR:
225 irq_state = pyb.disable_irq ()
226
227 # Get the item to be returned from the queue
228 to_return = self._buffer[self._rd_idx]
229
230 # Move the read pointer and adjust the number of items in the queue
231 self._rd_idx += 1
232 if self._rd_idx >= self._size:
233 self._rd_idx = 0
234 self._num_items -= 1
235 if self._num_items < 0:
236 self._num_items = 0
237
238 # Re-enable interrupts
239 if self._thread_protect and not in_ISR:
240 pyb.enable_irq (irq_state)
241
242 return (to_return)
243
244
245
250 @micropython.native
251 def any (self):
252 return (self._num_items > 0)
253
254
255
260 @micropython.native
261 def empty (self):
262 return (self._num_items <= 0)
263
264
265
270 @micropython.native
271 def full (self):
272 return (self._num_items >= self._size)
273
274
275
280 @micropython.native
281 def num_in (self):
282 return (self._num_items)
283
284
285
286 def clear (self):
287 self._rd_idx = 0
288 self._wr_idx = 0
289 self._num_items = 0
290 self._max_full = 0
291
292
293
297 def __repr__ (self):
298 return ('{:<12s} Queue<{:s}> Max Full {:d}/{:d}'.format (self._name,
299 type_code_strings[self._type_code], self._max_full, self._size))
300
301
302# ============================================================================
303
304
325
326
327 ser_num = 0
328
329
330
351 def __init__ (self, type_code, thread_protect = True, name = None):
352 # First call the parent class initializer
353 super ().__init__ (type_code, thread_protect, name)
354
355 self._buffer = array.array (type_code, [0])
356
357 self._name = str (name) if name != None \
358 else 'Share' + str (Share.ser_num)
359 Share.ser_num += 1
360
361
362
370 @micropython.native
371 def put (self, data, in_ISR = False):
372
373 # Disable interrupts before writing the data
374 if self._thread_protect and not in_ISR:
375 irq_state = pyb.disable_irq ()
376
377 self._buffer[0] = data
378
379 # Re-enable interrupts
380 if self._thread_protect and not in_ISR:
381 pyb.enable_irq (irq_state)
382
383
384
390 @micropython.native
391 def get (self, in_ISR = False):
392 # Disable interrupts before reading the data
393 if self._thread_protect and not in_ISR:
394 irq_state = pyb.disable_irq ()
395
396 to_return = self._buffer[0]
397
398 # Re-enable interrupts
399 if self._thread_protect and not in_ISR:
400 pyb.enable_irq (irq_state)
401
402 return (to_return)
403
404
405
408 def __repr__ (self):
409 return ("{:<12s} Share<{:s}>".format (self._name,
410 type_code_strings[self._type_code]))
411
412
Base class for queues and shares which exchange data between tasks.
Definition task_share.py:56
__init__(self, type_code, thread_protect=True, name=None)
Create a base queue object when called by a child class initializer.
Definition task_share.py:61
A queue which is used to transfer data from one task to another.
Definition task_share.py:90
put(self, item, in_ISR=False)
Put an item into the queue.
clear(self)
Remove all contents from the queue.
# Record maximum fillage _max_full
get(self, in_ISR=False)
Read an item from the queue.
full(self)
Check if the queue is full.
__init__(self, type_code, size, thread_protect=False, overwrite=False, name=None)
Initialize a queue object to carry and buffer data between tasks.
__repr__(self)
This method puts diagnostic information about the queue into a string.
any(self)
Check if there are any items in the queue.
num_in(self)
Check how many items are in the queue.
empty(self)
Check if the queue is empty.
An item which holds data to be shared between tasks.
put(self, data, in_ISR=False)
Write an item of data into the share.
__init__(self, type_code, thread_protect=True, name=None)
Create a shared data item used to transfer data between tasks.
get(self, in_ISR=False)
Read an item of data from the share.
__repr__(self)
Puts diagnostic information about the share into a string.
show_all()
Create a string holding a diagnostic printout showing the status of each queue and share in the syste...
Definition task_share.py:46