发明内容
为了解决上述技术问题,提供一种子程序调用的方法、装置及PLC控制系统,可有效解决现有技术中针对进行多路控制的需求,传统实现方案编程复杂、调试时间长以及维护难度高的问题。
本发明实施例提出的一种子程序调用的方法,包括:
获取子程序的调用位置信息;
定位预设的与所述调用位置信息对应的存储数据的存储空间;
根据所述存储空间存储的数据调用运行所述子程序,并在所述存储空间中保持所述子程序运行后的数据。
其中,所述定位预设的与所述调用位置信息对应的存储数据的存储空间的步骤之前还包括:
设置存储数据的存储空间,所述数据为所述子程序调用运行所需的数据。
其中,所述定位预设的与所述调用位置信息对应的存储数据的存储空间的步骤包括:
根据所述调用位置信息查找预设的映射信息,所述映射信息包括调用运行所述子程序的调用位置信息与所述存储空间的映射关系;
若查找出所述调用位置信息映射的存储空间,则定位到所述存储空间;若没有查找出所述调用位置信息映射的存储空间,则为所述调用位置信息分配存储空间并定位到所述存储空间。
其中,为所述调用位置信息分配存储空间并定位到所述存储空间的步骤之后还包括:
在所述映射信息中记录所述调用位置信息与所述分配的存储空间的映射关系。
其中,根据所述调用位置信息查找预设的映射信息的步骤之前还包括:
根据设置的存储数据的存储空间,初始化映射信息,所述映射信息包括调用运行所述子程序的调用位置信息与所述存储空间的映射关系。
其中,所述子程序为可编程逻辑控制器PLC过程控制子程序。
相应地,本发明实施例公开了一种子程序调用装置,包括:
位置获取模块,用于获取子程序的调用位置信息;
定位模块,用于定位预设的与所述调用位置信息对应的存储数据的存储空间;
调用运行模块,用于根据所述定位模块定位的存储空间存储的数据调用运行所述子程序,并在所述存储空间中保持所述子程序运行后的数据。
其中,所述子程序调用装置还包括:
存储空间设置模块,用于设置存储数据的存储空间,所述数据为所述子程序调用运行所需的数据。
其中,所述定位模块包括:
映射信息查找单元,用于根据所述调用位置信息查找预设的映射信息,所述映射信息包括调用运行所述子程序的调用位置信息与所述存储空间的映射关系;
存储空间定位单元,用于若所述映射信息查找单元查找出所述调用位置信息映射的存储空间,则定位到所述存储空间;若所述映射信息查找单元没有查找出所述调用位置信息映射的存储空间,则为所述调用位置信息分配存储空间并定位到所述存储空间。
其中,所述子程序调用装置还包括:
映射关系记录模块,用于当所述存储空间定位单元为所述调用位置信息分配存储空间并定位到所述存储空间后,在所述映射信息中记录所述调用位置信息与所述分配的存储空间的映射关系。
其中,所述子程序调用装置还包括:
映射信息初始化模块,用于根据所述存储空间设置模块设置的存储数据的存储空间,初始化映射信息,所述映射信息包括调用运行所述子程序的调用位置信息与所述存储空间的映射关系。
相应地,本发明实施例公开了一种PLC控制系统,包括上述的子程序调用装置,所述子程序为可编程逻辑控制器PLC过程控制子程序。
实施本发明实施例,具有如下有益效果:
通过根据子程序的调用位置信息定位对应的存储数据的存储空间,根据所述存储空间存储的数据调用运行所述子程序,并在所述存储空间中保持所述子程序运行后的数据,可有效解决现有技术中通过共享子程序进行多路控制时传统实现方案编程复杂、调试时间长以及维护难度高的问题,本发明实施例不使用指针和全局变量即可实现共享子程序进行多路控制,简化了编程调试,大大降低了用户的编程调试能力要求,缩短了编程调试周期,并加快了开发的进度。
具体实施方式
下面将结合本发明实施例中的附图,对本发明实施例中的技术方案进行清楚、完整地描述,显然,所描述的实施例仅仅是本发明一部分实施例,而不是全部的实施例。基于本发明中的实施例,本领域普通技术人员在没有作出创造性劳动前提下所获得的所有其他实施例,都属于本发明保护的范围。
如图1示出的本发明子程序调用的第一实施例的方法流程图,包括:
步骤S101:获取子程序的调用位置信息;
具体地,系统预先编写至少一个子程序(即可以预先编写多个不同的子程序),然后在整个程序的运行过程中该子程序被周期性地调用运行,那么系统在调用运行该子程序之前,获取该子程序的调用位置信息,该调用位置信息包括但不限于调用该子程序的指令在整个运行的程序中的行数信息等。
步骤S102:定位预设的与所述调用位置信息对应的存储数据的存储空间;
具体地,系统预先编写设置存储数据的存储空间,该数据为该子程序调用运行所需的数据,该存储空间与所述调用位置信息存在对应关系,每个被调用的子程序将被定位到各自对应的存储空间存储的数据,即,若某个子程序在固定的调用位置被周期性地调用,那么给子程序将一直被定位到对应的存储空间存储的数据。
步骤S103:根据所述存储空间存储的数据调用运行所述子程序,并在所述存储空间中保持所述子程序运行后的数据。
具体地,系统在所述存储空间中保持所述子程序运行后的数据,即系统能够在周期性地调用某个固定调用位置的子程序的过程中一直保持数据,而不同调用位置的子程序之间能够不共享数据。
需要说明的是,现有技术中一般以Function data的格式调用子程序,而本发明实施例中直接以Function即可调用该子程序,系统将根据Function的位置定位到存储空间存储的所需的数据来完成该子程序的调用运行。
还需要说明的是,步骤S102中,可以但不限于通过下面的例子设置定义数据以及存储该数据的存储空间:
struct LMemLocationNode{
INT8U*pCallPc;
INT8U mem[MEM_L_RANGE];
};
struct LMemLocationNode lMemLocationNodes[STL_MAX_INS_NUM/2];
进一步地,更详细地说明本发明实施例中定位预设的与所述调用位置信息对应的存储数据的存储空间的步骤,如图2示出的本发明子程序调用的第二实施例的方法流程图,包括:
步骤S201:获取子程序的调用位置信息;
步骤S202:根据所述调用位置信息查找预设的映射信息,所述映射信息包括调用运行所述子程序的调用位置信息与所述存储空间的映射关系;
具体地,系统预先设置了映射信息,该映射信息包括调用运行所述子程序的调用位置信息与所述存储空间的映射关系,该映射信息可以为一映射表,如图3示出的本发明映射表的第一实施例的结构示意图,以调用位置信息为子程序被调用运行的行数为例,该映射表中包括被调用运行的子程序所在的行数映射的存储空间,如在第15行调用的子程序A对应存储空间a、在第17行调用的子程序A对应存储空间b、在第18行调用的子程序B对应存储空间c等等。
步骤S203:若查找出所述调用位置信息映射的存储空间,则定位到所述存储空间;若没有查找出所述调用位置信息映射的存储空间,则为所述调用位置信息分配存储空间并定位到所述存储空间;
具体地,若系统查找出所述调用位置信息映射的存储空间,则定位到所述存储空间,如查找出第17行调用的子程序A对应存储空间b,即表明之前已经调用运行过第17行的子程序A,那么将调用运行第17行的子程序定位到存储空间b存储的数据上;若系统没有查找出所述调用位置信息映射的存储空间,则为所述调用位置信息分配存储空间并定位到所述存储空间,如没有查找出第23行调用的子程序A对应的存储空间,即表明之前没有调用运行过第23行的子程序A,当前第一次调用运行第23行的子程序A,那么为第23行的子程序A分配一个存储空间d,该存储空间d没有对应调用位置信息,即该存储空间d对应的调用位置信息为NULL,然后将第23行的子程序A定位到存储空间d。
步骤S204:根据所述存储空间存储的数据调用运行所述子程序,并在所述存储空间中保持所述子程序运行后的数据。
需要说明的是,系统可以但不限于通过下面的例子初始化设置映射信息:
void StlLMemLocationNodesInit(void)
{
int i;
for(i=0;i<sizeof(lMemLocationNodes)/sizeof(struct LMemLocationNode);
i++)
{
lMemLocationNodes[i].pCallPc=NULL;
memset(lMemLocationNodes[i].mem,0,MEM_L_RANGE);
}
}
进一步地,步骤S203中,为所述调用位置信息分配存储空间并定位到所述存储空间的步骤之后还包括:在所述映射信息中记录所述调用位置信息与所述分配的存储空间的映射关系。具体地,如为第30行的子程序A分配一个存储空间d后,如图4示出的本发明映射表的第二实施例的结构示意图,在该映射信息中自动记录了第30行的子程序A对应存储空间d,那么当再次调用第30行的子程序A时,系统将定位到存储空间d存储的数据。
需要说明的是,步骤S203中,系统可以但不限于通过下面的例子定位存储空间:
INT8U*getCurrLMemLocation(INT8U*currCallPc)
{
int i;
for(i=0;i<sizeof(lMemLocationNodes)/sizeof(struct LMemLocationNode);
i++)
{
if(lMemLocationNodes[i].pCallPc==currCallPc)
{
return lMemLocationNodes[i].mem;
/*若查找出所述调用位置信息映射的存储空间,则返回该存储空间,即定位到该存储空间*/
}
else if(lMemLocationNodes[i].pCallPc==NULL)
{
lMemLocationNodes[i].pCallPc=currCallPc;
return lMemLocationNodes[i].mem;
/*若没有查找出所述调用位置信息映射的存储空间,则为当前该调用位置信息分配存储空间并返回该存储空间,即定位到该存储空间*/
}
}
return NULL;
}
实施上述实施例,根据子程序的调用位置信息定位对应的存储数据的存储空间,根据所述存储空间存储的数据调用运行所述子程序,并在所述存储空间中保持所述子程序运行后的数据,能够实现在周期性地调用某个固定调用位置的子程序的过程中一直保持数据,即该数据仅对相同的调用位置的过程可见,而不同调用位置的子程序之间能够不共享数据,实现了不使用指针即可完成共享子程序进行多路控制,有效解决了现有技术中通过共享子程序进行多路控制时传统实现方案编程复杂、调试时间长以及维护难度高的问题,简化了编程调试,大大降低了用户的编程调试能力要求,缩短了编程调试周期,并加快了开发的进度。
下面以PLC控制4路电机运作为例进行说明:
假设电机1与电机2的接口参数均相同,通过共享PLC过程控制子程序A来控制(下面简称子程序A),电机3与电机4的接口参数均相同,通过共享PLC过程控制子程序B(下面简称子程序B)来控制。PLC控制系统预先编写子程序A以及子程序B,预先设置子程序A以及子程序B运行所需的数据,以及存储该数据的至少4个存储空间,预先初始化映射信息,如控制电机1的子程序A在整个程序中的第20行被调用运行,控制电机2的子程序A在整个程序中的第30行被调用运行。
当第一次调用运行第20行的子程序A时,PLC控制系统根据所述调用位置信息(第20行)查找预设的映射信息,没有查找出第20行映射的存储空间,则为第20行分配存储空间h,并定位到该存储空间h,PLC控制系统利用存储空间h存储的数据运行子程序A,以控制电机1的运作,并在存储空间h中保持该子程序A运行后的数据;同理,当第一次调用运行第30行的子程序A时,PLC控制系统根据所述调用位置信息(第30行)查找预设的映射信息,没有查找出第30行映射的存储空间,则为第30行分配存储空间j,并定位到该存储空间j,PLC控制系统利用存储空间j存储的数据运行子程序A,以控制电机2的运作,并在存储空间j中保持该子程序A运行后的数据;
当再次调用运行第20行的子程序A,以对电机1进行控制时,PLC控制系统根据所述调用位置信息(第20行)查找预设的映射信息,查找到第20行映射的存储空间h,那么PLC控制系统将定位到存储空间h存储的数据(即为第一次运行后保持的数据),以运行该子程序A,并在存储空间h中保持该子程序A运行后的数据;同理,当再次调用运行第30行的子程序A,以对电机2进行控制时,PLC控制系统根据所述调用位置信息(第30行)查找预设的映射信息,查找到第30行映射的存储空间j,那么PLC控制系统将定位到存储空间j存储的数据(即为第一次运行后保持的数据),以运行该子程序A,并在存储空间j中保持该子程序A运行后的数据。
对电机3和电机4的控制过程与上述过程一致,这里不再赘述。通过上述方法,实现了在周期性地调用某个固定调用位置的子程序的过程中一直保持数据,即该数据仅对相同的调用位置的过程可见,而不同调用位置的子程序,虽然子程序相同,但能够不共享数据。
上面详细说明了本发明实施例的子程序调用的方法,下面相应地,说明本发明实施例的子程序调用装置的结构。
如图5示出的本发明子程序调用装置的第一实施例的结构示意图,子程序调用装置5包括位置获取模块51、定位模块52和调用运行模块53,其中,
位置获取模块51用于获取子程序的调用位置信息;
具体地,系统预先编写至少一个子程序(即可以预先编写多个不同的子程序),然后在整个程序的运行过程中该子程序被周期性地调用运行,那么系统在调用运行该子程序之前,位置获取模块51获取该子程序的调用位置信息,该调用位置信息包括但不限于调用该子程序的指令在整个运行的程序中的行数信息等。
定位模块52用于定位预设的与所述调用位置信息对应的存储数据的存储空间;
具体地,子程序调用装置5预先编写设置存储数据的存储空间,该数据为该子程序调用运行所需的数据,该存储空间与所述调用位置信息存在对应关系,通过定位模块52每个被调用的子程序将被定位到各自对应的存储空间存储的数据,即,若某个子程序在固定的调用位置被周期性地调用,那么给子程序将一直被定位到对应的存储空间存储的数据。
调用运行模块53用于根据定位模块52定位的存储空间存储的数据调用运行所述子程序,并在所述存储空间中保持所述子程序运行后的数据。
具体地,调用运行模块53在所述存储空间中保持所述子程序运行后的数据,即子程序调用装置5能够在周期性地调用某个固定调用位置的子程序的过程中一直保持数据,而不同调用位置的子程序之间能够不共享数据。
需要说明的是,现有技术中一般以Function data的格式调用子程序,而本发明实施例中直接以Function即可调用该子程序,子程序调用装置5将根据Function的位置定位到存储空间存储的所需的数据来完成该子程序的调用运行。
如图6示出的本发明子程序调用装置的第二实施例的结构示意图,子程序调用装置5包括位置获取模块51、定位模块52和调用运行模块53外,还包括存储空间设置模块54,用于设置存储数据的存储空间,所述数据为所述子程序调用运行所需的数据。
具体地,存储空间设置模块54可以但不限于通过下面的例子设置定义数据以及存储该数据的存储空间:
struct LMemLocationNode{
INT8U*pCallPc;
INT8U mem[MEM_L_RANGE];
};
struct LMemLocationNode lMemLocationNodes[STL_MAX_INS_NUM/2];
如图7示出的本发明实施例的定位模块的结构示意图,进一步说明本发明实施例的子程序调用装置5,定位模块52包括映射信息查找单元521和存储空间定位单元522,其中
映射信息查找单元521用于根据所述调用位置信息查找预设的映射信息,所述映射信息包括调用运行所述子程序的调用位置信息与所述存储空间的映射关系;
具体地,子程序调用装置5预先设置了映射信息,该映射信息包括调用运行所述子程序的调用位置信息与所述存储空间的映射关系,该映射信息可以为一映射表,如图3示出的本发明映射表的第一实施例的结构示意图,以调用位置信息为子程序被调用运行的行数为例,该映射表中包括被调用运行的子程序所在的行数映射的存储空间,如在第15行调用的子程序A对应存储空间a、在第17行调用的子程序A对应存储空间b、在第18行调用的子程序B对应存储空间c等等。
存储空间定位单元522用于若映射信息查找单元521查找出所述调用位置信息映射的存储空间,则定位到所述存储空间;若映射信息查找单元521没有查找出所述调用位置信息映射的存储空间,则为所述调用位置信息分配存储空间并定位到所述存储空间。
具体地,若映射信息查找单元521查找出所述调用位置信息映射的存储空间,则存储空间定位单元522定位到所述存储空间,如查找出第17行调用的子程序A对应存储空间b,即表明之前已经调用运行过第17行的子程序A,那么存储空间定位单元522将调用运行第17行的子程序定位到存储空间b存储的数据上;若映射信息查找单元521没有查找出所述调用位置信息映射的存储空间,则存储空间定位单元522为所述调用位置信息分配存储空间并定位到所述存储空间,如没有查找出第23行调用的子程序A对应的存储空间,即表明之前没有调用运行过第23行的子程序A,当前第一次调用运行第23行的子程序A,那么存储空间定位单元522为第23行的子程序A分配一个存储空间d,该存储空间d没有对应调用位置信息,即该存储空间d对应的调用位置信息为NULL,然后将第23行的子程序A定位到存储空间d。
如图8示出的本发明子程序调用装置的第三实施例的结构示意图,子程序调用装置5包括位置获取模块51、定位模块52、调用运行模块53和存储空间设置模块54外,还包括映射信息初始化模块55,用于根据存储空间设置模块54设置的存储数据的存储空间,初始化映射信息,所述映射信息包括调用运行所述子程序的调用位置信息与所述存储空间的映射关系。具体地,映射信息初始化模块55可以但不限于通过下面的例子初始化设置映射信息:
void StlLMemLocationNodesInit(void)
{
int i;
for(i=0;i<sizeof(lMemLocationNodes)/sizeof(struct LMemLocationNode);
i++)
{
lMemLocationNodes[i].pCallPc=NULL;
memset(lMemLocationNodes[i].mem,0,MEM_L_RANGE);
}
}
如图9示出的本发明子程序调用装置的第四实施例的结构示意图,子程序调用装置5包括位置获取模块51、定位模块52、调用运行模块53、存储空间设置模块54和映射信息初始化模块55外,还包括映射信息存储模块56以及映射关系记录模块57,映射信息存储模块56用于存储子程序调用装置5设置的映射信息;映射关系记录模块57用于当定位模块52中的存储空间定位单元522为所述调用位置信息分配存储空间并定位到所述存储空间后,在映射信息存储模块56存储的映射信息中记录所述调用位置信息与所述分配的存储空间的映射关系。具体地,定位模块52可以但不限于通过下面的例子定位存储空间:
INT8U*getCurrLMemLocation(INT8U*currCallPc)
{
int i;
for(i=0;i<sizeof(lMemLocationNodes)/sizeof(struct LMemLocationNode);
i++)
{
if(lMemLocationNodes[i].pCallPc==currCallPc)
{
return lMemLocationNodes[i].mem;
/*若查找出所述调用位置信息映射的存储空间,则返回该存储空间,即定位到该存储空间*/
}
else if(lMemLocationNodes[i].pCallPc==NULL)
{
lMemLocationNodes[i].pCallPc=currCallPc;
retum lMemLocationNodes[i].mem;
/*若没有查找出所述调用位置信息映射的存储空间,则为当前该调用位置信息分配存储空间并返回该存储空间,即定位到该存储空间*/
}
}
return NULL;
}
需要特别注意的是以上各个实施例中提到的子程序是指的一类特定的子程序,这类子程序需要在程序的反复运行中反复的调用数据,这类数据既不是局部变量中存储的数据,也不是全局变量中存储的数据,而是直接与子程序的调用位置对应的一类数据,这类数据能够在不同的调用周期保持数据,而不同调用位置的这类子程序的调用数据不共享,也就是不会相互影响/改变。可以在PLC系统实现中定义关键字BD(background data)来修饰这类子程序,以区别于其他普通的子程序调用,比如调用一般的全局变量或者局部变量的子程序。
例如:
BD void MotorControl()
有了这种关键字BD加以区分,PLC系统可以方便的查找到需要调用这种映射关系的数据的子程序,因而也方便形成映射表。比如PLC在第一次执行用户程序之前,遍历整个用户程序中包含BD定义的子程序调用,记录该类子程序的调用位置,并根据所需要的数据长度为他们分配相应大小的数据空间,从而形成预设的映射表。
相应地,本发明实施例还公开了一种PLC控制系统,如图10示出的本发明实施例的PLC控制系统的结构示意图,PLC控制系统10包括上述实施例中的子程序调用装置5,该子程序为可编程逻辑控制器PLC过程控制子程序。
下面以PLC控制系统10控制4路电机运作为例进行说明:
假设电机1与电机2的接口参数均相同,通过共享PLC过程控制子程序A来控制(下面简称子程序A),电机3与电机4的接口参数均相同,通过共享PLC过程控制子程序B(下面简称子程序B)来控制。PLC控制系统10预先编写子程序A以及子程序B,预先设置子程序A以及子程序B运行所需的数据,以及存储该数据的至少4个存储空间,预先初始化映射信息,如控制电机1的子程序A在整个程序中的第20行被调用运行,控制电机2的子程序A在整个程序中的第30行被调用运行。
当第一次调用运行第20行的子程序A时,PLC控制系统10根据所述调用位置信息(第20行)查找预设的映射信息,没有查找出第20行映射的存储空间,则为第20行分配存储空间h,并定位到该存储空间h,PLC控制系统10利用存储空间h存储的数据运行子程序A,以控制电机1的运作,并在存储空间h中保持该子程序A运行后的数据;同理,当第一次调用运行第30行的子程序A时,PLC控制系统10根据所述调用位置信息(第30行)查找预设的映射信息,没有查找出第30行映射的存储空间,则为第30行分配存储空间j,并定位到该存储空间j,PLC控制系统10利用存储空间j存储的数据运行子程序A,以控制电机2的运作,并在存储空间j中保持该子程序A运行后的数据;
当再次调用运行第20行的子程序A,以对电机1进行控制时,PLC控制系统10根据所述调用位置信息(第20行)查找预设的映射信息,查找到第20行映射的存储空间h,那么PLC控制系统10将定位到存储空间h存储的数据(即为第一次运行后保持的数据),以运行该子程序A,并在存储空间h中保持该子程序A运行后的数据;同理,当再次调用运行第30行的子程序A,以对电机2进行控制时,PLC控制系统10根据所述调用位置信息(第30行)查找预设的映射信息,查找到第30行映射的存储空间j,那么PLC控制系统10将定位到存储空间j存储的数据(即为第一次运行后保持的数据),以运行该子程序A,并在存储空间j中保持该子程序A运行后的数据。
对电机3和电机4的控制过程与上述过程一致,这里不再赘述。通过上述方法,实现了在周期性地调用某个固定调用位置的子程序的过程中一直保持数据,即该数据仅对相同的调用位置的过程可见,而不同调用位置的子程序,虽然子程序相同,但能够不共享数据。
综上所述,实施本发明实施例,根据子程序的调用位置信息定位对应的存储数据的存储空间,根据所述存储空间存储的数据调用运行所述子程序,并在所述存储空间中保持所述子程序运行后的数据,能够实现在周期性地调用某个固定调用位置的子程序的过程中一直保持数据,即该数据仅对相同的调用位置的过程可见,而不同调用位置的子程序之间能够不共享数据,实现了不使用指针和全局变量即可完成共享子程序进行多路控制,有效解决了现有技术中通过共享子程序进行多路控制时传统实现方案编程复杂、调试时间长以及维护难度高的问题,简化了编程调试,大大降低了用户的编程调试能力要求,缩短了编程调试周期,并加快了开发的进度。
本领域普通技术人员可以理解实现上述实施例方法中的全部或部分流程,是可以通过计算机程序来指令相关的硬件来完成,所述的程序可存储于一计算机可读取存储介质中,该程序在执行时,可包括如上述各方法的实施例的流程。其中,所述的存储介质可为磁碟、光盘、只读存储记忆体(Read-Only Memory,ROM)或随机存储记忆体(Random Access Memory,RAM)等。
以上所揭露的仅为本发明实施例中的较佳实施例而已,当然不能以此来限定本发明之权利范围,因此依本发明权利要求所作的等同变化,仍属本发明所涵盖的范围。