Ассемблер для STM32. Сложно ли, стоит ли пытаться?
- VladislavS
- Собутыльник Кота
- Сообщения: 2562
- Зарегистрирован: Вт май 01, 2018 19:44:47
Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?
Я же всё показал. Сравнивай сам.
Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?
[uquote="Dimon456",url="/forum/viewtopic.php?p=3951622#p3951622"]Поигрался я с идеей iddqd, есть 2 варианта:
1 вариант, когда пины располагаются на одном порту, не важно в какой последовательности.
ОЗУ на один пин 4 байта, на 8 пинов 32 байта.[/uquote] Технически на 1 пин - 1 бит на порцию, если -> ODR или 2 бита, если -> BSRR. В допущении port-wide доступа. Port-wide доступ имеет смысл например если там LCD с 8-bit bus развесили или например большая группа светодиодов, etc. В принципе с BSRR это битовая маска + latch, так что можно и меньше пинов за раз ворочать, с ухучшением КПД этой операции.
[uquote="AVI-crak",url="/forum/viewtopic.php?p=3951673#p3951673"]Для того чтобы графику в жк индикатор писать - нужно дма вместе с таймером использовать.[/uquote] И вас с новым годом. Я попробовал и с mem2mem. Вообще на светодиодах которым я сделал так подобие PWM это прокатило. Но выпадут ли из порта трансферы и прокатят ли уж какие получатся тайминги (дисплею это важно) если расписать "bus seqencing" и весь его пульнуть как mem2mem - вопрос открытый. Желающие могут позырить если у них скоростной многоканальный логический анализатор есть.
[uquote="BlackKilkennyCat",url="/forum/viewtopic.php?p=3951682#p3951682"]PWM в микроконтроллере это значительно больше, чем "ногодрыганье" с определенной частотой, и как только начнётся попытка реализовать его полноценную работу, и глянется на блок-схему, то на DMA останется минимум функционала.[/uquote] Так реализуется только очень базовый вариант PWM, с рядом ограничений. Скажите, а вам никогда не хотелось PWM'нуть сразу МНОГО светодиодов, например? Можно и не PWM'нуть, а "sequence". При том вот так - число выходов "PWM" таки до 16 на порт - и таки в отличие от совсем софтварных эрзацев хорошо подперто железом, вплоть до того что будет долбить указанным (при формировании буфера) duty/последовательностью даже при кончине (или занятости) процессорного ядра. Да еще шину потоком команд не грузит, в отличие от софтэрзацев. А рассуждения о хардварных PWM - это прекрасно, но вот захочется пару десятков каналов "хоть какого-то PWM", для например группы светодиодов - и тогда чего? Хардварных каналов ограниченное количество, и вот для них можно и интереснее и требовательнее применения найти.
PWM до кучи придумался. Несколько интереснее ... скажем так, "штукам с разверткой". Когда куча светодиодов на энном порту имеет некий смысл. Вот там таймер ... может очень круто вписаться. Такой себе аппаратный blitter/display controller, если можно так сказать про такую штуку.
1 вариант, когда пины располагаются на одном порту, не важно в какой последовательности.
ОЗУ на один пин 4 байта, на 8 пинов 32 байта.[/uquote] Технически на 1 пин - 1 бит на порцию, если -> ODR или 2 бита, если -> BSRR. В допущении port-wide доступа. Port-wide доступ имеет смысл например если там LCD с 8-bit bus развесили или например большая группа светодиодов, etc. В принципе с BSRR это битовая маска + latch, так что можно и меньше пинов за раз ворочать, с ухучшением КПД этой операции.
Любую идею можно довести до маразма. Слать можно отдельные регионы картинки/небольшие иконки/инициализацию дисплея/etc и размер может быть вменяемым. Кстати и ряд других коммуникаций недурно смотрится в виде make packet -> queue send, а пока оно там send можно чем-то еще заняться. И если там всякое сжатие, ну тогда после decompress и "prepare buffer" из вон того куска наверное ок? А какие еще варианты? Если контроллер шины есть то все просто, но он только в очень разлапистых камнях, они дорогие и роутить печатку заманаешься, в общем это сразу повышает планку. А без него вообще какие варианты? Софтом ногодрыгать? Так это вообще блокирующая операция, на ее время проц недееспособен толком (минус IRQ). А, ну еще RTOS можно, но я не знаю как там с таймингами шины будет, в такие дебри я лезть не собираюсь. Мне от MK нужен нижний уровень и предсказуемость, а не высокие абстракции.Если хранить картинку 256*256 точек, да в добавок в цветном изображении, параллельный порт 8 пинов, 256*256*3*32 = 6.291.456 байт.?
Есть варианты когда можно совсем без кода. Типа quasi-hardware PWM, когда целый порт ворочается закольцованым DMA без вмешательства софта вообще. Это будет работать даже если процессорное ядро встрянет. Правда оно тогда не сможет параметры подкручивать, но если это не требовалось, то там целиком железки без участия процессора смогут все сделать.Ну как так можно без кода обойтись? Ведь еще сжать картинку можно, без кода ни как.
1 пин не эффективно по КПД операции. Оно может ВЕСЬ ПОРТ за транзакцию кантовать. Но да, это потребует определенных компромиссов. Оптимальнее всего выделить весь порт под такое развлечение. А почему бы хардвару не сделать хардвару и софту удобно и быстро?. И да, data -> ODR будет с КПД вплоть до 100%. В BSRR только до 50%, битов в 2 раза больше. Зато есть latch, можно только некоторые биты ворочать. Это даже может сосуществовать с некоторой периферией - AFIO в общем случае не очень интересует что там GPIO пытался вообще изобразить. А какое дело какому-нибудь uart input'у до его бита в ODR?Значит дма будем запускать только на один пин, а в прерывании выключать канал,
Вы кажется не поняли. Суть идеи: в RAM или Flash заводится буфер. Он описывает sequencing группы пинов. Типа эволюции состояния порта во времени. И конечно же трансферов при этом должно быть уж точно не 1. Иначе нахрена б такое счастье с сетапом DMA. И да, поскольку DMA отпускает шину чтобы процу что-то дать, он рекорд скорости может и не поставит. Но есть одна killer feature. Мы можем "зарядить отправку пакета" или даже "закольцевать отправку буфера" - и заняться своими делами! DMA асинхронен относительно кода проца. Так что основной профит - в асинхронщине этого относительно процессора и подпертости железом. А отсутствие трафика кода по шинам для этой активности - приятный побочный эффект, DMA не процессор, ему для ворочания порции данных не надо инструкции по шине гонять. Если хочется именно 1 бит, именно DMA, ну, не знаю, SPI какой поюзайте, чтоли. Он видите ли десереализует то что в него вгрузили, так КПД операции сильно интереснее, а послать опять же можно "целый пакет" и даже, вероятно, закольцевать, если это за каким-то чертом надо.А теперь вопрос в практическом применении, для чего и за чем? И где тут выигрыш в скорости?
[uquote="AVI-crak",url="/forum/viewtopic.php?p=3951673#p3951673"]Для того чтобы графику в жк индикатор писать - нужно дма вместе с таймером использовать.[/uquote] И вас с новым годом. Я попробовал и с mem2mem. Вообще на светодиодах которым я сделал так подобие PWM это прокатило. Но выпадут ли из порта трансферы и прокатят ли уж какие получатся тайминги (дисплею это важно) если расписать "bus seqencing" и весь его пульнуть как mem2mem - вопрос открытый. Желающие могут позырить если у них скоростной многоканальный логический анализатор есть.
[uquote="BlackKilkennyCat",url="/forum/viewtopic.php?p=3951682#p3951682"]PWM в микроконтроллере это значительно больше, чем "ногодрыганье" с определенной частотой, и как только начнётся попытка реализовать его полноценную работу, и глянется на блок-схему, то на DMA останется минимум функционала.[/uquote] Так реализуется только очень базовый вариант PWM, с рядом ограничений. Скажите, а вам никогда не хотелось PWM'нуть сразу МНОГО светодиодов, например? Можно и не PWM'нуть, а "sequence". При том вот так - число выходов "PWM" таки до 16 на порт - и таки в отличие от совсем софтварных эрзацев хорошо подперто железом, вплоть до того что будет долбить указанным (при формировании буфера) duty/последовательностью даже при кончине (или занятости) процессорного ядра. Да еще шину потоком команд не грузит, в отличие от софтэрзацев. А рассуждения о хардварных PWM - это прекрасно, но вот захочется пару десятков каналов "хоть какого-то PWM", для например группы светодиодов - и тогда чего? Хардварных каналов ограниченное количество, и вот для них можно и интереснее и требовательнее применения найти.
PWM до кучи придумался. Несколько интереснее ... скажем так, "штукам с разверткой". Когда куча светодиодов на энном порту имеет некий смысл. Вот там таймер ... может очень круто вписаться. Такой себе аппаратный blitter/display controller, если можно так сказать про такую штуку.
- AVI-crak
- Прорезались зубы
- Сообщения: 202
- Зарегистрирован: Сб янв 09, 2016 15:51:17
- Контактная информация:
Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?
[uquote="iddqd",url="/forum/viewtopic.php?p=3955397#p3955397"]Но выпадут ли из порта трансферы и прокатят ли уж какие получатся тайминги (дисплею это важно)[/uquote]
Один канал таймера использовать как имитацию ноги WR, вторым каналом пинать дма. И да, дма уже загрузило данные для дальнейшей работы, если хочется - можно грузить целую пачку данных. Потери данных могут возникнуть только в одном случае: другой дма с более высоким приоритетом фигачет в режиме нонстоп.
Один канал таймера использовать как имитацию ноги WR, вторым каналом пинать дма. И да, дма уже загрузило данные для дальнейшей работы, если хочется - можно грузить целую пачку данных. Потери данных могут возникнуть только в одном случае: другой дма с более высоким приоритетом фигачет в режиме нонстоп.
-
bob1
- Мучитель микросхем
- Сообщения: 453
- Зарегистрирован: Ср июн 08, 2011 20:25:20
- Контактная информация:
Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?
Продолжение от сюда https://radiokot.ru/forum/viewtopic.php ... start=8840
По поводу тактов возник вопрос.
Команда LDR R0,[R1, #+0]; лежит уже в конвейере. До нее и после команд чтения и записи нет. За сколько тактов должна обработаться? За 2 или 3? процессор STM32G431.
[uquote="jcxz",url="/forum/viewtopic.php?p=4745295#p4745295"]Почему 2/3?[/uquote] Вопрос и возник, что меньше 3 не могу получить, а в теории должно быть 2.
[uquote="jcxz",url="/forum/viewtopic.php?p=4745295#p4745295"]Раз не с кем спариваться, то в вашем случае на CM4 должно быть 2 такта.[/uquote]
Ниже тестовая прога для теста. Лежит в ССM, хотя из флешь также работает. Частота 16МГц.
Изменяя n вычисляем разницу счета таймера 4. Получаем такты за цикл. В меньшем случае 21=7+2+3*4. 7 это 1 тактовые команды, 2 такта переход, 4- количество LDR. 3 выходит такты выполнения команды LDR.
Ниже листинг цикла. Для правильного получения нужно поиграться оптимизацией для разных reg.
По поводу тактов возник вопрос.
Команда LDR R0,[R1, #+0]; лежит уже в конвейере. До нее и после команд чтения и записи нет. За сколько тактов должна обработаться? За 2 или 3? процессор STM32G431.
[uquote="jcxz",url="/forum/viewtopic.php?p=4745295#p4745295"]Почему 2/3?[/uquote] Вопрос и возник, что меньше 3 не могу получить, а в теории должно быть 2.
[uquote="jcxz",url="/forum/viewtopic.php?p=4745295#p4745295"]Раз не с кем спариваться, то в вашем случае на CM4 должно быть 2 такта.[/uquote]
Ниже тестовая прога для теста. Лежит в ССM, хотя из флешь также работает. Частота 16МГц.
Изменяя n вычисляем разницу счета таймера 4. Получаем такты за цикл. В меньшем случае 21=7+2+3*4. 7 это 1 тактовые команды, 2 такта переход, 4- количество LDR. 3 выходит такты выполнения команды LDR.
Спойлер
Код: Выделить всё
/*
#define reg (uint32_t) TIM4->CNT
#define reg1 (uint32_t) TIM4->CNT
#define reg2 (uint32_t) TIM4->CNT
#define reg3 (uint32_t) TIM4->CNT
*/
#define reg (uint32_t) GPIOA->IDR
#define reg1 (uint32_t) GPIOA->IDR
#define reg2 (uint32_t) GPIOA->IDR
#define reg3 (uint32_t) GPIOA->IDR
/*
#define reg bx[0]
#define reg1 bx[1]
#define reg2 bx[2]
#define reg3 bx[3]
*/
__root uint32_t bx[]={1,2,3,4};
__root uint32_t res;
void test (void)@".ccmram"{
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM4);
LL_DBGMCU_APB1_GRP1_FreezePeriph(LL_DBGMCU_APB1_GRP1_TIM4_STOP);
LL_TIM_InitTypeDef TIM_InitStruct = {0};
TIM_InitStruct.Autoreload = 0xFFFFFFFFU;
LL_TIM_Init(TIM4, &TIM_InitStruct);
uint32_t n=6;
uint32_t w,w1;
TIM4->CR1=1;
//--------------------------
do{
w=reg;
w1=w1+w;
w= reg1;
w1=w1+w;
w= reg2;
w1=w1+w;
w= reg3;
w1=w1+w;
}
while (n--!=0) ;
//--------------------------
res=w1;
TIM4->CR1=0;
};Спойлер
Код: Выделить всё
// 1102 //--------------------------
// 1103 do{
// 1104 w=reg;
??test_1:
LDR R0,[R3, #+0]
// 1105 w1=w1+w;
ADDS R2,R0,R2
// 1106 w= reg1;
LDR R0,[R3, #+0]
// 1107 w1=w1+w;
ADDS R2,R0,R2
// 1108 w= reg2;
LDR R0,[R3, #+0]
// 1109 w1=w1+w;
ADDS R2,R0,R2
// 1110 w= reg3;
LDR R0,[R3, #+0]
// 1111 w1=w1+w;
ADDS R2,R0,R2
// 1112 }
// 1113 while (n--!=0) ;
MOV R0,R1
SUBS R1,R0,#+1
CMP R0,#+0
BNE.N ??test_1
// 1114 //-------------------------- Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?
[uquote="bob1",url="/forum/viewtopic.php?p=4745460#p4745460"]Команда LDR R0,[R1, #+0]; лежит уже в конвейере.[/uquote]Почему такой вывод?
Какова ширина шины CPU, читающей поток команд из данной памяти? Есть ли другие bus-masters, работающие в это время?
[uquote="bob1",url="/forum/viewtopic.php?p=4745460#p4745460"]Ниже тестовая прога для теста. Лежит в ССM, хотя из флешь также работает. Частота 16МГц.
Изменяя n вычисляем разницу счета таймера 4. Получаем такты за цикл. В меньшем случае 21=7+2+3*4. 7 это 1 тактовые команды, 2 такта переход, 4- количество LDR. 3 выходит такты выполнения команды LDR.[/uquote]
А куда указывает R3? Откуда идёт чтение?
И как именно производите замер времени выполнения цикла?
Имхо: тестовый код - некорректный. Длительность выполнения LDR следует измерять не так.
Также необходимо прояснить целевой адрес R3. Вангую, что R3 указывает в тот же регион памяти, где находится код. Отсюда и лишний такт.
Какова ширина шины CPU, читающей поток команд из данной памяти? Есть ли другие bus-masters, работающие в это время?
[uquote="bob1",url="/forum/viewtopic.php?p=4745460#p4745460"]Ниже тестовая прога для теста. Лежит в ССM, хотя из флешь также работает. Частота 16МГц.
Изменяя n вычисляем разницу счета таймера 4. Получаем такты за цикл. В меньшем случае 21=7+2+3*4. 7 это 1 тактовые команды, 2 такта переход, 4- количество LDR. 3 выходит такты выполнения команды LDR.[/uquote]
А куда указывает R3? Откуда идёт чтение?
И как именно производите замер времени выполнения цикла?
Имхо: тестовый код - некорректный. Длительность выполнения LDR следует измерять не так.
Также необходимо прояснить целевой адрес R3. Вангую, что R3 указывает в тот же регион памяти, где находится код. Отсюда и лишний такт.
-
bob1
- Мучитель микросхем
- Сообщения: 453
- Зарегистрирован: Ср июн 08, 2011 20:25:20
- Контактная информация:
Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?
[uquote="jcxz",url="/forum/viewtopic.php?p=4745491#p4745491"]Почему такой вывод?[/uquote] Это не вывод, а убрать вопросы про время загрузки команды в конвейер. Про кеш, ускоритель...
[uquote="jcxz",url="/forum/viewtopic.php?p=4745491#p4745491"]Какова ширина шины CPU, читающей поток команд из данной памяти?[/uquote] 64.
[uquote="jcxz",url="/forum/viewtopic.php?p=4745491#p4745491"]Есть ли другие bus-masters, работающие в это время?[/uquote] Нет. Тестовая функция практически в начале main.
[uquote="jcxz",url="/forum/viewtopic.php?p=4745491#p4745491"]А куда указывает R3? Откуда идёт чтение?[/uquote] В тестовой функции экспериментировал чтение с TIM4->CNT , GPIOA->IDR и SRAM. Наверху кода выбирается в #define reg*.
[uquote="jcxz",url="/forum/viewtopic.php?p=4745491#p4745491"]И как именно производите замер времени выполнения цикла?[/uquote] Изменяя n. К примеру выбираю n=6. Таймер 4 считает время выполнения кода. Увеличиваю n=7. Опять таймер считает. Разница счетов и дает время выполнения цикла. Увеличивая n на 1, то счет Tаймера 4 растет на одну и туже величину.
[uquote="jcxz",url="/forum/viewtopic.php?p=4745491#p4745491"]Длительность выполнения LDR следует измерять не так.[/uquote] Готов посмотреть и ваш код.
[uquote="jcxz",url="/forum/viewtopic.php?p=4745491#p4745491"]Вангую, что R3 указывает в тот же регион памяти, где находится код.[/uquote] В примере код в ССМ. Код был и во флеши (при enable ICEN bit ). Результат одинаковый. Чтение кода и памяти (куда указывает R3) идет по разным шинам.
[uquote="jcxz",url="/forum/viewtopic.php?p=4745491#p4745491"]Какова ширина шины CPU, читающей поток команд из данной памяти?[/uquote] 64.
[uquote="jcxz",url="/forum/viewtopic.php?p=4745491#p4745491"]Есть ли другие bus-masters, работающие в это время?[/uquote] Нет. Тестовая функция практически в начале main.
Код: Выделить всё
int main(void){
SCB->VTOR = CCMSRAM_BASE;
LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_SYSCFG);
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_PWR);
LL_RCC_ForceBackupDomainReset();
LL_RCC_ReleaseBackupDomainReset();
LL_PWR_EnableBkUpAccess();
LL_PWR_DisableDeadBatteryPD();
test();
[uquote="jcxz",url="/forum/viewtopic.php?p=4745491#p4745491"]И как именно производите замер времени выполнения цикла?[/uquote] Изменяя n. К примеру выбираю n=6. Таймер 4 считает время выполнения кода. Увеличиваю n=7. Опять таймер считает. Разница счетов и дает время выполнения цикла. Увеличивая n на 1, то счет Tаймера 4 растет на одну и туже величину.
[uquote="jcxz",url="/forum/viewtopic.php?p=4745491#p4745491"]Длительность выполнения LDR следует измерять не так.[/uquote] Готов посмотреть и ваш код.
[uquote="jcxz",url="/forum/viewtopic.php?p=4745491#p4745491"]Вангую, что R3 указывает в тот же регион памяти, где находится код.[/uquote] В примере код в ССМ. Код был и во флеши (при enable ICEN bit ). Результат одинаковый. Чтение кода и памяти (куда указывает R3) идет по разным шинам.
Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?
[uquote="bob1",url="/forum/viewtopic.php?p=4745502#p4745502"][uquote="jcxz",url="/forum/viewtopic.php?p=4745491#p4745491"]Какова ширина шины CPU, читающей поток команд из данной памяти?[/uquote] 64.[/uquote]В моём текущем XMC4500 - столько же. Точнее - это ширина шины, читающей из кеша в буфер предвыборки. Ширина шин к памяти - разная, в зависимости от типа памяти. Up to 256 бит.
[uquote="bob1",url="/forum/viewtopic.php?p=4745502#p4745502"]Изменяя n. К примеру выбираю n=6. Таймер 4 считает время выполнения кода. Увеличиваю n=7. Опять таймер считает. Разница счетов и дает время выполнения цикла. Увеличивая n на 1, то счет Tаймера 4 растет на одну и туже величину.[/uquote]Некорректный метод. Не учитывает возможного времени перезагрузки буфера предвыборки при переходе. Также не учитывается невыровненность целевого адреса перехода. И не вижу запрета прерываний на время теста.
[uquote="bob1",url="/forum/viewtopic.php?p=4745502#p4745502"]Готов посмотреть и ваш код.[/uquote]Код (IAR):Вызов из си++:
Таймеры для измерения тоже не нужны - IAR (у вас же вроде IAR?) сам умеет измерять по отладочному таймеру DWT.CYCCNT. Ставим бряки как на картинке ниже:

потом делаем один шаг "step into" чтобы соскочить с бряка (так как на некоторых МК в некоторых памятях это добавляет лишние такты (при soft-бряках)):

потом жмём "go". Останавливается на 2-м бряке, смотрим поле "CCSTEP":

Делаем рестарт МК, после "step into" вводим в R2 вручную 4, "go", результат:

Как видно - у меня разница составила 34-27=7 тактов. Следовательно - длительность LDR = 2 такта. Как и ожидалось.
И нет влияния времени перезагрузки буфера предвыборки при переходе по BNE.
Можно ещё улучшить тест. Исключив возможное влияние перезагрузки буфера предвыборки. После первой пары LDR/MOVS добавляем 2-ю такую же пару:

Делаем тест (с тем же числом проходов). У меня получилось == 49 тактов:

Считаем (49-34)/5 = 3 такта добавилось. Тоже - как и ожидалось.
В моих тестах 0x20000000 - адрес начала одного из регионов ОЗУ. Код выполняется из другого региона ОЗУ (0x10000000).
Добавлено after 7 minutes 19 seconds:
PS: [uquote="bob1",url="/forum/viewtopic.php?p=4745460#p4745460"][/uquote]Если цель - писать оптимально, то это плохая организация цикла. Используя постфиксную операцию декремента, вы не даёте компилятору использовать флаги результата команды SUBS, заставляя его добавлять ненужную CMP.
Лучше использовать префиксный декремент:или в этих случаях будет одна команда SUBS за которой сразу BNE.
Хотя для целей измерения времени выполнения команды тут конечно всё равно.
[uquote="bob1",url="/forum/viewtopic.php?p=4745502#p4745502"]Изменяя n. К примеру выбираю n=6. Таймер 4 считает время выполнения кода. Увеличиваю n=7. Опять таймер считает. Разница счетов и дает время выполнения цикла. Увеличивая n на 1, то счет Tаймера 4 растет на одну и туже величину.[/uquote]Некорректный метод. Не учитывает возможного времени перезагрузки буфера предвыборки при переходе. Также не учитывается невыровненность целевого адреса перехода. И не вижу запрета прерываний на время теста.
[uquote="bob1",url="/forum/viewtopic.php?p=4745502#p4745502"]Готов посмотреть и ваш код.[/uquote]Код (IAR):
Код: Выделить всё
SECTION .text:CODE:NOROOT(2)
PUBLIC TestLdr
THUMB
;extern "C" void TestLdr(u32 const *);
TestLdr: MRS R12, PRIMASK
CPSID I
MOVS R2, #5
alignrom 2, 0xBF00
TestLdr_01: MOVS R3, #1
LDR R1, [R0]
MOVS R3, #1
SUBS R2, R2, #1
BNE TestLdr_01
MSR PRIMASK, R12
BX LRКод: Выделить всё
extern "C" void TestLdr(u32 const *);
TestLdr((u32 const *)0x20000000);
потом делаем один шаг "step into" чтобы соскочить с бряка (так как на некоторых МК в некоторых памятях это добавляет лишние такты (при soft-бряках)):

потом жмём "go". Останавливается на 2-м бряке, смотрим поле "CCSTEP":

Делаем рестарт МК, после "step into" вводим в R2 вручную 4, "go", результат:

Как видно - у меня разница составила 34-27=7 тактов. Следовательно - длительность LDR = 2 такта. Как и ожидалось.
И нет влияния времени перезагрузки буфера предвыборки при переходе по BNE.
Можно ещё улучшить тест. Исключив возможное влияние перезагрузки буфера предвыборки. После первой пары LDR/MOVS добавляем 2-ю такую же пару:

Делаем тест (с тем же числом проходов). У меня получилось == 49 тактов:

Считаем (49-34)/5 = 3 такта добавилось. Тоже - как и ожидалось.
В моих тестах 0x20000000 - адрес начала одного из регионов ОЗУ. Код выполняется из другого региона ОЗУ (0x10000000).
Добавлено after 7 minutes 19 seconds:
PS: [uquote="bob1",url="/forum/viewtopic.php?p=4745460#p4745460"]
Код: Выделить всё
// 1113 while (n--!=0) ;
MOV R0,R1
SUBS R1,R0,#+1
CMP R0,#+0
BNE.N ??test_1Лучше использовать префиксный декремент:
Код: Выделить всё
int n = N; do { ... } while (--n);Код: Выделить всё
int n = N - 1; do { ... } while (--n >= 0);Хотя для целей измерения времени выполнения команды тут конечно всё равно.
-
bob1
- Мучитель микросхем
- Сообщения: 453
- Зарегистрирован: Ср июн 08, 2011 20:25:20
- Контактная информация:
Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?
Разобрался частично. Вывод: кеш инструкций включен, инструкции должны загружаться по I-bus, данные по D-bus. Загрузка по S-bus добавляет 1 такт в лучшем случае и получается, что с периферии данные считываются за 3 такта.
з.ы. Вопросы по расположению кода (цикла) еще остались. Потом еще поэкспериментирую.
з.ы. Вопросы по расположению кода (цикла) еще остались. Потом еще поэкспериментирую.
Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?
[uquote="bob1",url="/forum/viewtopic.php?p=4745753#p4745753"]с периферии данные считываются за 3 такта.[/uquote]Ранее вы писали, что читаете из памяти:[uquote="bob1",url="/forum/viewtopic.php?p=4745502#p4745502"]Чтение кода и памяти (куда указывает R3)[/uquote]Почему сразу и спрашивал вас "откуда читаете?" При чтении из периферии есть много влияющих на чтение факторов: какая именно периферия? на какой шине (AHB, APB1, APB2 - для STM32)? какова частота шины?
Даже у разной периферии, находящейся на одной шине, длительность чтения может быть разной. К скорости выполнения LDR это не имеет отношения. Периферия может долго не ставить ready-сигнал, замораживая CPU.
PS: Иногда (на некоторых МК) помогает работа через bit-band область (если она есть в МК). На моих STM32 (STM32F4xx, STM32F1xx) работа с GPIO-потами через bit-band - заметно быстрее, чем через их регистры. Если подходит - можно попробовать переписать работу на bit-band и проверить.
Даже у разной периферии, находящейся на одной шине, длительность чтения может быть разной. К скорости выполнения LDR это не имеет отношения. Периферия может долго не ставить ready-сигнал, замораживая CPU.
PS: Иногда (на некоторых МК) помогает работа через bit-band область (если она есть в МК). На моих STM32 (STM32F4xx, STM32F1xx) работа с GPIO-потами через bit-band - заметно быстрее, чем через их регистры. Если подходит - можно попробовать переписать работу на bit-band и проверить.
-
bob1
- Мучитель микросхем
- Сообщения: 453
- Зарегистрирован: Ср июн 08, 2011 20:25:20
- Контактная информация:
Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?
[uquote="jcxz",url="/forum/viewtopic.php?p=4745834#p4745834"]Почему сразу и спрашивал вас "откуда читаете?"[/uquote] Меня интересовала не конкретная задача, а общий случай. Пробовал и код в ссм и читал ram с адреса 0x20000000. Это было в декабре. Код тогда сделал "3 тактах". Просто пришлось больше стыковать друг другу команд чтения и записи. Тогда и возник вопрос про чтение по 2-м тактам. Сейчас созрел задать его
[uquote="jcxz",url="/forum/viewtopic.php?p=4745834#p4745834"]какая именно периферия?[/uquote] ADC-результат. AHB2, делителя нет. Частота 32МГц такая же как у ядра SYSCLK. ADC тактируется без деления.
[uquote="jcxz",url="/forum/viewtopic.php?p=4745834#p4745834"]bit-band[/uquote] Возьму на заметку. Нужно было чтение всего слова.
[uquote="jcxz",url="/forum/viewtopic.php?p=4745834#p4745834"]можно попробовать переписать работу на и проверить.[/uquote] Сейчас завал.
[uquote="jcxz",url="/forum/viewtopic.php?p=4745834#p4745834"]К скорости выполнения LDR это не имеет отношения[/uquote] Если так, то еще попробую поиграться, но позже.....
з.ы. Спасибо за идеи. Результат "2 такта" получил.
[uquote="jcxz",url="/forum/viewtopic.php?p=4745834#p4745834"]какая именно периферия?[/uquote] ADC-результат. AHB2, делителя нет. Частота 32МГц такая же как у ядра SYSCLK. ADC тактируется без деления.
[uquote="jcxz",url="/forum/viewtopic.php?p=4745834#p4745834"]bit-band[/uquote] Возьму на заметку. Нужно было чтение всего слова.
[uquote="jcxz",url="/forum/viewtopic.php?p=4745834#p4745834"]можно попробовать переписать работу на и проверить.[/uquote] Сейчас завал.
[uquote="jcxz",url="/forum/viewtopic.php?p=4745834#p4745834"]К скорости выполнения LDR это не имеет отношения[/uquote] Если так, то еще попробую поиграться, но позже.....
з.ы. Спасибо за идеи. Результат "2 такта" получил.
-
shalfey
- Встал на лапы
- Сообщения: 123
- Зарегистрирован: Ср май 16, 2012 20:44:38
- Откуда: Харків-Україна.
Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?
не заморачивайся си проще ассемблера, ти будешь оцифровивать ззвук или что на си прекрасно все работает, даже уже плюси суют ни єто уже сноби, в контроллер плюси совать, микропайтон пихают в esp32, ну а тут давай и с++ всунем ми мол крутие, джаву еше всуньте.
-
shalfey
- Встал на лапы
- Сообщения: 123
- Зарегистрирован: Ср май 16, 2012 20:44:38
- Откуда: Харків-Україна.
Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?
[uquote="Shuspano",url="/forum/viewtopic.php?p=3741147#p3741147"]
А что тогда делать? "С" - он же намного сложнее асма, я его просто не осилю.[/uquote] Для STM Си не очень страшний,освой указатели массивы, циклы и тебе хватить такого наваять, если канечно ты не будешь туда операционку пихать.NStorm писал(а):Пытаться разбираться не стоит. Писать на асме бесперспективно