SKV, CASE в любом случае нужно убирать и не тиражироать вызовы (CASE заменить на IF Step = .. ;;;; IF Condition THEN Step := Step +1; IF Error THEN Step := 0; и т.д.), тк дисперчер должен после освобождения одного слейва тут же посылать запрос другому. Например, так (фрагмент моего "диспетчера"):
Код:
2: (*RUN*)
(*WatchDog*)
TON_WD(IN := TRUE, PT := Set_Poll.WDT);
IF TON_WD.Q THEN ErrCode := ErrCode_WatchDog; Step := 3; RETURN; END_IF
(*Last Cycle 'Busy' Slave: Busy Flag Check*)
IF Busy THEN
SLAVE[BusyNum](Busy => Busy);
IF SLAVE[BusyNum].Done THEN DoneNum := BusyNum; END_IF
END_IF
(*No 'Busy' Slave: Check all slaves for busy again *)
(*ДОБАВИЛ ДЛЯ ПОЯСНЕНИЯ В ЭТОМ ТОПИКЕ: в цикле и далее вызывается Массив из FB-слейвов, в каждом из них буффер чтения, буффер записи, флаги диагностики, таймеры таймаутов, счетчики ошибок, и естественно единственный код опроса на всех напрямую с ком портом без modbus.lib. При вызове обновляются таймеры и если какой-то из них превышает время поллинга больше других слейвов , то он "отправляется на опрос". Также есть вотч-дог диспетчера, если слейвы перестали опрашиваться в течение заданного интервала. *)
IF Busy = FALSE THEN
OverT:= t#0ms;
KickNum := 0;
BusyNum := 0;
FOR Cnt := 1 TO Set_Poll.SlaveCnt DO
IF SLAVE[Cnt].Set.Use THEN
SLAVE[Cnt](
Start:= FALSE,
Poll:= FALSE,
Reset:= FALSE
);
(*'Busy' Slave detected: Set common 'Busy' flag and return*)
IF SLAVE[Cnt].Busy THEN Busy := TRUE; BusyNum := Cnt; RETURN; END_IF
(*Calc Higher OverTime Slave number*)
IF SLAVE[Cnt].ByTime AND SLAVE[Cnt].OverTime > OverT THEN OverT := SLAVE[Cnt].OverTime; KickNum := Cnt; END_IF
END_IF
END_FOR
(*'Kick-start' slave with higher OverTime *)
IF KickNum > 0 THEN
(*New 'Kick-Start' : Reset WatchDog*)
TON_WD(IN := FALSE);
SLAVE[KickNum](Poll:= TRUE, Busy => Busy);
IF Busy THEN BusyNum := KickNum; END_IF
END_IF
END_IF
возможно, когда откатаю на паре объектов, выложу полностью. А пока не готов к жесткой критике со стороны старослужащих))
Еще раз по поводу быстродействия: в modbus.lib есть мистический таймер с вызовом PT:=t#3ms, точно не помню, но какжца, он все тормозит как минимум на один цикл. Модифицировать биб-ку или уходить от нее - это уже дело вкуса)