Страница 110 из 135 ПерваяПервая ... 1060100108109110111112120 ... ПоследняяПоследняя
Показано с 1,091 по 1,100 из 1349

Тема: Hardella IDE

  1. #1091

    По умолчанию

    Цитата Сообщение от IVM Посмотреть сообщение
    Для вспомогательных переменных то же память данных нужна, которой может не хватить.
    Памяти переменным почти наверняка хватит.
    Но там сложность будет в том, что, например, внутри блока PRU_STEPPER используется PRU_STEPPER_ACCEL_CALC. И переменные этого самого accelCalc тоже нужно будет сохранять-восстанавливать вместе с переменными PRU_STEPPER.

  2. #1092

    По умолчанию

    Когда я тупо объявлял 2 экземпляра ФБ в программе для PRU регистровой памяти не хватало.

  3. #1093

    По умолчанию

    Цитата Сообщение от IVM Посмотреть сообщение
    Когда я тупо объявлял 2 экземпляра ФБ в программе для PRU регистровой памяти не хватало.
    Так я же говорю, что я научил компилятор задействовать ОЗУ при нехватке регистров.
    Памяти там 4096 байт у каждого ядра, и расходуется она на "область обмена КДС-PRU" и "память для переменных". 4 килобайта уж наверняка хватит на 2 ШД, даже, если все переменные по 2-3 раза объявлять.

  4. #1094

    По умолчанию

    Я думаю, что без функций, которые сохраняет контекст в ОЗУ по абсолютным адресам и делают восстановление контекста не обойтись.

  5. #1095

    По умолчанию

    Цитата Сообщение от Владимир Ситников Посмотреть сообщение
    Так я же говорю, что я научил компилятор задействовать ОЗУ при нехватке регистров.
    Памяти там 4096 байт у каждого ядра, и расходуется она на "область обмена КДС-PRU" и "память для переменных". 4 килобайта уж наверняка хватит на 2 ШД, даже, если все переменные по 2-3 раза объявлять.
    Если все вопросы с сохранением регистровой памяти решены, то можно пробовать писать программу PRU для двух ШД. Напишите как сохранять регистровую память и как восстанавливать.

  6. #1096

    По умолчанию

    Цитата Сообщение от IVM Посмотреть сообщение
    Если все вопросы с сохранением регистровой памяти решены, то можно пробовать писать программу PRU для двух ШД. Напишите как сохранять регистровую память и как восстанавливать.
    Вручную нужно переменные сохранять.
    Если сохранять "все регистры" (а это можно даже в старой версии Hardella), то вместе с регистрами, отвечающими за PRU_STEPPER сохранятся и регистры, отвечающие за то, "который сейчас час". Т.е. регистр с прошедшим временем сохранять и восстанавливать не нужно. Конечно, можно после компиляции посмотреть в какие регистры попали данные по времени и их не восстанавливать, но это будет непойми какой хрупкий код.

  7. #1097

    По умолчанию

    Цитата Сообщение от Владимир Ситников Посмотреть сообщение
    Вручную нужно переменные сохранять.
    И как это выглядит ?

    Владимир, accel_ramp и decel_ramp в ФБ STEPPER как DWORD сделали ?

  8. #1098

    По умолчанию

    Цитата Сообщение от IVM Посмотреть сообщение
    И как это выглядит ?
    Я начал уж было переписывать, но бросил на шаге "текущее время".

    Выглядит примерно так:
    Код:
    PROGRAM STEPPER_PRU0 
      variables: 
        @Export             
            input dir : BOOL;
    
        stepper : PRU_STEPPER; 
         
        @Export               
            input enable1 : BOOL;
        @Export                   
            input quantity1 : WORD;
        @Export                            
            output state1 : STEPPER_RUN_STATE;
        @Export                      
            output step_count1 : WORD;
        @Export               
            input enable2 : BOOL;
        @Export                   
            input quantity2 : WORD;
        @Export                            
            output state2 : STEPPER_RUN_STATE;
        @Export                      
            output step_count2 : WORD;
    
        first : BOOL; 
       
      body: 
         
        IF first THEN 
          ASM 
            SBCO R29.b0, 3, 100, 4 ; сохраняем R29 
            LDI R29.dw, 2000 
            LBCO R0.b0, 3, R29.dw, 120 ; загружаем все регистры из адреса 2000 
            LBCO R29.b0, 3, 100, 4 ; возвращаем R29 в прежнее состояние 
          END_ASM 
          stepper.enable := enable1; 
          stepper.quantity := quantity1; 
        ELSE 
          ASM 
            SBCO R29.b0, 3, 100, 4 ; сохраняем R29 
            LDI R29.dw, 3000 
            LBCO R0.b0, 3, R29.dw, 120 ; загружаем все регистры из адреса 3000 
            LBCO R29.b0, 3, 100, 4 ; возвращаем R29 в прежнее состояние 
          END_ASM 
          stepper.enable := enable2; 
          stepper.quantity := quantity2; 
        END_IF; 
        stepper(); 
        IF first THEN 
          ASM 
            SBCO R29.b0, 3, 100, 4 ; сохраняем R29 
            LDI R29.dw, 2000 
            SBCO R0.b0, 3, R29.dw, 120 ; сохраняем все регистры по адресу 2000 
            LBCO R29.b0, 3, 100, 4 ; возвращаем R29 в прежнее состояние 
          END_ASM 
           
          state1 := stepper.state; 
          step_count1 := stepper.step_count; 
        ELSE 
          state2 := stepper.state; 
          step_count2 := stepper.step_count; 
        END_IF; 
        first := NOT first; 
         
        FAST_OUTPUTS(out3 := stepper.Q, out4 := dir); 
    END_PROGRAM
    Смысл в том, что команда LBCO загружает данные из памяти, а команда SBCO пишет данные в память (из регистров).
    Адрес превышающий 124 (или около того) в LBCO/SBCO не поддерживается, и нужно использовать вспомогательный регистр.
    Команды имеют вид "LBCO регистр (который в прочитаются данные), 3 (означает "память текущего ядра"), 100 (смещение), 4 (количество байт, если больше размера регистра, то лишние данные попадут в следующие регистры по порядку)

    Поэтому видно, что исходно в части "IF first" я хочу загрузить данные "как бы для 1-го ШД" из памяти (ну, я взял и волевым решением принял, что 1-ый ШД будет храниться по адресу 2000, а второй по адресу 3000). Для обращения к 2000 нужно это самое 2000 записать в регистр (я выбрал R29, но можно любой из R0..R29). Но в этом R29 могло находиться что-то полезное, поэтому я предварительно сохранил его в память по адресу 100.


    Обмен с КДС находится по адресам 0.. и далее, поэтому до 1000 он уж точно не дойдёт.
    Последний раз редактировалось Владимир Ситников; 29.01.2018 в 12:17.

  9. #1099

    По умолчанию

    Владимир, а оформить этот код в виде функции, которая тупо переписывает регистры туда-сюда нельзя ?
    Последний раз редактировалось IVM; 29.01.2018 в 12:17.

  10. #1100

    По умолчанию

    Цитата Сообщение от IVM Посмотреть сообщение
    Владимир, accel_ramp и decel_ramp в ФБ STEPPER как DWORD сделали ?
    Вообще говоря, эти переменные сделаны WORD для экономии регистров. Можете привести пример установки, где нужен разгон быстрее, чем 65500 кГц/сек?
    Прямо реально установка, которая за секунду с нуля до 65 кГц разгоняется? Обычно, такому разгону мешают силы инерции и т.п.

    Да и точность, возможно, страдать будет, т.к. в нескольких местах происходит деление на accel_ramp. WORD тут как раз позволяет адаптировать формулы, чтобы точность вычислений несильно страдала.

    Если прямо реально нужен разгон более быстрый, чем 65кГц/сек, то можно поправить формулы, чтобы значение считалось как, например, умноженное на 8.
    Иными словами, передаём 65000, а разгон идёт как 65*8=520кГц/сек. Точность задания accel_ramp будет пониже, но максимальное значение побольше.

Страница 110 из 135 ПерваяПервая ... 1060100108109110111112120 ... ПоследняяПоследняя

Ваши права

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