Сообщение от
vladimirisitnikov
Иными словами:
1) Я могу генерировать и публиковать PRU0.prg для законченных программ. Например, я могу опубликовать PRU0.prg для работы с ШД.
2) Я не могу встроить механизм генерации PRU0.prg в Hardella, т.к. для этого придётся публиковать "секретный инструмент создания FB_ARRAY.bin"
Прошу провести натурные испытания.
pru_pulse_v1.zip
Порядок работы:
1) Заливаем PRU0.prg (как-то)
2) Подключаем ШД на fast output 3
2) Используем блок pru_pulse.lib для работы с ШД
CYCLE_LENGTH задаёт длительность единичного и нулевого значения на выходе. Оно указывается в тактах PRU. Вроде как PRU работает на частоте 150МГц, т.е. значение cycle_length=150 это импульсы по 1мкс.
Параметр CYCLE_LENGTH сейчас WORD, т.е. максимальное значение 65535, и, значит, возможна генерация частот в пределах 1кГц...1МГц
Если нужны более низкие частоты, то придётся перекомпилировать программу, а мне было немного лень, т.к. для этого нужно перезапускать bat'ники.
В pru_pulse один блок:
Код:
FUNCTION_BLOCK PRU_PULSE
(* Output will be generated to FAST OUTPUT 3 *)
VAR_INPUT
ENABLE: BOOL;
CYCLE_LENGTH: WORD; (* PRU cycles *)
QUANTITY: DWORD;
END_VAR
VAR_OUTPUT
READY : BOOL;
QUANTITY_LEFT: DWORD; (* for debugging *)
END_VAR
Вышеобозначенное получено "официальным линкером".
Я ему скормил всю-всю программу как один ФБ.
Для примера, вот так выглядит pulse.p -- т.е. просто вызов одного моего ФБ.
Код:
;include "target.trg"
FBDECL
#defFB PRU_PULSE PRU_PULSE
/FBDECL
SYNCLIST
IN=R25
IN=R26
IN=R27
OUT=R28
OUT=R29
/SYNCLIST
PROGRAMM
PRU_PULSE
/PROGRAMM
А так выглядит "ассемблерный код" моего ФБ:
Код:
.origin 0
.entrypoint __INIT_PROGRAM
;FB_WORKTIME=40
;FB_NAME=PRU_PULSE
__INIT_PROGRAM:
Да, да. Код целиком и полностью сгенерирован в Hardella, а линкеру я скормил пустой файл. Вроде, тот не подавился, и ладно.
Обмен с PRU я сделал так. Тут, к сожалению, сделано наугад в надежде на то, что PRU_FB_GetParameter/PRU_FB_SetParameter будут читать/писать по нужным адресам в PRU памяти.
Код:
TMP : DWORD;
...
PRU_FB_GetParameter(pru_num:=0, index:=28, value:=ADR(TMP));
READY := TMP <> 0;
PRU_FB_GetParameter(pru_num:=0, index:=29, value:=ADR(QUANTITY_LEFT));
PRU_FB_SetParameter(pru_num:=0, index:=25, value:=ADR(QUANTITY));
TMP := WORD_TO_DWORD(CYCLE_LENGTH);
PRU_FB_SetParameter(pru_num:=0, index:=26, value:=ADR(TMP));
TMP := SEL(ENABLE, 0, 1);
PRU_FB_SetParameter(pru_num:=0, index:=27, value:=ADR(TMP));