реклама на сайте
подробности

 
 
5 страниц V  « < 2 3 4 5 >  
Reply to this topicStart new topic
> Самомодифицирующийся код в экосистеме Cortex-M., есть ли право на жизнь?
adnega
сообщение Jun 29 2018, 21:21
Сообщение #46


Гуру
******

Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702



Цитата(jcxz @ Jun 29 2018, 20:23) *
Как заработает - напишу.

Проверил в железе - работает (Cortex-M0).

CODE
#include "stdafx.h"
#include "conio.h"
#include "windows.h"

#define IS_ALIGN (1)
#define VAR_NUM (32)

//-----------------------------------------------------------------------------
// enum eVAR_TYPE
//-----------------------------------------------------------------------------
enum eVAR_TYPE
{
VAR_NONE = 0,
VAR_DWORD,
VAR_WORD,
VAR_BYTE,
};

//-----------------------------------------------------------------------------
// typedef struct sVAR
//-----------------------------------------------------------------------------
typedef struct sVAR
{
union
{
DWORD data_dw;
WORD data_w;
BYTE data_b;
};
enum eVAR_TYPE type;
} sVAR;

volatile sVAR var[VAR_NUM] =
{
{0x12345678, VAR_DWORD},
{0xABCD, VAR_WORD},
{0x11223344, VAR_DWORD},
{0x55, VAR_BYTE},
{0x00, VAR_BYTE},
{0x66, VAR_BYTE},
{0x77, VAR_BYTE},
{0x88, VAR_BYTE},
{0x99, VAR_BYTE},
{0xAA, VAR_BYTE},
{0xBB, VAR_BYTE},
{0xCC, VAR_BYTE},
{0xDD, VAR_BYTE},
{0xEE, VAR_BYTE},
{0xFF, VAR_BYTE},
{0x98765432, VAR_DWORD},
};

BYTE exec_ram[1024];

//-----------------------------------------------------------------------------
// void set_new_mask(const DWORD mask)
//-----------------------------------------------------------------------------
void set_new_mask(const DWORD mask)
{
int offset;
int last_var = 0;
int s_pos = 0;
int exec_ram_pos = 0;

printf("// r0 = *s, r1 = var\n");

// PUSH {r2, lr}
exec_ram[exec_ram_pos++] = 0x04;
exec_ram[exec_ram_pos++] = 0xB5;

printf("B5 04 - push {r2, pc}\n");

for(int i = 0; i < VAR_NUM; i++)
{
if(mask & (1 << i))
{
switch(var[i].type)
{
case VAR_DWORD:
printf("// DWORD[%d]\n", i);

offset = (i - last_var) * 8;
last_var = i;

while(offset > 128)
{
offset -= 128;
// ADD r1, #128
exec_ram[exec_ram_pos++] = 128;
exec_ram[exec_ram_pos++] = 0x31;

printf("31 80 - add r1, #128\n");
}

if(offset)
{
// ADD r1, #offset
exec_ram[exec_ram_pos++] = offset;
exec_ram[exec_ram_pos++] = 0x31;

printf("31 %02X - add r1, #%d\n", offset, offset);
}

if(IS_ALIGN && (s_pos & 1))
{
// byte align

// LDRB r2, [r1, #0]
exec_ram[exec_ram_pos++] = 0x0A;
exec_ram[exec_ram_pos++] = 0x78;

printf("78 0A - ldrb r2, [r1, #0]\n");

// STRB r2, [r0, #0]
exec_ram[exec_ram_pos++] = 0x02;
exec_ram[exec_ram_pos++] = 0x70;

printf("70 02 - strb r2, [r0, #0]\n");

// LDRB r2, [r1, #1]
exec_ram[exec_ram_pos++] = 0x4A;
exec_ram[exec_ram_pos++] = 0x78;

printf("78 4A - ldrb r2, [r1, #1]\n");

// STRB r2, [r0, #1]
exec_ram[exec_ram_pos++] = 0x42;
exec_ram[exec_ram_pos++] = 0x70;

printf("70 42 - strb r2, [r0, #1]\n");

// LDRB r2, [r1, #2]
exec_ram[exec_ram_pos++] = 0x8A;
exec_ram[exec_ram_pos++] = 0x78;

printf("78 8A - ldrb r2, [r1, #2]\n");

// STRB r2, [r0, #2]
exec_ram[exec_ram_pos++] = 0x82;
exec_ram[exec_ram_pos++] = 0x70;

printf("70 82 - strb r2, [r0, #2]\n");

// LDRB r2, [r1, #3]
exec_ram[exec_ram_pos++] = 0xCA;
exec_ram[exec_ram_pos++] = 0x78;

printf("78 CA - ldrb r2, [r1, #3]\n");

// STRB r2, [r0, #3]
exec_ram[exec_ram_pos++] = 0xC2;
exec_ram[exec_ram_pos++] = 0x70;

printf("70 C2 - strb r2, [r0, #3]\n");
}
else if(IS_ALIGN && (s_pos & 2))
{
// word align

// LDRH r2, [r1, #0]
exec_ram[exec_ram_pos++] = 0x0A;
exec_ram[exec_ram_pos++] = 0x88;

printf("88 0A - ldrh r2, [r1, #0]\n");

// STRH r2, [r0, #0]
exec_ram[exec_ram_pos++] = 0x02;
exec_ram[exec_ram_pos++] = 0x80;

printf("80 02 - strh r2, [r0, #0]\n");

// LDRH r2, [r1, #2]
exec_ram[exec_ram_pos++] = 0x4A;
exec_ram[exec_ram_pos++] = 0x88;

printf("88 4A - ldrh r2, [r1, #2]\n");

// STRH r2, [r0, #2]
exec_ram[exec_ram_pos++] = 0x42;
exec_ram[exec_ram_pos++] = 0x80;

printf("80 42 - strh r2, [r0, #2]\n");
}
else
{
// dword align

// LDR r2, [r1, #0]
exec_ram[exec_ram_pos++] = 0x0A;
exec_ram[exec_ram_pos++] = 0x68;

printf("68 0A - ldr r2, [r1, #0]\n");

// STR r2, [r0, #0]
exec_ram[exec_ram_pos++] = 0x02;
exec_ram[exec_ram_pos++] = 0x60;

printf("60 02 - str r2, [r0, #0]\n");
}

// ADDS r0, #4
exec_ram[exec_ram_pos++] = 0x04;
exec_ram[exec_ram_pos++] = 0x30;

printf("30 04 - adds r0, #4\n");

s_pos += 4;
break;

case VAR_WORD:
printf("// WORD[%d]\n", i);

offset = (i - last_var) * 8;
last_var = i;

while(offset > 128)
{
offset -= 128;
// ADD r1, #128
exec_ram[exec_ram_pos++] = 128;
exec_ram[exec_ram_pos++] = 0x31;

printf("31 80 - add r1, #128\n");
}

if(offset)
{
// ADD r1, #offset
exec_ram[exec_ram_pos++] = offset;
exec_ram[exec_ram_pos++] = 0x31;

printf("31 %02X - add r1, #%d\n", offset, offset);
}

if(IS_ALIGN && (s_pos & 1))
{
// byte align

// LDRB r2, [r1, #0]
exec_ram[exec_ram_pos++] = 0x0A;
exec_ram[exec_ram_pos++] = 0x78;

printf("78 0A - ldrb r2, [r1, #0]\n");

// STRB r2, [r0, #0]
exec_ram[exec_ram_pos++] = 0x02;
exec_ram[exec_ram_pos++] = 0x70;

printf("70 02 - strb r2, [r0, #0]\n");

// LDRB r2, [r1, #1]
exec_ram[exec_ram_pos++] = 0x4A;
exec_ram[exec_ram_pos++] = 0x78;

printf("78 4A - ldrb r2, [r1, #1]\n");

// STRB r2, [r0, #1]
exec_ram[exec_ram_pos++] = 0x42;
exec_ram[exec_ram_pos++] = 0x70;

printf("70 42 - strb r2, [r0, #1]\n");
}
else
{
// word align

// LDRH r2, [r1, #0]
exec_ram[exec_ram_pos++] = 0x0A;
exec_ram[exec_ram_pos++] = 0x88;

printf("88 0A - ldrh r2, [r1, #0]\n");

// STRH r2, [r0, #0]
exec_ram[exec_ram_pos++] = 0x02;
exec_ram[exec_ram_pos++] = 0x80;

printf("80 02 - strh r2, [r0, #0]\n");
}

// ADDS r0, #2
exec_ram[exec_ram_pos++] = 0x02;
exec_ram[exec_ram_pos++] = 0x30;

printf("30 02 - adds r0, #2\n");

s_pos += 2;
break;

case VAR_BYTE:
printf("// BYTE[%d]\n", i);

offset = (i - last_var) * 8;
last_var = i;

while(offset > 128)
{
offset -= 128;
// ADD r1, #128
exec_ram[exec_ram_pos++] = 128;
exec_ram[exec_ram_pos++] = 0x31;

printf("31 80 - add r1, #128\n\r");
}

if(offset)
{
// ADD r1, #offset
exec_ram[exec_ram_pos++] = offset;
exec_ram[exec_ram_pos++] = 0x31;

printf("31 %02X - add r1, #%d\n", offset, offset);
}

// LDRB r2, [r1, #0]
exec_ram[exec_ram_pos++] = 0x0A;
exec_ram[exec_ram_pos++] = 0x78;

printf("78 0A - ldrb r2, [r1, #0]\n");

// STRB r2, [r0, #0]
exec_ram[exec_ram_pos++] = 0x02;
exec_ram[exec_ram_pos++] = 0x70;

printf("70 02 - strb r2, [r0, #0]\n");

// ADDS r0, #1
exec_ram[exec_ram_pos++] = 0x01;
exec_ram[exec_ram_pos++] = 0x30;

printf("30 01 - adds r0, #1\n");

s_pos += 1;
break;
}
}
}
printf("// EXIT\n");

// POP {r2, pc}
exec_ram[exec_ram_pos++] = 0x04;
exec_ram[exec_ram_pos++] = 0xBD;

printf("BD 04 - pop {r2, pc}\n");

#if 0
printf("SMC:\n");
for(int i = 0; i < exec_ram_pos / 2; i++)
printf("%02X %02X\n", exec_ram[i * 2 + 1], exec_ram[i * 2 + 0]);
#endif
}

int _tmain(int argc, _TCHAR* argv[])
{
set_new_mask(0xc7);
_getch();
return 0;
}




СМК:
CODE
// r0 = *s, r1 = var
B5 04 - push {r2, pc}
// DWORD[0]
68 0A - ldr r2, [r1, #0]
60 02 - str r2, [r0, #0]
30 04 - adds r0, #4
// WORD[1]
31 08 - add r1, #8
88 0A - ldrh r2, [r1, #0]
80 02 - strh r2, [r0, #0]
30 02 - adds r0, #2
// DWORD[2]
31 08 - add r1, #8
88 0A - ldrh r2, [r1, #0]
80 02 - strh r2, [r0, #0]
88 4A - ldrh r2, [r1, #2]
80 42 - strh r2, [r0, #2]
30 04 - adds r0, #4
// BYTE[6]
31 20 - add r1, #32
78 0A - ldrb r2, [r1, #0]
70 02 - strb r2, [r0, #0]
30 01 - adds r0, #1
// BYTE[7]
31 08 - add r1, #8
78 0A - ldrb r2, [r1, #0]
70 02 - strb r2, [r0, #0]
30 01 - adds r0, #1
// EXIT
BD 04 - pop {r2, pc}


Результат на Cortex-M0
Цитата
RESULT[20000F44]: 78 56 34 12 CD AB 44 33 22 11 77 88
Go to the top of the page
 
+Quote Post
jcxz
сообщение Jun 30 2018, 00:22
Сообщение #47


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(adnega @ Jun 30 2018, 00:21) *
Проверил в железе - работает (Cortex-M0).

мммм... неправильно laughing.gif
См. моё сообщение #39 - какой должен быть результат работы.
К тому же: a) const в аргументе set_new_mask() - лишнее; б) R2,LR в вашей функции - не нужно сохранять, см. соглашения вызова компилятора; в) даже по Вашему алгоритму копирования - очень неоптимально, количество команд в 2 раза больше, чем можно было бы (для Cortex-M4).
Go to the top of the page
 
+Quote Post
adnega
сообщение Jun 30 2018, 06:41
Сообщение #48


Гуру
******

Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702



Цитата(jcxz @ Jun 30 2018, 03:22) *
мммм... неправильно

А что именно неправильно?
Есть таблица переменных состоящая из значений и типов.
Есть маска, где каждый бит связан с соответствующим элементом таблицы.
Есть функция-генератор, создающая в рантайме код, при выполнении которого
в выходной поток копируются данные из таблицы с учетом длины и заданной маски.
Для заданного var, RESULT (отработал СМК) такой ожидаете?
Если нет, то где ошибка?

Цитата(jcxz @ Jun 30 2018, 03:22) *
a) const в аргументе set_new_mask() - лишнее;

Ну, функция set_new_mask не должна менять mask, поэтому и const. Или я вас не понял.

Цитата(jcxz @ Jun 30 2018, 03:22) *
б) R2,LR в вашей функции - не нужно сохранять, см. соглашения вызова компилятора;

Вы же супер-скорость хотели. Выкидывайте push и pop - и вот вам готовый участок кода, дающий результат,
но не забудьте проинициализировать r0 и r1.
Если нужна именно как функция, то достаточно одного "bx lr" в конце.

Цитата(jcxz @ Jun 30 2018, 03:22) *
в) даже по Вашему алгоритму копирования - очень неоптимально, количество команд в 2 раза больше, чем можно было бы (для Cortex-M4).

Какие именно команды лишние? Можно IS_ALIGN обнулить, тогда генератор будет работать с невыровненными данными.
Попробую сегодня избавиться от лишних adds.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Jun 30 2018, 07:21
Сообщение #49


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(adnega @ Jun 30 2018, 09:41) *
А что именно неправильно?
Есть таблица переменных состоящая из значений и типов.

Вы же ассемблер понимаете? Тогда посмотрите на требуемый результат (код) в сообщении #39 и поймёте в чём разница.
Нет таблицы переменных, есть таблица указателей на переменные. Так как эти переменные разбросаны по всей программе и объединить их в одну область памяти (структуру) нельзя. Они находятся в разных обособленных службах программы, и там и должны оставаться. А адресация их идёт через таблицу указателей. Я писал об этом. И в примере результата это чётко видно.
Если си-исходник будет понятней, то:
CODE
enum {N = <максимум 64>};
enum {TYP_s16, TYP_u16, TYP_s32, TYP_u32, TYP_float, TYP_n};
struct {
u8 main:3;
u8 misc:5;
} const isTyp[N] = {{TYP_s32, ...}, {TYP_u16, ...}, ...};
u8 isTypSize[TYP_n] = {2, 2, 4, 4, 4};
char *psrc;
char *pdst;
if (map & 1 << 0) {
psrc = varPtrs[0];
if (isTypSize[isTyp[0].main]) == 4) {
*(u32 *)pdst = *(u32 *)psrc;
pdst += 4;
} else {
*(u16 *)pdst = *(u16 *)psrc;
pdst += 2;
}
}
if (map & 1 << 1) {
psrc = varPtrs[1];
if (isTypSize[isTyp[1].main]) == 4) {
*(u32 *)pdst = *(u32 *)psrc;
pdst += 4;
} else {
*(u16 *)pdst = *(u16 *)psrc;
pdst += 2;
}
}
//и так далее... так сейчас в си-исходнике сделано. Цель СМК - построить оптимальный код выкинув кучу ненужных операций из этого алгоритма по текущей карте map, до следующего её изменения.


Цитата(adnega @ Jun 30 2018, 09:41) *
Какие именно команды лишние? Можно IS_ALIGN обнулить, тогда генератор будет работать с невыровненными данными.
Попробую сегодня избавиться от лишних adds.

У меня Cortex-M4. Он поддерживает команды с пост- и пре- модификациями адреса. Например: LDR R0, [R1], #4 тогда ваш код сократится в 2 раза.
Да я уже вчера всё сделал. И даже больше. Мой генератор ещё и перемежение команд поддерживает для исключения штрафов между командами LDR. rolleyes.gif
И я его на асме написал. Хотя это просто из спортивного интереса. cool.gif
Go to the top of the page
 
+Quote Post
adnega
сообщение Jun 30 2018, 08:59
Сообщение #50


Гуру
******

Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702



Цитата(jcxz @ Jun 30 2018, 10:21) *
Да я уже вчера всё сделал

Покажите пожалуйста выход генератора для случая DWORD, WORD, DWORD, BYTE, BYTE в виде asm-инструкций.
У меня с таблицей переменных и невыровненными данным получилось так
CODE
// r0 = *s, r1 = var
// DWORD[0]
68 0A - ldr r2, [r1, #0]
60 02 - str r2, [r0, #0]
// WORD[1]
89 0A - ldrh r2, [r1, #8]
80 82 - strh r2, [r0, #4]
// DWORD[2]
8A 0A - ldrh r2, [r1, #16]
80 C2 - strh r2, [r0, #6]
8A 4A - ldrh r2, [r1, #18]
81 02 - strh r2, [r0, #8]
// BYTE[6]
31 30 - add r1, #48
78 0A - ldrb r2, [r1, #0]
72 82 - strb r2, [r0, #10]
// BYTE[7]
7A 0A - ldrb r2, [r1, #8]
72 C2 - strb r2, [r0, #11]
30 0C - adds r0, #12
47 70 - bx lr


Кста, а есть у кого-нить справочник машинных кодов для Cortex-M всех семейств?
Не путать со справочником asm-команд, который найти не составляет труда.
Go to the top of the page
 
+Quote Post
AlexandrY
сообщение Jun 30 2018, 10:09
Сообщение #51


Ally
******

Группа: Модераторы
Сообщений: 6 232
Регистрация: 19-01-05
Пользователь №: 2 050



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

ARM®v7-M Architecture Reference Manual

Господа, вы тут явно пытаетесь эмулировать DMA. biggrin.gif
Go to the top of the page
 
+Quote Post
AVI-crak
сообщение Jun 30 2018, 11:24
Сообщение #52


Частый гость
**

Группа: Участник
Сообщений: 182
Регистрация: 16-10-15
Пользователь №: 88 894



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

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

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

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

Имеет смысл посмотреть блочную реализацию парсера бэйсика. На него кстати есть с десяток активных проектов на гите, в том числе и под арм.
Или реализацию джавы для арм, хотя там без тяжёлых наркотиков очень трудно разобраться.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Jun 30 2018, 11:56
Сообщение #53


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(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) *
Более простое название этого процесса - полиморфный код.

Мне без разницы как это называть. Пускай будет полиморфный.
А что именно требуется - мне кажется уже каждый должен был понять, хоть немного почитав тред.
Go to the top of the page
 
+Quote Post
adnega
сообщение Jun 30 2018, 12:12
Сообщение #54


Гуру
******

Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702



Цитата(jcxz @ Jun 30 2018, 14:56) *
Да, как только поборю IAR.

gcc-шный objdump легко превращает бинарник в s-файл.
Можете скинуть бинарь - я его конвертну, если у вас нет gcc.
Go to the top of the page
 
+Quote Post
AlexandrY
сообщение Jun 30 2018, 13:17
Сообщение #55


Ally
******

Группа: Модераторы
Сообщений: 6 232
Регистрация: 19-01-05
Пользователь №: 2 050



Цитата(jcxz @ Jun 30 2018, 14:56) *
Да причём тут DMA??? Каким боком он поможет в этой задаче? Разве чтобы только затормозить процедуру в несколько раз?

Скопирует все переменные в одну область и вышлет куда надо.
Или даже без копирования вышлет.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Jun 30 2018, 13:30
Сообщение #56


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(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 не захватывает текст из этого окна):
Прикрепленное изображение

А здесь результат в бинарнике:
Прикрепленный файл  smk00.zip ( 233 байт ) Кол-во скачиваний: 4

Итого - время выполнения этого кода думаю будет == примерно 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
Про передачу свЯзными списками я в курсе.
Go to the top of the page
 
+Quote Post
AlexandrY
сообщение Jun 30 2018, 13:39
Сообщение #57


Ally
******

Группа: Модераторы
Сообщений: 6 232
Регистрация: 19-01-05
Пользователь №: 2 050



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

И чем не подошла передача связными списками?
Go to the top of the page
 
+Quote Post
jcxz
сообщение Jun 30 2018, 13:56
Сообщение #58


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



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

Тем что при программировании каждого сегмента списка, DMA-контроллер читает из памяти следующий блок-описатель сегмента, который в моём МК насколько помню == 5 слов. Это кроме собственно пересылки потом. И так - на каждую переменную. В итоге количество обращений к памяти в разы больше, и скорость выполнения в разы меньше чем с СМК. Уже не говоря о манипуляциях с IO-регистрами DMA.
Да и ОЗУ для описания такого связного списка нужно больше.
В то время как время выполнения результата генератора СМК приведённого выше, думаю должно быть == ~31 такт.
Go to the top of the page
 
+Quote Post
AlexandrY
сообщение Jun 30 2018, 14:43
Сообщение #59


Ally
******

Группа: Модераторы
Сообщений: 6 232
Регистрация: 19-01-05
Пользователь №: 2 050



Цитата(jcxz @ Jun 30 2018, 16:56) *
В то время как время выполнения результата генератора СМК приведённого выше, думаю должно быть == ~31 такт.

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

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

Я честно думал, что речь идет об оптимизации именно алгоритмов в токовых контурах или алгоритмов модуляции.
Go to the top of the page
 
+Quote Post
Arlleex
сообщение Jun 30 2018, 15:09
Сообщение #60


Местный
***

Группа: Участник
Сообщений: 492
Регистрация: 12-11-11
Пользователь №: 68 264



jcxz, а зачем тут это? Вы сначала загружаете адрес интересуемой переменной из таблицы, потом загружаете значение переменной по этому адресу, и сохраняете в dst с постинкрементом, это понятно. А выделенное то зачем? Вы что-то говорили про перемежение инструкций для удаления штрафов LDR/STR. Могли бы озвучить, в чем там проблема?
Go to the top of the page
 
+Quote Post

5 страниц V  « < 2 3 4 5 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 21st June 2025 - 06:17
Рейтинг@Mail.ru


Страница сгенерированна за 0.0152 секунд с 7
ELECTRONIX ©2004-2016