Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Самомодифицирующийся код в экосистеме Cortex-M.
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Страницы: 1, 2
AlexandrY
Цитата(adnega @ Jun 30 2018, 11:59) *
Кста, а есть у кого-нить справочник машинных кодов для Cortex-M всех семейств?

ARM®v7-M Architecture Reference Manual

Господа, вы тут явно пытаетесь эмулировать DMA. biggrin.gif
AVI-crak
Цитата(jcxz @ Jun 29 2018, 04:54) *
Есть мысль использовать самомодифицирующийся код для оптимизации решения одной задачи.

Если "модификация" происходит под внешним управлением - то это называется эмуляцией.
Доказательство очень простое: информация от том что и как необходимо изменить - остаётся без изменений. Место хранения этой информации не важно, важно то что эта информация является избыточной.

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

Насколько я верно понял, вам нужно выполнять внешний код из текстового ввода. То-есть все те-же команды ассемблера arm - записанные в текстовом массиве. Без разметки границ, без легирования меток, и без чёткой локализации хранения данных.
Поздравляю - это называется парсер.

Имеет смысл посмотреть блочную реализацию парсера бэйсика. На него кстати есть с десяток активных проектов на гите, в том числе и под арм.
Или реализацию джавы для арм, хотя там без тяжёлых наркотиков очень трудно разобраться.
jcxz
Цитата(adnega @ Jun 30 2018, 11:59) *
Покажите пожалуйста выход генератора для случая DWORD, WORD, DWORD, BYTE, BYTE в виде asm-инструкций.

Да, как только поборю IAR. Если у Вас IAR, то как Вы ему сказали, чтобы он массив объявленный в программе как массив, показывал в окне дизасма как код? А то у меня он, собака, как только видит что это массив, показывает просто как кучу констант DC32 как этот массив не объявляй. Не могу заставить его дизассемблировать sad.gif(((
И мне не нужны байтовые операции - переменные только 16 и 32 бита.

Цитата(adnega @ Jun 30 2018, 11:59) *
Кста, а есть у кого-нить справочник машинных кодов для Cortex-M всех семейств?

Мне тоже хотелось-бы. Не нашёл в инете. Только если правильно выражаться: таблица маш.кодов набора инструкций Thumb-2.

Цитата(AlexandrY @ Jun 30 2018, 13:09) *
Господа, вы тут явно пытаетесь эмулировать DMA. biggrin.gif

Да причём тут DMA??? Каким боком он поможет в этой задаче? Разве чтобы только затормозить процедуру в несколько раз?

Цитата(AVI-crak @ Jun 30 2018, 14:24) *
Более простое название этого процесса - полиморфный код.

Мне без разницы как это называть. Пускай будет полиморфный.
А что именно требуется - мне кажется уже каждый должен был понять, хоть немного почитав тред.
adnega
Цитата(jcxz @ Jun 30 2018, 14:56) *
Да, как только поборю IAR.

gcc-шный objdump легко превращает бинарник в s-файл.
Можете скинуть бинарь - я его конвертну, если у вас нет gcc.
AlexandrY
Цитата(jcxz @ Jun 30 2018, 14:56) *
Да причём тут DMA??? Каким боком он поможет в этой задаче? Разве чтобы только затормозить процедуру в несколько раз?

Скопирует все переменные в одну область и вышлет куда надо.
Или даже без копирования вышлет.
jcxz
Цитата(adnega @ Jun 30 2018, 15:12) *
Можете скинуть бинарь - я его конвертну, если у вас нет gcc.

Спасибо, уже не надо - просто копировал из массива результат в неиспользуемую память МК, а для такой памяти IAR позволяет делать дизасм. Так и отладил.
Вобщем: всё ок работает алгоритм. rolleyes.gif
Ниже прикладываю результат его работы для 64-битного слова: 0000.002A.1003.0006.
При таких весах битов карты (см. установленные биты в бит-карте выше):
бит1=2 байта, бит2=2 байта, бит16=4 байта, бит17=2 байта, бит28=4 байта, бит33=4 байта, бит35=4 байта, бит37=2 байта.

Результат картинкой (не знаю как в IAR сохранить текстовое содержимое окна дизасма, а InqSoft Scaner не захватывает текст из этого окна):
Нажмите для просмотра прикрепленного файла
А здесь результат в бинарнике:
Нажмите для просмотра прикрепленного файла
Итого - время выполнения этого кода думаю будет == примерно 31 такт (не измерял), при условии что dst на входе - выровнен на 4.
Как можно догадаться: функция строится таким образом, чтобы она была определена как:
extern "C" void * Func(void *dst, u32 *table);
где: dst - буфер для записи (передаётся в R0); table - массив из 64-х указателей на захватываемые переменные.

Цитата(AlexandrY @ Jun 30 2018, 16:17) *
Скопирует все переменные в одну область и вышлет куда надо.
Или даже без копирования вышлет.

Ну-ну. А теперь объясните как он это скопирует, когда переменные разбросаны по всей памяти МК кусочками по 2 и по 4 байта? smile3009.gif
Про передачу свЯзными списками я в курсе.
AlexandrY
Цитата(jcxz @ Jun 30 2018, 16:30) *
Ну-ну. А теперь объясните как он это скопирует, когда переменные разбросаны по всей памяти МК кусочками по 2 и по 4 байта? smile3009.gif
Про передачу свЯзными списками я в курсе.

И чем не подошла передача связными списками?
jcxz
Цитата(AlexandrY @ Jun 30 2018, 16:39) *
И чем не подошла передача связными списками?

Тем что при программировании каждого сегмента списка, DMA-контроллер читает из памяти следующий блок-описатель сегмента, который в моём МК насколько помню == 5 слов. Это кроме собственно пересылки потом. И так - на каждую переменную. В итоге количество обращений к памяти в разы больше, и скорость выполнения в разы меньше чем с СМК. Уже не говоря о манипуляциях с IO-регистрами DMA.
Да и ОЗУ для описания такого связного списка нужно больше.
В то время как время выполнения результата генератора СМК приведённого выше, думаю должно быть == ~31 такт.
AlexandrY
Цитата(jcxz @ Jun 30 2018, 16:56) *
В то время как время выполнения результата генератора СМК приведённого выше, думаю должно быть == ~31 такт.

Что-то непонятная мне логика.
В управлении мотором или SMPS самые приоритетные прерывания и процедуры - это токовые контуры.
Они безальтернативно самые приоритетные и прервут любую пересылку или еще что-там.
Т.е. ваша программная пересылка гарантировано будет прервана и задержана как минимум на время прерываний в токовом контуре.
Таким образом теряете детерминизм и гарантированность времени окончания пересылки, так какой прок экономить такты?
DMA же этой проблемы не имеет.

Для справки, прерываний в токовом контуре у самых навороченных DSP от TI заточенных на это длится не менее 1 мкс, это 140 тактов в чипе с частотой 140 МГц.
Вот плюс минус сотня тактов и будет погрешностью. Так чего экономить 30 если погрешность больше 100?

Я честно думал, что речь идет об оптимизации именно алгоритмов в токовых контурах или алгоритмов модуляции.
Arlleex
jcxz, а зачем тут это? Вы сначала загружаете адрес интересуемой переменной из таблицы, потом загружаете значение переменной по этому адресу, и сохраняете в dst с постинкрементом, это понятно. А выделенное то зачем? Вы что-то говорили про перемежение инструкций для удаления штрафов LDR/STR. Могли бы озвучить, в чем там проблема?
VladislavS
Недавно в другой теме проскакивал вот такой код. По сути - копирование восьми 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
jcxz
Цитата(Arlleex @ Jun 30 2018, 18:09) *
А выделенное то зачем? Вы что-то говорили про перемежение инструкций для удаления штрафов LDR/STR. Могли бы озвучить, в чем там проблема?

Если выполнить просто:
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 с перемежением, чтобы убрать такие штрафы.

Цитата(VladislavS @ Jun 30 2018, 21:33) *
Зачем компилятор R2 и R3 чередует?

Здесь не знаю. А для какого это ядра?
Мой генератор кода заточен для Cortex-M4. У него я не знаю необходимости в таком перемежении.
VladislavS
Цитата(jcxz @ Jun 30 2018, 22:31) *
Здесь не знаю. А для какого это ядра?
Мой генератор кода заточен для Cortex-M4. У него я не знаю необходимости в таком перемежении.

Тоже Cortex-M4, если точнее, то STM32F427.
jcxz
Цитата(AlexandrY @ Jun 30 2018, 17:43) *
Таким образом теряете детерминизм и гарантированность времени окончания пересылки, так какой прок экономить такты?

Ваш пост настолько бессмысленен, что даже не знаю как ответить..... wacko.gif
На всякий случай: частоты ШИМ-ов для motor control обычно лежат где-то около 10-30 кГц. А для моего Cortex-M это однозначно - много тысяч тактов CPU на период ШИМа. Что как бы не сравнимо с 31 тактом. Не находите?
Если вы дадите себе труд изучить работу любого DMA в режиме linked-list, то увидите, что длительность пересылки будет много больше указанных нескольких десятков тактов. Кроме всего прочего....

Цитата(VladislavS @ Jun 30 2018, 22:35) *
Тоже Cortex-M4, если точнее, то STM32F427.

Не знаю. По-крайней мере TRM для CM4 в разделе "3.3.3 Load/store timings" о необходимости такого не говорит. Можете сами убедиться.
Может в реализации CM4 от STM32 имеется какой-то баг, который фиксится таким образом?
У себя я реализовал только оптимизацию чередованием инструкций указанную выше.
Arlleex
Цитата(jcxz @ Jun 30 2018, 23:31) *
Поэтому мой генератор кода использует в качестве рабочих два регистра - 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.
jcxz
Цитата(Arlleex @ Jun 30 2018, 22:45) *
По тем же самым причинам - снижение штрафов на 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 не используется для вычисления адреса в следующих за ними командах. Посмотрите внимательнее.
AlexandrY
Цитата(jcxz @ Jun 30 2018, 22:41) *
Ваш пост настолько бессмысленен, что даже не знаю как ответить..... wacko.gif
На всякий случай: частоты ШИМ-ов для motor control обычно лежат где-то около 10-30 кГц. А для моего Cortex-M это однозначно - много тысяч тактов CPU на период ШИМа. Что как бы не сравнимо с 31 тактом. Не находите?
Если вы дадите себе труд изучить работу любого DMA в режиме linked-list, то увидите, что длительность пересылки будет много больше указанных нескольких десятков тактов. Кроме всего прочего....

Я тоже не понял эту аргументацию.
Понял только что вам как бы детерминизм в токовых контурах не важен.
И что такое токовый контур похоже не знаете.
Ну не в теме и не в теме. Что поделаешь.
Продолжайте пилить динамику. biggrin.gif

А тему переназовите так - как мне сделать пересылку быстрее чем по linked-list поскольку в XMC4700 оказался скверный DMA.
Arlleex
Кстати, решил почитать внимательнее 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 отдельно все сказано.
jcxz
Цитата(Arlleex @ Jul 1 2018, 13:03) *
Что это вообще за инструкции такие с синтаксисом обратной записи в базовый регистр LDR Rx!,[any]? Для LDM понимаю, но чтобы для LDR... Опечатка в документации? Тоже вряд ли, ниже по тексту про LDM отдельно все сказано.

Видимо это инструкции вида:
LDR Rx, [Ry], #z
и
LDR Rx, [Ry, #z]!

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

Цитата(AlexandrY @ Jul 1 2018, 10:22) *
А тему переназовите так - как мне сделать пересылку быстрее чем по linked-list поскольку в XMC4700 оказался скверный DMA.

Так расскажите нам: в каком таком ядре идеальный DMA, умеющий загружать из ОЗУ описание следующего блока linked-list (которое как правило имеет размер в несколько слов) за 0 тактов? Видимо это ядро умеет мгновенно телепортировать в DMA содержимое ОЗУ без использования шин biggrin.gif
AVI-crak
Цитата(jcxz @ Jun 29 2018, 10:51) *
Вы о чём? wacko.gif

Простые вопросы на самом деле бывают со сложными ответами. Особенно когда мозаика не складывается в общий узор.
Я повторю свой вопрос - откуда мк читает программный код?
Есть ли дополнительный код или инструкции которые должен выполнять мк в нативе, или программный код на мк в режиме эмуляции?
VladislavS
Цитата(AVI-crak @ Jul 1 2018, 18:22) *
Я повторю свой вопрос - откуда мк читает программный код?

При наличии PSRAM в чипе странно было бы генерить код не в него. Хотя, от задачи зависит тоже.
jcxz
Цитата(VladislavS @ Jul 1 2018, 19:25) *
При наличии PSRAM в чипе странно было бы генерить код не в него. Хотя, от задачи зависит тоже.

Конечно генерю в PSRAM. При генерации в обычную SRAM время выполнения увеличивается примерно в 2 раза.
AVI-crak
Цитата(jcxz @ Jul 2 2018, 22:12) *
Конечно генерю в PSRAM. При генерации в обычную SRAM время выполнения увеличивается примерно в 2 раза.

Как и предполагалось, для ответа простые вопросы нужно хорошо подумать.
Повторюсь:
Откуда мк начинает выполнять программный код сразу после аппаратного сброса. Общая функция этого кода, и что происходит дальше по алгоритму.
Arlleex
Цитата(AVI-crak @ Jul 3 2018, 00:46) *
Откуда мк начинает выполнять программный код сразу после аппаратного сброса. Общая функция этого кода, и что происходит дальше по алгоритму.

А откуда он после сброса может выполнять код, на Ваш взгляд? Конечно же из flash. И алгоритм его находится во flash-памяти. Но формирует опкоды для исполнения в PSRAM.
AVI-crak
Цитата(Arlleex @ Jul 3 2018, 10:44) *
А откуда он после сброса может выполнять код, на Ваш взгляд? Конечно же из flash.

Правильный ответ считается решением задачи.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.