pythoncomcan-buscaplcanoe

How can I call CAPL general functions from Python 3.x?


Issue

I'm trying to call CAPL general functions (in my case timeNowNS), but I don't know if it's possible.

capl general functions

What I'm using

I'm using Python 3.7 and Vector CANoe 11.0.

The connection is done using the .NET CANoe API. This is how I've accessed the DLL files.

import clr

sys.path.append("C:\Program Files\Vector CANoe 11.0\Exec64")  # Path to CANoe DLL Files
clr.AddReference('Vector.CANoe.Interop')                      # Add reference to .NET DLL file

import CANoe                                                  # Import namespace from DLL file

What I've tried

I opened the CANoe simulation successfully, started the measure and I'm having access to signals, environment variables and sys variables.

Then I've created the CAPL Object and tried using the GetFunction method to obtain the CAPLFunction object, so I could call it.

def begin_can(self, sCfgFile, fPrjInitFunc = None):
     self.open_can()
     self.load_can_configuration(sCfgFile)
     self.start_can_measurement(fPrjInitFunc)

def open_can(self):
    self.mCANoeApp = CANoe.Application()
    self.mCANoeMeasurement = CANoe.Measurement(self.mCANoeApp.Measurement)
    self.mCANoeEnv = CANoe.Environment(self.mCANoeApp.Environment)
    self.mCANoeBus = CANoe.Bus(self.mCANoeApp.get_Bus("CAN"))
    self.mCANoeSys = CANoe.System(self.mCANoeApp.System)
    self.mCANoeNamespaces = CANoe.Namespaces(self.mCANoeSys.Namespaces)
    self.mCANoeCAPL = CANoe.CAPL(self.mCANoeApp.CAPL)
    self.mCANoeCAPL.Compile()

def getFunction(self):
        function1 = self.mCANoeCAPL.GetFunction('timeNowNS')

        # Here I tried also CANoe.CAPLFunction(self.mCANoeCAPL.GetFunction('timeNowNS'))
        # But I got an attribute error: doesn't exist or something like that

        result = function1.Call()

Expected results

I should get the current simulation time using this function.

Actual results

Using the above code I get:

**COMException**: Catastrophic failure (Exception from HRESULT: 0x8000FFFF (E_UNEXPECTED))
   at CANoe.ICAPL5.GetFunction(String Name)

I've tried different variations of the code, but I didn't get anywhere.

Is it possible to be a hardware problem? Should I do some settings in the CANoe Simulation?

Here is a photo of my measure setup after adding the CAPL block:

Measure setup


Solution

  • After a long session of try and error and the help of m-spiller, I found the solution.

    function2 = None
    
    def open_can(self):
         self.mCANoeApp = CANoe.Application()
         self.mCANoeMeasurement = self.mCANoeApp.Measurement   # Change here: no cast necessary
         self.mCANoeEnv = CANoe.Environment(self.mCANoeApp.Environment)
         self.mCANoeBus = CANoe.Bus(self.mCANoeApp.get_Bus("CAN"))
         self.mCANoeSys = CANoe.System(self.mCANoeApp.System)
         self.mCANoeNamespaces = CANoe.Namespaces(self.mCANoeSys.Namespaces)
         self.mCANoeCAPL = CANoe.CAPL(self.mCANoeApp.CAPL)
         self.mCANoeMeasurement.OnInit += CANoe._IMeasurementEvents_OnInitEventHandler(self.OnInit)
         # Change here also: explained below
    
     def OnInit(self):
         global function2
         function2 = CANoe.CAPLFunction(mCANoeCAPL.GetFunction('MyTime')) # Cast here is necessary
    
     def callFunction(self):
         result = function2.Call()
    

    What was the problem with the initial code?

    The problem was that I tried to assign a function to a variable after the measure has started. As stated here in chapter 2.7, the assignment of a CAPL Function to a variable can only be done in the OnInit event handler of the Measurement object.

    I've added this line, studying the documentation:

    self.mCANoeMeasurement.OnInit += CANoe._IMeasurementEvents_OnInitEventHandler(self.OnInit)
    

    After adding it, on init the OnInit function was executed and the CAPL function was assigned to a variable and afterwards I could use that variable to call the function.