Показано с 1 по 10 из 64

Тема: ST, паузы, async/await/coroutines

Древовидный режим

Предыдущее сообщение Предыдущее сообщение   Следующее сообщение Следующее сообщение
  1. #6

    По умолчанию

    Приведу ещё пример: асинхронная запись в файл, которую настоятельно рекомендует ОВЕН (по понятным причинам).

    Пример от ОВЕН выглядит так:
    Код:
    CASE state_res OF
    
    	0:
    	res:=OwenFileOpenAsync('usb:test.dat','a',ADR(handle));
    	IF res=ASYNC_WORKING THEN
    		state:=1;
    	END_IF
    
    
    	1:
    	res:=OwenFileOpenAsync('test.dat','a',ADR(handle));
    	IF res=ASYNC_DONE THEN
    		IF handle<>0 THEN
    			state:=2;
    		ELSE
    			state:=0;
    		END_IF
    	ELSIF res<0 THEN
    		state:=0;
    	END_IF
    
    
    
    	2:
    	res:=OwenFileWriteAsync(handle,ADR(bufout),14,ADR(result));
    	IF res=ASYNC_WORKING THEN
    		state:=3;
    	ELSE
    		state:=6;
    	END_IF
    
    
    
    	3:
    	res:=OwenFileWriteAsync(handle,ADR(bufout),14,ADR(result));
    	IF res=ASYNC_DONE THEN
    		IF result=14 THEN
    			state:=4;
    		ELSE
    			state:=6;
    		END_IF
    	ELSIF res<0 THEN
    		state:=6;
    	END_IF
    
    
    
    	4:
    	res:=OwenFileReadAsync(handle,ADR(bufin),14,ADR(result));
    	IF res=ASYNC_WORKING THEN
    		state:=5;
    	ELSE
    		state:=6;
    	END_IF
    
    
    
    	5:
    	res:=OwenFileReadAsync(handle,ADR(bufin),14,ADR(result));
    	IF res=ASYNC_DONE THEN
    		IF result>=0 THEN
    			state:=6;
    			counter:=counter+1;
    		ELSE
    			state:=6;
    		END_IF
    	ELSIF res<0 THEN
    		state:=6;
    	END_IF
    
    
    
    	6:
    	res:=OwenFileCloseAsync(handle,ADR(result));
    	IF res=ASYNC_WORKING THEN
    		state:=7;
    	ELSE
    		state:=0;
    	END_IF
    
    
    
    	7:
    	res:=OwenFileCloseAsync(handle,ADR(result));
    	IF res=ASYNC_DONE THEN
    		IF result=0 THEN
    
    			state:=0;
    		ELSE
    			state:=0;
    		END_IF
    	ELSIF res<0 THEN
    		state:=0;
    	END_IF
    
    
    ELSE
    	state:=0;
    END_CASE
    Что? Всё понятно? Прямо прочитали и сразу поняли?
    Контрольный вопрос: чем отличается state=0 от state=1? Если честно, то я не особо понял.

    На паузах это будет так (40 строк вместо 100):
    Код:
    WHILE TRUE
    	REPEAT
    		res:=OwenFileOpenAsync('usb:test.dat','a',ADR(handle));
    		IF res = ASYNC_WORKING THEN
    			ПАУЗА;
    		END_IF;
    	UNTIL res<>ASYNC_DONE
    	END_REPEAT;
        
    	IF res<0 OR handle=0 THEN
    		CONTINUE; (* ошибка, поехали сначала *)
    	END_IF
    
    	REPEAT
    		res:=OwenFileWriteAsync(handle,ADR(bufout),14,ADR(result));
    		IF res = ASYNC_WORKING THEN
    			ПАУЗА;
    		END_IF;
    	UNTIL res<>ASYNC_DONE
    	END_REPEAT;
    	
    	(* читаем файл *)
    	IF result=14 THEN
    		REPEAT
    			res := OwenFileReadAsync(handle,ADR(bufin),14,ADR(result));
    			IF res = ASYNC_WORKING THEN
    				ПАУЗА;
    			END_IF;
    		UNTIL res<>ASYNC_DONE
    		END_REPEAT;
    	END_IF;
    	
    	(* Закрытие файла *)
    	REPEAT
    		res := OwenFileCloseAsync(handle,ADR(result));
    	    	IF res = ASYNC_WORKING THEN
        			ПАУЗА;
    	    	END_IF;
    	UNTIL res<>ASYNC_DONE
    	END_REPEAT;
    END_WHILE;
    По-моему, вариант с паузами гораздо понятнее. Операции "открыть файл", "записать", "прочитать", "закрыть" стали встречаться в коде только 1 раз. В исходном варианте они встречались по 2 раза. Да и разнообразные "IF ... state:=5;" никак не прибавляют читабельности и понятности коду.

    Можно ли было изначально написать на CASE более внятно? Вполне возможно.

    Но, и вариант "на паузах" можно написать гораздо компактнее. А именно: видно, что каждая операция с файлом обёрнута в repeat-until.
    Если в самой библиотеке объявить вспомогательные функции типа таких
    Код:
    ASYNC FUNCTION OwenFileOpenAsync2 : ASYNC_RET_VALUE
    VAR_INPUT
    	stFileName: STRING(255);
    	stMode : STRING[3];
    	returnvalue:POINTER TO DWORD;
    END_VAR
    	res: ASYNC_RET_VALUE;
    VAR
    END_VAR
    	REPEAT
    		res:=OwenFileOpenAsync(stFileName, stMode, returnvalue);
    		OwenFileOpenAsync2 := res;
    		IF res = ASYNC_WORKING THEN
    			ПАУЗА;
    		END_IF;
    	UNTIL res<>ASYNC_DONE
    	END_REPEAT;
    END_FUNCTION
    То "код примера работы с асинхронной библиотекой файлов станет таким.
    16 понятных строк, там где было 100 строк на CASE state=2/state=6.

    При этом стоит понимать, что код по-прежнему выполняется асинхронно, т.е. "не занимает" цикл ПЛК.

    Код:
    WHILE TRUE
    	res := OwenFileOpenAsync2('usb:test.dat','a',ADR(handle));
    
    	IF res<0 OR handle=0 THEN
    		CONTINUE; (* ошибка, поехали сначала *)
    	END_IF
    
    	res := OwenFileWriteAsync2(handle,ADR(bufout),14,ADR(result));
    
    	IF result=14 THEN
    		res := OwenFileReadAsync2(handle,ADR(bufin),14,ADR(result));
    	END_IF;
    	
    	res := OwenFileCloseAsync2(handle,ADR(result));
    END_WHILE;
    Последний раз редактировалось Владимир Ситников; 10.10.2017 в 10:42.

Похожие темы

  1. Ответов: 4
    Последнее сообщение: 11.05.2018, 13:01
  2. Режим паузы в ТРМ251 на прошивке 2.10
    от Brewer в разделе Эксплуатация
    Ответов: 2
    Последнее сообщение: 29.03.2016, 16:10
  3. Реализация паузы в SFC
    от KoT'86 в разделе ПЛК1хх
    Ответов: 7
    Последнее сообщение: 05.06.2013, 21:28
  4. ПЛК63 - непонятные паузы в исполнении при опросе по 485
    от Alex_yu в разделе Помощь Разработчикам
    Ответов: 9
    Последнее сообщение: 02.07.2011, 22:54

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •