如何在codesys v3中创建指向函数的指针

时间:2017-03-31 11:01:56

标签: c codesys iec61131-3

你能给我一个例子,说明如何在我的库中声明一个指向函数的指针?如何将指向函数的指针传递给外部库?

3 个答案:

答案 0 :(得分:0)

TL; DR:在CoDeSys v3中可能会带来手提包,并且变得非常简单。

在CoDeSys中,“功能”实际上是存储在功能表中的功能指针。

在CodeSys v2中,要获取必须使用INDEXOF(F_MyFunction)的函数的地址,这将在函数表中提供函数指针的索引。嗯,获取表格的地址对读者来说是一个练习(可以通过一些体操运动来取回)。

在CoDeSys v3中,ADR代替了INDEXOF,因此ADR(F_MyFunction)为您提供了指向F_MyFunction的代码的函数指针的地址!

猜猜是什么:您可以设置该函数指针,而F_MyFunction(...)只是通过该函数指针的调用。

就这么简单。

因此,要进行间接函数调用,您需要做的就是声明一个虚拟的“函数”,实际上它就像可设置的函数指针一样工作!

假设我们有两个目标函数要间接调用:

FUNCTION F_Add1: INT
VAR_INPUT
  param : INT;
END_VAR
F_Add1:= param + 1;
END_FUNCTION

FUNCTION F_Add2: INT
VAR_INPUT
  param : INT;
END_VAR
F_Add2:= param + 2;
END_FUNCTION

然后,我们定义一个“函数指针”,该函数必须具有与间接调用的函数相同的签名:

FUNCTION FPTR_Add : INT
VAR_INPUT
  param : INT;
END_VAR
END_FUNCTION

我们还可以有一个分配给函数指针的助手:

F_FPTR_Assign
VAR_INPUT
  dst : POINTER TO PVOID;
  src : POINTER TO PVOID;
END_VAR
dst^ := src^;
END_FUNCTION

最后,让我们进行一些间接调用:

// should return 3 if indirect calls work
FUNCTION F_Test : INT
VAR
  val : INT;
END_VAR

F_FPTR_Assign(ADR(FPTR_Add), ADR(F_Add1));

// FPTR_Add points to F_Add1
val := FPTR_Add(val);
// here val has value 1

F_FPTR_Assign(ADR(FPTR_Add), ADR(F_Add2));

// FPTR_Add points to F_Add2
val := FPTR_Add(val);
// here val has value 3

F_Test := val;

END_FUNCTION

此方法的唯一缺点是,调试器不会检查函数指针的动态值,因此 stepping 的行为类似于 step over 。解决方法是在目标函数中设置断点,然后进入进入都将在此处停止。

还有其他方法可以达到这种效果,例如通过直接操作堆栈帧,因此即使由于CoDeSys的某些更改而使此精确方法无法正常工作,也有其他方法可以实现。

答案 1 :(得分:-1)

codesys中可以使用指针。要在codesys中创建指针,您可以

VAR 
  pVar : POINTER TO BYTE;
  tempVar  : BYTE;
  derefereceVar : BYTE;
END_VAR

//get a pointer to the byte variable
pVar := ADR(tempVar);

取消引用你想要的指针

derefereceVar := tempVar^;

因此,如果您希望将指针作为函数的参数,则可以将上面示例中的pVarADR(tempVar)传递给函数的参数POINTER_TO_BYTE作为类型。

答案 2 :(得分:-1)

在基于Codesys的平台中,可以创建指向数据类型或功能块的指针。在TwinCAT 3中,也可以创建一个函数指针,但不能在PLC程序中调用它。函数指针只能作为外部库组件的参数给出。

检查一下: https://infosys.beckhoff.com/english.php?content=../content/1033/tc3_plc_intro/136447627.html&id=4296747249216071915