@@ -180,7 +180,7 @@ class Controller(core.VortexCore):
180180 _libc = ctypes .CDLL ("libc.so.6" )
181181 _Command = namedtuple ("Command" , ['id' , 'name' , 'opts' , 'data' , 'defaults' ])
182182
183- def __init__ (self , config ):
183+ def __init__ (self , config , command_completion_callback ):
184184 # Unfortunately, Python does not deal with merging
185185 # class members from multiple classes. So, we can't
186186 # set chip architecture and frequency to a default
@@ -203,7 +203,7 @@ def __init__(self, config):
203203 self .object_defs = {x : None for x in core .ObjectKlass }
204204 self .object_factory = {x : None for x in core .ObjectKlass }
205205 self ._virtual_objects = {}
206- self ._completion_callback = None
206+ self ._completion_callback = command_completion_callback
207207 self ._event_handlers = {}
208208 self ._timer_factory = timers .Factory (self )
209209 self ._exec_cmd_map = {}
@@ -274,14 +274,13 @@ def _load_objects(self, config):
274274 try :
275275 obj = self .object_factory [klass ](options , self .objects ,
276276 self .query_objects ,
277- self .virtual_command_complete ,
277+ self ._completion_callback ,
278278 self .event_submit )
279279 except VirtualObjectError as error :
280280 self .log .error (f"Failed to create virtual object { klass } :{ name } : { error } " )
281281 continue
282282 self .object_defs [klass ] = obj .__class__
283- object_id = self .register_virtual_object (klass , name , self .vobj_cmd_exec ,
284- self .vobj_get_state )
283+ object_id = self .register_virtual_object (klass , name , obj )
285284 if object_id == vortex .core .INVALID_OBJECT_ID :
286285 self .log .error (f"Failed to register virtual object { klass } :{ name } " )
287286 continue
@@ -320,9 +319,7 @@ def _verify_pins(self, config):
320319 raise core .VortexCoreError (e )
321320 return True , None
322321
323- def start (self , timer_frequency , update_frequency , set_priority , vobj_exec_cb , completion_cb ):
324- self ._virtual_object_exec_command = vobj_exec_cb
325- self ._completion_callback = completion_cb
322+ def start (self , timer_frequency , update_frequency , set_priority ):
326323 cur_freq = get_host_cpu_frequency ()
327324 max_freq = get_host_cpu_frequency ("max" )
328325 tick_ns = hz_to_nsec (self .FREQUENCY )
@@ -336,47 +333,6 @@ def start(self, timer_frequency, update_frequency, set_priority, vobj_exec_cb, c
336333 def get_frequency (self ):
337334 return self .FREQUENCY
338335
339- def command_complete (self , cmd_id , status , data_addr ):
340- self .log .debug (f"controller complete { cmd_id } ={ status } , data_addr={ data_addr } " )
341- obj_id , obj_cmd = self ._exec_cmd_map .pop (cmd_id , (None , None ))
342- obj = self .objects .object_by_id (obj_id )
343- data = None
344- if data_addr :
345- cmd = [x for x in self .object_factory [obj .klass ].commands if x [0 ] == obj_cmd ]
346- if not cmd or len (cmd ) != 1 :
347- self ._completion_callback (cmd_id , - 255 )
348- cmd_data = cmd [0 ][3 ]
349- if cmd_data is not None and issubclass (cmd_data , ctypes .Structure ):
350- data = ctypes .cast (data_addr , ctypes .POINTER (cmd_data )).contents
351- data = vortex .lib .ctypes_helpers .parse_ctypes_struct (data )
352- self ._completion_callback (cmd_id , status , data )
353-
354- def virtual_command_complete (self , cmd_id , status , data = None ):
355- self .log .debug (f"controller virtual complete: { cmd_id } ={ status } , data={ data } " )
356- self ._completion_callback (cmd_id , status , data )
357-
358- def virtual_object_opts_convert (self , obj_id , obj_cmd_id , opts ):
359- if obj_id not in self ._virtual_objects :
360- return - 1
361- vobj = self ._virtual_objects [obj_id ]
362- args_struct = [cmd [2 ] for cmd in vobj .commands if cmd [0 ] == obj_cmd_id ]
363- if not args_struct :
364- raise - 1
365- args_ptr = ctypes .cast (opts , ctypes .POINTER (args_struct [0 ])).contents
366- args = vortex .lib .ctypes_helpers .parse_ctypes_struct (args_ptr )
367- return args
368-
369- def vobj_cmd_exec (self , klass , obj_id , cmd_id , cmd , opts ):
370- return self ._virtual_object_exec_command (klass , obj_id , cmd_id , cmd , opts )
371-
372- def vobj_get_state (self , klass , obj_id ):
373- if obj_id not in self ._virtual_objects :
374- return 0
375- state = self ._virtual_objects [obj_id ].get_status ()
376- struct = self ._virtual_objects [obj_id ].state ()
377- vortex .lib .ctypes_helpers .fill_ctypes_struct (struct , state )
378- return struct
379-
380336 def get_param (self , param ):
381337 if param == "commands" :
382338 cmds = {x : [] for x in core .ObjectKlass }
@@ -420,12 +376,6 @@ def lookup_objects(self, klass):
420376 return self .objects .object_by_klass (klass )
421377
422378 def query_objects (self , objects ):
423- virtual_objects = []
424- for id in objects :
425- object = self .objects .object_by_id (id )
426- if object .klass and self .object_defs [object .klass ].virtual :
427- virtual_objects .append (id )
428- objects = [x for x in objects if x not in virtual_objects ]
429379 _status = self .get_status (objects )
430380 object_status = dict .fromkeys (objects , None )
431381 for i , id in enumerate (objects ):
@@ -434,14 +384,15 @@ def query_objects(self, objects):
434384 self .log .error (f"Could not find klass for object id { id } " )
435385 continue
436386 if _status [i ]:
437- status_struct = self .object_defs [object .klass ].state
438- status = ctypes .cast (_status [i ], ctypes .POINTER (status_struct )).contents
439- object_status [id ] = vortex .lib .ctypes_helpers .parse_ctypes_struct (status )
440- self ._libc .free (ctypes .c_void_p (_status [i ]))
387+ if self .object_defs [object .klass ].virtual :
388+ object_status [id ] = _status [i ]
389+ else :
390+ status_struct = self .object_defs [object .klass ].state
391+ status = ctypes .cast (_status [i ], ctypes .POINTER (status_struct )).contents
392+ object_status [id ] = vortex .lib .ctypes_helpers .parse_ctypes_struct (status )
393+ self ._libc .free (ctypes .c_void_p (_status [i ]))
441394 else :
442395 object_status [id ] = None
443- for id in virtual_objects :
444- object_status [id ] = self ._virtual_objects [id ].get_status ()
445396 return object_status
446397
447398 def _convert_opts (self , klass , cmd_id , opts ):
@@ -471,35 +422,49 @@ def _convert_opts(self, klass, cmd_id, opts):
471422 def exec_command (self , command_id , object_id , subcommand_id , opts = None ):
472423 object = self .objects .object_by_id (object_id )
473424 self .log .debug (f"controller executing command { command_id } : { object .id } { object .klass } { object .name } " )
474- if opts is not None :
425+ if not self . object_defs [ object . klass ]. virtual and opts is not None :
475426 opts = self ._convert_opts (object .klass , subcommand_id , opts )
476- if not self .object_defs [object .klass ].virtual :
477- args = 0
478- if opts is not None :
427+ args = 0
428+ if opts is not None :
429+ if self .object_defs [object .klass ].virtual :
430+ args = id (opts )
431+ else :
479432 args = ctypes .addressof (opts )
480- # Store the command into the command map so if the object
481- # completes the command quickly (before it is stored if it were
482- # stored after), the complete callback can successfully find it.
483- #
484- # this thread core completion thread
485- # -------------------------------------------------------
486- # self.exec_command()
487- # object->exec_command()
488- # CORE_CMD_COMPLETE()
489- # core_process_completions()
490- # complete_cm()
491- # self.command_complete()
492- # return
493- # return
494- self ._exec_cmd_map [command_id ] = (object_id , subcommand_id )
495- ret = super ().exec_command (command_id , object_id , subcommand_id , args )
496- self .log .debug (f"result: { command_id } ={ ret } " )
497- if ret :
498- self ._exec_cmd_map .pop (command_id )
499- return ret
500- else :
501- return self ._virtual_objects [object_id ].exec_command (command_id ,
502- subcommand_id , opts )
433+ # Store the command into the command map so if the object
434+ # completes the command quickly (before it is stored if it were
435+ # stored after), the complete callback can successfully find it.
436+ #
437+ # this thread core completion thread
438+ # -------------------------------------------------------
439+ # self.exec_command()
440+ # object->exec_command()
441+ # CORE_CMD_COMPLETE()
442+ # core_process_completions()
443+ # complete_cm()
444+ # self.command_complete()
445+ # return
446+ # return
447+ self ._exec_cmd_map [command_id ] = (object_id , subcommand_id )
448+ ret = super ().exec_command (command_id , object_id , subcommand_id , args )
449+ self .log .debug (f"result: { command_id } ={ ret } " )
450+ if ret :
451+ self ._exec_cmd_map .pop (command_id )
452+ return ret
453+
454+ def command_complete (self , cmd_id , status , data_addr ):
455+ self .log .debug (f"controller complete { cmd_id } ={ status } , data_addr={ data_addr } " )
456+ obj_id , obj_cmd = self ._exec_cmd_map .pop (cmd_id , (None , None ))
457+ obj = self .objects .object_by_id (obj_id )
458+ data = None
459+ if data_addr :
460+ cmd = [x for x in self .object_factory [obj .klass ].commands if x [0 ] == obj_cmd ]
461+ if not cmd or len (cmd ) != 1 :
462+ self ._completion_callback (cmd_id , - 255 )
463+ cmd_data = cmd [0 ][3 ]
464+ if cmd_data is not None and issubclass (cmd_data , ctypes .Structure ):
465+ data = ctypes .cast (data_addr , ctypes .POINTER (cmd_data )).contents
466+ data = vortex .lib .ctypes_helpers .parse_ctypes_struct (data )
467+ self ._completion_callback (cmd_id , status , data )
503468
504469 def event_register (self , klass , event_type , object_name , handler ):
505470 subscription_id = super ().event_register (klass , event_type , object_name ,
@@ -549,7 +514,7 @@ def cleanup(self):
549514 for obj in self .objects .object_by_klass (klass ):
550515 self .destory_object (obj .id )
551516
552- def load_mcu (name , config ):
517+ def load_mcu (name ):
553518 # Get base controller class
554519 base_module = importlib .import_module ("vortex.controllers" )
555520 base_class = getattr (base_module , "Controller" )
@@ -571,4 +536,4 @@ def load_mcu(name, config):
571536 mro = controllers [0 ].__mro__
572537 if mro [- 3 ] is not Controller or mro [- 2 ] is not core .VortexCore :
573538 logging .warning ("Controller class inheritance is incorrect." )
574- return controllers [0 ]( config )
539+ return controllers [0 ]
0 commit comments