modelica-3rdparty/Modelica_DeviceDrivers

About the Blocks/HardwareIO/Comedi issue

alexzcao opened this issue · 5 comments

Everything was fine with the modeling, but when compiling the C code (C, GCC), it gave out the error below:

Comedi_Hello_World_06inz.c:60:75: error: use of undeclared identifier '$PdioRead$Pcomedi'
  omc_Modelica__DeviceDrivers_HardwareIO_Comedi___dio__config(threadData, $PdioRead$Pcomedi, (modelica_integer)data->simulationInfo->integerParameter[1], (modelica_integer)data->simulationInfo->integerParameter[0], ((modelica_integer) 0));
                                                                          ^
1 error generated.
make: *** [<builtin>: Comedi_Hello_World_06inz.o] Error 1
make: *** Waiting for unfinished jobs....
Compilation process failed. Exited with code 2.

OS: Debian 10, Kernel: 4.19.0.6 (4.19.0.6-rt with the same error), libcomedi-dev: 0.11.0-1
Device: NI USB-6501

Any solutions? Thanks!

Screenshot from 2019-10-21 14-29-58

Which OpenModelica version did you use?

Which OpenModelica version did you use?

1.13.2

Looking at the screenshot it seems that compilation is done with clang, not gcc. You can change the compiler in Tool->Options->Simulation, but I'm not sure if this is the issue. The OpenModelica version is recent, so it should work, unless there was a regression. What I miss in the output is the instruction to link the library libcomedi. I can't test it at the moment, but I can possible test it in the evening at my machine.

I can replicate the issue. It seems that recent versions of OpenModelica don't support it anymore to hand in external objects as parameters. This is a "regression".

The issue is that according to the Modelica standard this was a grey area some time ago and it seems it is forbidden more explicitly now (unfortunately). In Modelica Specification 3.4, Section 12.9.7 it says:

Only the constructor may return external objects and external object can only be bound in component declarations and neither modified later nor assigned to.

I've discussed this issue with @sjoelund some time ago and although he held the opinion that it shouldn't be supported by the standard to do this, he kindly added support for it anyway. However, it seems it doesn't work anymore in the latest OMC versions. Side note: Dymola supports less restricted external objects (which I think is good), and since MDD was developed using Dymola, the present solution was already "legacy".

The workaround is to define the external object as inner in the top model and as outer in the device blocks (and do without the ComediConfig block). E.g., in the top model do

parameter String deviceName = "/dev/comedi0" "Name of Comedi device";
inner Comedi comedi = Comedi(deviceName) "Handle to comedi device";

In the device blocks change

parameter Comedi comedi "Handle to comedi device";

to s.th. like

outer Comedi comedi "Handle to comedi device";

From a standard compliance perspective the Comedi blocks should be revised, but this would be backwards incompatible and I'm very reluctant to do such changes.

I can replicate the issue. It seems that recent versions of OpenModelica don't support it anymore to hand in external objects as parameters. This is a "regression".

The issue is that according to the Modelica standard this was a grey area some time ago and it seems it is forbidden more explicitly now (unfortunately). In Modelica Specification 3.4, Section 12.9.7 it says:

Only the constructor may return external objects and external object can only be bound in component declarations and neither modified later nor assigned to.

I've discussed this issue with @sjoelund some time ago and although he held the opinion that it shouldn't be supported by the standard to do this, he kindly added support for it anyway. However, it seems it doesn't work anymore in the latest OMC versions. Side note: Dymola supports less restricted external objects (which I think is good), and since MDD was developed using Dymola, the present solution was already "legacy".

The workaround is to define the external object as inner in the top model and as outer in the device blocks (and do without the ComediConfig block). E.g., in the top model do

parameter String deviceName = "/dev/comedi0" "Name of Comedi device";
inner Comedi comedi = Comedi(deviceName) "Handle to comedi device";

In the device blocks change

parameter Comedi comedi "Handle to comedi device";

to s.th. like

outer Comedi comedi "Handle to comedi device";

From a standard compliance perspective the Comedi blocks should be revised, but this would be backwards incompatible and I'm very reluctant to do such changes.

Really appreciate this reply!