Перейти к содержанию
    

Самомодифицирующийся код в экосистеме Cortex-M.

Недавно в другой теме проскакивал вот такой код. По сути - копирование восьми uint16_t.

cpld_regs[0] = ppm8s.state.rx.chanel[0].fv_att_h.fvatt;
cpld_regs[1] = ppm8s.state.rx.chanel[0].fv_att_v.fvatt;
cpld_regs[2] = ppm8s.state.rx.chanel[1].fv_att_h.fvatt;;
cpld_regs[3] = ppm8s.state.rx.chanel[1].fv_att_v.fvatt;
cpld_regs[4] = ppm8s.state.rx.chanel[2].fv_att_h.fvatt;;
cpld_regs[5] = ppm8s.state.rx.chanel[2].fv_att_v.fvatt;
cpld_regs[6] = ppm8s.state.rx.chanel[3].fv_att_h.fvatt;;
cpld_regs[7] = ppm8s.state.rx.chanel[3].fv_att_v.fvatt;

Который компилируется вот в это

        LDR.W    R1,??DataTable6
        LDRH     R2,[R1, #+0]
        MOV      R0,#+1610612736
        STRH     R2,[R0, #+0]
        LDRH     R3,[R1, #+2]
        STRH     R3,[R0, #+2]
        LDRH     R2,[R1, #+4]
        STRH     R2,[R0, #+4]
        LDRH     R3,[R1, #+6]
        STRH     R3,[R0, #+6]
        LDRH     R2,[R1, #+8]
        STRH     R2,[R0, #+8]
        LDRH     R3,[R1, #+10]
        STRH     R3,[R0, #+10]
        LDRH     R2,[R1, #+12]
        STRH     R2,[R0, #+12]
        LDRH     R3,[R1, #+14]
        STRH     R3,[R0, #+14]

Зачем компилятор R2 и R3 чередует?

IAR 8.30.1

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А выделенное то зачем? Вы что-то говорили про перемежение инструкций для удаления штрафов LDR/STR. Могли бы озвучить, в чем там проблема?

image.png

Если выполнить просто:

LDR R2, [R1, #4]

LDR R2, [R2]

то вторая команда выполнится за 2 такта. Если же между ними вставить любую другую команду, не модифицирующую R2, то LDR R2, [R2] должна выполниться за 1 такт.

Это следует из фразы:

LDR [any] are pipelined when possible. This means that if the next instruction is an LDR or STR, and the destination of the first LDR is not used to compute the address for the next instruction, then one cycle is removed from the cost of the next instruction.

из "ARM® Cortex®‑M4 Processor Technical Reference Manual" раздел "3.3.3 Load/store timings".

Поэтому мой генератор кода использует в качестве рабочих два регистра - R2 и R3 с перемежением, чтобы убрать такие штрафы.

 

Зачем компилятор R2 и R3 чередует?

Здесь не знаю. А для какого это ядра?

Мой генератор кода заточен для Cortex-M4. У него я не знаю необходимости в таком перемежении.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Здесь не знаю. А для какого это ядра?

Мой генератор кода заточен для Cortex-M4. У него я не знаю необходимости в таком перемежении.

Тоже Cortex-M4, если точнее, то STM32F427.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Таким образом теряете детерминизм и гарантированность времени окончания пересылки, так какой прок экономить такты?

Ваш пост настолько бессмысленен, что даже не знаю как ответить..... :wacko:

На всякий случай: частоты ШИМ-ов для motor control обычно лежат где-то около 10-30 кГц. А для моего Cortex-M это однозначно - много тысяч тактов CPU на период ШИМа. Что как бы не сравнимо с 31 тактом. Не находите?

Если вы дадите себе труд изучить работу любого DMA в режиме linked-list, то увидите, что длительность пересылки будет много больше указанных нескольких десятков тактов. Кроме всего прочего....

 

Тоже Cortex-M4, если точнее, то STM32F427.

Не знаю. По-крайней мере TRM для CM4 в разделе "3.3.3 Load/store timings" о необходимости такого не говорит. Можете сами убедиться.

Может в реализации CM4 от STM32 имеется какой-то баг, который фиксится таким образом?

У себя я реализовал только оптимизацию чередованием инструкций указанную выше.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Поэтому мой генератор кода использует в качестве рабочих два регистра - R2 и R3 с перемежением, чтобы убрать такие штрафы.

Точно. LDR первая же всегда 2 такта занимает.

 

Зачем компилятор R2 и R3 чередует?

По тем же самым причинам - снижение штрафов на LDR/STR.

LDR [any] are pipelined when possible. This means that if the next instruction is an LDR or STR, and the destination of the first LDR is not used to compute the address for the next instruction, then one cycle is removed from the cost of the next instruction.

Изменено пользователем Arlleex

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

По тем же самым причинам - снижение штрафов на LDR/STR.

LDR [any] are pipelined when possible. This means that if the next instruction is an LDR or STR, and the destination of the first LDR is not used to compute the address for the next instruction, then one cycle is removed from the cost of the next instruction.

В том случае это не применимо: содержимое R2 и R3 не используется для вычисления адреса в следующих за ними командах. Посмотрите внимательнее.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ваш пост настолько бессмысленен, что даже не знаю как ответить..... :wacko:

На всякий случай: частоты ШИМ-ов для motor control обычно лежат где-то около 10-30 кГц. А для моего Cortex-M это однозначно - много тысяч тактов CPU на период ШИМа. Что как бы не сравнимо с 31 тактом. Не находите?

Если вы дадите себе труд изучить работу любого DMA в режиме linked-list, то увидите, что длительность пересылки будет много больше указанных нескольких десятков тактов. Кроме всего прочего....

Я тоже не понял эту аргументацию.

Понял только что вам как бы детерминизм в токовых контурах не важен.

И что такое токовый контур похоже не знаете.

Ну не в теме и не в теме. Что поделаешь.

Продолжайте пилить динамику. :biggrin:

 

А тему переназовите так - как мне сделать пересылку быстрее чем по linked-list поскольку в XMC4700 оказался скверный DMA.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Кстати, решил почитать внимательнее 3.3.2. Load/store timings из Cortex-M3 Technical Reference Manual. Там есть такие строки:

LDR Rx!,[any] is not normally pipelined. That is, base update load is generally at least a two-cycle operation (more if stalled). However, if the next instruction does not require to read from a register, the load is reduced to one cycle. Non register writing instructions include CMP, TST, NOP, and non-taken IT controlled instructions.

Что это вообще за инструкции такие с синтаксисом обратной записи в базовый регистр LDR Rx!,[any]? Для LDM понимаю, но чтобы для LDR... Опечатка в документации? Тоже вряд ли, ниже по тексту про LDM отдельно все сказано.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Что это вообще за инструкции такие с синтаксисом обратной записи в базовый регистр LDR Rx!,[any]? Для LDM понимаю, но чтобы для LDR... Опечатка в документации? Тоже вряд ли, ниже по тексту про LDM отдельно все сказано.

Видимо это инструкции вида:

LDR Rx, [Ry], #z

и

LDR Rx, [Ry, #z]!

 

PS: Кстати - Вы смотрите не последнюю ревизию ядра. В ревизии r2p1 для CM3 такого замечания уже нет - видимо исправили.

Так что надо смотреть какая ревизия ядра у Вашего МК.

 

А тему переназовите так - как мне сделать пересылку быстрее чем по linked-list поскольку в XMC4700 оказался скверный DMA.

Так расскажите нам: в каком таком ядре идеальный DMA, умеющий загружать из ОЗУ описание следующего блока linked-list (которое как правило имеет размер в несколько слов) за 0 тактов? Видимо это ядро умеет мгновенно телепортировать в DMA содержимое ОЗУ без использования шин :biggrin:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вы о чём? :wacko:

Простые вопросы на самом деле бывают со сложными ответами. Особенно когда мозаика не складывается в общий узор.

Я повторю свой вопрос - откуда мк читает программный код?

Есть ли дополнительный код или инструкции которые должен выполнять мк в нативе, или программный код на мк в режиме эмуляции?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я повторю свой вопрос - откуда мк читает программный код?

При наличии PSRAM в чипе странно было бы генерить код не в него. Хотя, от задачи зависит тоже.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

При наличии PSRAM в чипе странно было бы генерить код не в него. Хотя, от задачи зависит тоже.

Конечно генерю в PSRAM. При генерации в обычную SRAM время выполнения увеличивается примерно в 2 раза.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Конечно генерю в PSRAM. При генерации в обычную SRAM время выполнения увеличивается примерно в 2 раза.

Как и предполагалось, для ответа простые вопросы нужно хорошо подумать.

Повторюсь:

Откуда мк начинает выполнять программный код сразу после аппаратного сброса. Общая функция этого кода, и что происходит дальше по алгоритму.

Изменено пользователем AVI-crak

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Откуда мк начинает выполнять программный код сразу после аппаратного сброса. Общая функция этого кода, и что происходит дальше по алгоритму.

А откуда он после сброса может выполнять код, на Ваш взгляд? Конечно же из flash. И алгоритм его находится во flash-памяти. Но формирует опкоды для исполнения в PSRAM.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А откуда он после сброса может выполнять код, на Ваш взгляд? Конечно же из flash.

Правильный ответ считается решением задачи.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...