IEC 61499每个功能块的执行是通过事件触发的,在运行时(forte)里面主要在ecet.h和ecet.cpp文件里面实现的。类名是CEventChainExecutionThread,里面有两个用数组实现的缓存事件的列表mExternalEventList和mEventList,每次触发的事件先放到mExternalEventList列表里面,这是一个循环队列,在向mExternalEventList添加事件的同时会触发执行任务的函数,此时会把mExternalEventList里面的事件放到mEventList循环队列里面,再依次从mEventList里面取出每个事件进行执行,这个流程关联的函数有:
void CEventChainExecutionThread::startEventChain(SEventEntry *paEventToAdd)
void CEventChainExecutionThread::transferExternalEvents()
void CEventChainExecutionThread::mainRun()
开源项目的这个实现流程存在一个BUG,就是在某种条件下mExternalEventList队列满后,再有空的情况会导致队列实际是空,但检测是提示队列已满,这是通过循环事件功能块单步调试测试出来的(更多交流加2193410903)。所以要对整个流程进行修改,startEventChain修改后执行逻辑如下:
{
CCriticalRegion criticalRegion(mExternalEventListSync);
if (mExit) return;
TEventEntryPtr* pstNextEventListElem;
if (&mExternalEventList[0] == mExternalEventListEnd) {
pstNextEventListElem = &mExternalEventList[cg_nEventChainExternalEventListSize - 1];
}
else {
pstNextEventListElem = (mExternalEventListEnd - 1);
}
if (*mExternalEventListEnd && 0 == *pstNextEventListElem) {
mExternalEventListEnd = pstNextEventListElem;
}
if (0 == *mExternalEventListEnd) {
*mExternalEventListEnd = paEventToAdd;
if (mExternalEventListStart != pstNextEventListElem) {
mExternalEventListEnd = pstNextEventListElem;
}
mProcessingEvents = true;
resumeSelfSuspend();
}
else {
DEVLOG_ERROR("External event queue is full, external event dropped!\n");
}
}