Ассемблер для STM32. Сложно ли, стоит ли пытаться?
- Eddy_Em
- Собутыльник Кота
- Сообщения: 2516
- Зарегистрирован: Пт июл 12, 2019 22:52:01
- Контактная информация:
Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?
[uquote="protoder",url="/forum/viewtopic.php?p=3742127#p3742127"]Я так понял, человек не про это спрашивает. Интересует что-то, где хорошо описывалось бы программирование для STM со всеми его библиотеками и периферией.[/uquote]
Тогда ему нужно качать сниппеты с сайта ST.
Пользоваться калокубами, SPLами и прочей дерьмотой (даже opencm3) ни в коем случае нельзя! Это как гланды через задницу выдирать...
Читаем даташит, читаем RM, смотрим сниппеты и собираем свои сниппеты и даже готовые блоки.
Я себе подобным образом постепенно базу набиваю. Тоже по дурости неопытной сначала SPL пробовал, потом какое-то время сидел на opencm3, и лишь по прошествию определенного времени (тут толчок нужен был и им было то, что разрабы opencm3 поломали API, и мое терпение лопнуло) постиг дзен!
Тогда ему нужно качать сниппеты с сайта ST.
Пользоваться калокубами, SPLами и прочей дерьмотой (даже opencm3) ни в коем случае нельзя! Это как гланды через задницу выдирать...
Читаем даташит, читаем RM, смотрим сниппеты и собираем свои сниппеты и даже готовые блоки.
Я себе подобным образом постепенно базу набиваю. Тоже по дурости неопытной сначала SPL пробовал, потом какое-то время сидел на opencm3, и лишь по прошествию определенного времени (тут толчок нужен был и им было то, что разрабы opencm3 поломали API, и мое терпение лопнуло) постиг дзен!
Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?
[uquote="Shuspano",url="/forum/viewtopic.php?p=3742179#p3742179"]Фух... вроде мигает. Да, от знания асма толку никакого вообще. Ну да ладно.
мне вот интересен еще момент. Почему если подпрограмму пишу где нить внизу листинга, а вызываю ее где нибудь вверху, например:
то транслятор ругается. Транслирует, но в итоге задержка не работает. А в асме это не разу не проблема.[/uquote]
Хорошие вопросы задаете, товарищ! Не, кроме шуток. Главный минус С - необходимость одно и то же по сто раз объявлять.
Но вам придется с этим смириться. Такова идеология С. Все, что вы используете, вы должны заранее объявить. Мое мнение, что оно прилетела со стародавніх времен, когда работает компилятор и хоть что-то хоть как-то компилит хотя бы за ночь ( не смейтесь. Я еще застал времена, когда С программу на компиляцию на ночь ставили) - уже праздник. Соответственно, в С вообще много фишек для облегчения жизни компилятору. Это - одна из них. Мне кажется, оно совершенно не современно. Но спорить - не возьмусь. Идеология - она вещь такая. Можно и в нос получить, ну ее нафиг
Так. Стоп. Поторопился, кинулся отвечать, до конца не дочитав. Вы хотите сказать, что ваш код откомпилирован, но при этом не происходит задержки? Так не должно быть. Полагаю, что у вас где-то есть заголовочный файл (например, какой-нибудь стандартной библиотеки), в котором уже описана функция delay, которая делает задержку. Поэтому компилятор не ругается.
Но при этом вы реализовываете функцию delay сами. А что будет, если вы уберете текст
void delay(uint16_t time)
{}
Заработает?
мне вот интересен еще момент. Почему если подпрограмму пишу где нить внизу листинга, а вызываю ее где нибудь вверху, например:
то транслятор ругается. Транслирует, но в итоге задержка не работает. А в асме это не разу не проблема.[/uquote]
Хорошие вопросы задаете, товарищ! Не, кроме шуток. Главный минус С - необходимость одно и то же по сто раз объявлять.
Но вам придется с этим смириться. Такова идеология С. Все, что вы используете, вы должны заранее объявить. Мое мнение, что оно прилетела со стародавніх времен, когда работает компилятор и хоть что-то хоть как-то компилит хотя бы за ночь ( не смейтесь. Я еще застал времена, когда С программу на компиляцию на ночь ставили) - уже праздник. Соответственно, в С вообще много фишек для облегчения жизни компилятору. Это - одна из них. Мне кажется, оно совершенно не современно. Но спорить - не возьмусь. Идеология - она вещь такая. Можно и в нос получить, ну ее нафиг
Так. Стоп. Поторопился, кинулся отвечать, до конца не дочитав. Вы хотите сказать, что ваш код откомпилирован, но при этом не происходит задержки? Так не должно быть. Полагаю, что у вас где-то есть заголовочный файл (например, какой-нибудь стандартной библиотеки), в котором уже описана функция delay, которая делает задержку. Поэтому компилятор не ругается.
Но при этом вы реализовываете функцию delay сами. А что будет, если вы уберете текст
void delay(uint16_t time)
{}
Заработает?
Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?
[uquote="protoder",url="/forum/viewtopic.php?p=3742251#p3742251"]Заработает?[/uquote]
Вот чего кокос выдал:
А вот моя писанина (вложение):
МК - плата с STM32F103RBT6 и программатор St-link V2, купил это добро на али в 2013 году.
Вот чего кокос выдал:
Код: Выделить всё
[cc] D:\Disk_D\PRG\coconut\main.c:18:5: warning: implicit declaration of function 'Delay' [-Wimplicit-function-declaration]
[cc] Delay(8000000);
[cc] ^~~~~
[cc] D:\Disk_D\PRG\coconut\main.c: At top level:
[cc] D:\Disk_D\PRG\coconut\main.c:22:6: warning: conflicting types for 'Delay'
А вот моя писанина (вложение):
МК - плата с STM32F103RBT6 и программатор St-link V2, купил это добро на али в 2013 году.
- Вложения
-
- main.c
- (617 байт) 363 скачивания
Последний раз редактировалось Shuspano Сб ноя 23, 2019 22:58:06, всего редактировалось 1 раз.
Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?
[uquote="Shuspano",url="/forum/viewtopic.php?p=3742179#p3742179"]Да, от знания асма толку никакого вообще.[/uquote]....заявил человек его не знающий 
Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?
Так приведите весь код, который нужно компилировать...jcxz писал(а):Неправильно скомпилили.
Что из себя представляет Pval, PIN_PRND_B и PIN_PRND_F?
Оптимизация O2, ядро M3.jcxz писал(а):Или у Вас включена оптимизация по размеру, а не по скорости, или выбрано неправильное ядро (не CM3, CM4F).
Потому что данные в __IO регистре, т. е. valatile. Было бы лучше если привели текстовый код. Это исключило бы неточности.jcxz писал(а):Компилятор у Вас зачем то перегружал повторно указатель, потратив на это лишние команды LDR.
Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?
[uquote="Shuspano",url="/forum/viewtopic.php?p=3742179#p3742179"]Фух... вроде мигает. Да, от знания асма толку никакого вообще. Ну да ладно.
мне вот интересен еще момент. Почему если подпрограмму пишу где нить внизу листинга, а вызываю ее где нибудь вверху, например:
то транслятор ругается. Транслирует, но в итоге задержка не работает. А в асме это не разу не проблема.[/uquote]
И никто до сих пор не заметил что-ли? Что 8000000 никак не влезет в uint16_t, где максимальное значение 65535. Делайте uint32_t.
И это ругается, потому что до вызова функцию нужно объявить. Сверху где-нибудь просто "void delay(uint32_t time);" всё, без кода функции. И ругаться не будет.
Но правильно сказали - писать на C учиться можно и на ПК. На МК оно не завязано. Ничем C для ПК не отличается от C для МК. Объявление регистров - это всего-лишь объявления регистрой. Ничего от EQU в асме не отличается.
мне вот интересен еще момент. Почему если подпрограмму пишу где нить внизу листинга, а вызываю ее где нибудь вверху, например:
Код: Выделить всё
while (1)
{
...
delay(8000000);
...
}
void delay(uint16_t time)
{}
то транслятор ругается. Транслирует, но в итоге задержка не работает. А в асме это не разу не проблема.[/uquote]
И никто до сих пор не заметил что-ли? Что 8000000 никак не влезет в uint16_t, где максимальное значение 65535. Делайте uint32_t.
И это ругается, потому что до вызова функцию нужно объявить. Сверху где-нибудь просто "void delay(uint32_t time);" всё, без кода функции. И ругаться не будет.
Но правильно сказали - писать на C учиться можно и на ПК. На МК оно не завязано. Ничем C для ПК не отличается от C для МК. Объявление регистров - это всего-лишь объявления регистрой. Ничего от EQU в асме не отличается.
- VladislavS
- Собутыльник Кота
- Сообщения: 2562
- Зарегистрирован: Вт май 01, 2018 19:44:47
Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?
[uquote="jcxz",url="/forum/viewtopic.php?p=3741718#p3741718"]В смысле "тот же"? Кто с кем?[/uquote]Немного поэкспериментировал с твоим примером. Процессор STM32F303 (CM4F), выполнение кода из SRAM. Скорее всего, из FLASH будут другие цифры по тактам.
Сделал тестовый код (надеюсь я правильно понял твои макросы). Тщательно проверил, чтобы считывание CYCCNT было строго одинаково везде.
Результаты под IAR и GCC
GCC -Os 19 тактов
GCC -O3 21 такт
Затем немного плюсовщины добавил, чтобы компилятор сделал таки то что ты от него хотел.И получил как разТолько разницы по тактам, как я и предполагал, никакой. Результаты под IAR и GCC
GCC -Os 19 тактов
GCC -O3 20 тактов
Но мы же любопытные. Полностью на плюсах получаем третий вариант на те же 17 тактов.
Сделал тестовый код (надеюсь я правильно понял твои макросы). Тщательно проверил, чтобы считывание CYCCNT было строго одинаково везде.
Код: Выделить всё
__disable_irq();
uint32_t t1 = DWT->CYCCNT;
__NOP();
GPIOC->ODR = 3 - ((GPIOA->IDR>>10)&1) - ((GPIOB->IDR>>0)&1)*2;
uint32_t t2 = DWT->CYCCNT;
DEBUG_Print("TICS = %d\r\n",t2-t1);
__enable_irq();
Результаты под IAR и GCC
Спойлер
IAR SPEED 17 тактовКод: Выделить всё
// 12 __disable_irq();
CPSID I
// 13 uint32_t t1 = DWT->CYCCNT;
LDR.N R0,??DataTable1 ;; 0xe0001004
LDR R2,[R0, #+0]
// 14 __NOP();
Nop
// 15 GPIOC->ODR = 3 - ((GPIOA->IDR>>10)&1) - ((GPIOB->IDR>>0)&1)*2;
LDR.N R1,??DataTable1_1 ;; 0x48000010
LDR R3,[R1, #+0]
LDR R4,[R1, #+1024]
UBFX R3,R3,#+10,#+1
LSLS R4,R4,#+1
RSB R3,R3,#+3
AND R4,R4,#0x2
SUBS R3,R3,R4
STR R3,[R1, #+2052]
// 16 uint32_t t2 = DWT->CYCCNT;
LDR R0,[R0, #+0]
// 17 DEBUG_Print("TICS = %d\r\n",t2-t1);
ADR.N R1,?_0
SUBS R2,R0,R2
MOVS R0,#+0
BL SEGGER_RTT_printf
// 18 __enable_irq();GCC -Os 19 тактов
Код: Выделить всё
0x2000026e cpsid i
0x20000270 ldr r0, [pc, #88] ; (0x200002cc <main()+96>)
0x20000272 ldr r2, [r0, #4]
0x20000274 nop
0x20000276 mov.w r3, #1207959552 ; 0x48000000
0x2000027a ldr r1, [pc, #84] ; (0x200002d0 <main()+100>)
0x2000027c ldr r3, [r3, #16]
0x2000027e ldr r1, [r1, #16]
0x20000280 ubfx r3, r3, #10, #1
0x20000284 and.w r1, r1, #1
0x20000288 add.w r3, r3, r1, lsl #1
0x2000028c ldr r1, [pc, #68] ; (0x200002d4 <main()+104>)
0x2000028e rsb r3, r3, #3
0x20000292 str r3, [r1, #20]
0x20000294 ldr r3, [r0, #4]
0x20000296 ldr r1, [pc, #64] ; (0x200002d8 <main()+108>)
0x20000298 subs r2, r3, r2
0x2000029a movs r0, #0
0x2000029c bl 0x200007c2 <SEGGER_RTT_printf(unsigned int, char const*, ...)>
0x200002a0 cpsie i GCC -O3 21 такт
Код: Выделить всё
0x2000027e cpsid i
0x20000280 ldr r4, [pc, #88] ; (0x200002dc <main()+96>)
0x20000282 ldr r2, [r4, #4]
0x20000284 nop
0x20000286 ldr r1, [pc, #88] ; (0x200002e0 <main()+100>)
0x20000288 ldr r5, [pc, #88] ; (0x200002e4 <main()+104>)
0x2000028a mov.w r3, #1207959552 ; 0x48000000
0x2000028e ldr r3, [r3, #16]
0x20000290 ldr r0, [r1, #16]
0x20000292 ldr r1, [pc, #84] ; (0x200002e8 <main()+108>)
0x20000294 and.w r0, r0, #1
0x20000298 ubfx r3, r3, #10, #1
0x2000029c add.w r3, r3, r0, lsl #1
0x200002a0 rsb r3, r3, #3
0x200002a4 str r3, [r5, #20]
0x200002a6 ldr r3, [r4, #4]
0x200002a8 movs r0, #0
0x200002aa subs r2, r3, r2
0x200002ac bl 0x20000b84 <SEGGER_RTT_printf(unsigned int, char const*, ...)>
0x200002b0 cpsie i Затем немного плюсовщины добавил, чтобы компилятор сделал таки то что ты от него хотел.
Код: Выделить всё
__disable_irq();
GPIO::PB_0 pb0;
uint32_t t1 = DWT->CYCCNT;
__NOP();
GPIOC->ODR = 3 - ((GPIOA->IDR>>10)&1) - pb0*2;
uint32_t t2 = DWT->CYCCNT;
DEBUG_Print("TICS = %d\r\n",t2-t1);
__enable_irq();
Код: Выделить всё
UBFX R3,R3,#+10,#+1
RSB R3,R3,#+3
AND R4,R4,#0x1
SUB R3,R3,R4, LSL #+1
Спойлер
IAR SPEED 17 тактовКод: Выделить всё
// 9 __disable_irq();
CPSID I
// 10 uint32_t t1 = DWT->CYCCNT;
LDR.N R0,??DataTable1 ;; 0xe0001004
LDR R2,[R0, #+0]
// 11 __NOP();
Nop
// 12 GPIOC->ODR = 3 - ((GPIOA->IDR>>10)&1) - pb0*2;
LDR.N R1,??DataTable1_1 ;; 0x48000010
LDR R3,[R1, #+0]
LDR R4,[R1, #+1024]
UBFX R3,R3,#+10,#+1
RSB R3,R3,#+3
AND R4,R4,#0x1
SUB R3,R3,R4, LSL #+1
STR R3,[R1, #+2052]
// 13 uint32_t t2 = DWT->CYCCNT;
LDR R0,[R0, #+0]
// 14 DEBUG_Print("TICS = %d\r\n",t2-t1);
ADR.N R1,?_1
SUBS R2,R0,R2
MOVS R0,#+0
BL SEGGER_RTT_printf
// 15 __enable_irq();
GCC -Os 19 тактов
Код: Выделить всё
0x2000026e cpsid i
0x20000270 ldr r0, [pc, #88] ; (0x200002cc <main()+96>)
0x20000272 ldr r2, [r0, #4]
0x20000274 nop
0x20000276 mov.w r3, #1207959552 ; 0x48000000
0x2000027a ldr r1, [pc, #84] ; (0x200002d0 <main()+100>)
0x2000027c ldr r3, [r3, #16]
0x2000027e ldr r1, [r1, #16]
0x20000280 ubfx r3, r3, #10, #1
0x20000284 and.w r1, r1, #1
0x20000288 rsb r3, r3, #3
0x2000028c sub.w r3, r3, r1, lsl #1
0x20000290 ldr r1, [pc, #64] ; (0x200002d4 <main()+104>)
0x20000292 str r3, [r1, #20]
0x20000294 ldr r3, [r0, #4]
0x20000296 ldr r1, [pc, #64] ; (0x200002d8 <main()+108>)
0x20000298 subs r2, r3, r2
0x2000029a movs r0, #0
0x2000029c bl 0x200007c2 <SEGGER_RTT_printf(unsigned int, char const*, ...)>
0x200002a0 cpsie i
GCC -O3 20 тактов
Код: Выделить всё
0x2000027e cpsid i
0x20000280 ldr r4, [pc, #88] ; (0x200002dc <main()+96>)
0x20000282 ldr r2, [r4, #4]
0x20000284 nop
0x20000286 mov.w r3, #1207959552 ; 0x48000000
0x2000028a ldr r1, [pc, #84] ; (0x200002e0 <main()+100>)
0x2000028c ldr r3, [r3, #16]
0x2000028e ldr r0, [r1, #16]
0x20000290 ldr r5, [pc, #80] ; (0x200002e4 <main()+104>)
0x20000292 ldr r1, [pc, #84] ; (0x200002e8 <main()+108>)
0x20000294 ubfx r3, r3, #10, #1
0x20000298 and.w r0, r0, #1
0x2000029c rsb r3, r3, #3
0x200002a0 sub.w r3, r3, r0, lsl #1
0x200002a4 str r3, [r5, #20]
0x200002a6 ldr r3, [r4, #4]
0x200002a8 movs r0, #0
0x200002aa subs r2, r3, r2
0x200002ac bl 0x20000b84 <SEGGER_RTT_printf(unsigned int, char const*, ...)>
0x200002b0 cpsie i
Но мы же любопытные. Полностью на плюсах получаем третий вариант на те же 17 тактов.
Спойлер
Код: Выделить всё
__disable_irq();
using namespace GPIO;
PB_0 pb0;
PA_10 pa10;
GpioC<0xFFFF> port;
uint32_t t1 = DWT->CYCCNT;
__NOP();
port = 3 - pa10 - pb0*2;
uint32_t t2 = DWT->CYCCNT;
DEBUG_Print("TICS = %d\r\n",t2-t1);
__enable_irq();
Код: Выделить всё
// 7 __disable_irq();
CPSID I
// 8 using namespace GPIO;
// 9 PB_0 pb0;
// 10 PA_10 pa10;
// 11 GpioC<0xFFFF> port;
// 12 uint32_t t1 = DWT->CYCCNT;
LDR.N R0,??DataTable1 ;; 0xe0001004
LDR R2,[R0, #+0]
// 13 __NOP();
Nop
// 14 port = 3 - pa10 - pb0*2;
LDR.N R1,??DataTable1_1 ;; 0x48000010
LDR R3,[R1, #+0]
LDR R4,[R1, #+1024]
LSRS R3,R3,#+10
AND R3,R3,#0x1
RSB R3,R3,#+3
AND R4,R4,#0x1
SUB R3,R3,R4, LSL #+1
STR R3,[R1, #+2052]
// 15 uint32_t t2 = DWT->CYCCNT;
LDR R0,[R0, #+0]
// 16 DEBUG_Print("TICS = %d\r\n",t2-t1);
Nop
ADR.N R1,?_3
SUBS R2,R0,R2
MOVS R0,#+0
BL SEGGER_RTT_printf
// 17 __enable_irq();
Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?
Народ, а коль уж тут речь зашла. НА AVR GCC плюсы для серьезных задач использовать практически не возможно, так как TVM они держат не во FLASH, что было бы логично, а в ОЗУ. Ни разу не эффективно, а главное, ОЗУ кончается очень быстро.
А для STM как это решено?
Кстати, вот и еще один пример, зачем может быть нужен ассемблер: в сложных случаях понять, а что же такое намудрил компилятор.
А для STM как это решено?
Кстати, вот и еще один пример, зачем может быть нужен ассемблер: в сложных случаях понять, а что же такое намудрил компилятор.
Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?
[uquote="VladislavS",url="/forum/viewtopic.php?p=3742456#p3742456"]Немного поэкспериментировал с твоим примером. Процессор STM32F303 (CM4F), выполнение кода из SRAM. Скорее всего, из FLASH будут другие цифры по тактам.
Сделал тестовый код (надеюсь я правильно понял твои макросы).[/uquote]Да, именно в такое мои макросы и должны были развернуться. Единственный момент - IAR ругается warning-ом на выражения, в которых встречаются сразу несколько чтений volatile переменных. Поэтому эта строка у меня разбита на 2: сперва "3 - ((GPIOA->IDR>>10)&1)", а потом - остальное.
Ну собственно IAR-овский результат такой же как у меня - 5 команд.
[uquote="VladislavS",url="/forum/viewtopic.php?p=3742456#p3742456"]И получил как раз[/uquote]Да, собственно этого я и ожидал от IAR-а. Как минимально-оптимальный результат.
4 шт. 4-байтовых арифметических команды.
[uquote="VladislavS",url="/forum/viewtopic.php?p=3742456#p3742456"]Только разницы по тактам, как я и предполагал, никакой. Результаты под IAR и GCC[/uquote]IAR-овский результат - 5 команд. Должен быть на 1 такт длиннее. Ну а то что "нет разницы" - так там в результаты попали множество LDR, которые в сумме длиннее. И IAR их поставил меньше. Таким способом с точностью до такта не измерить. Вобщем - GCC здесь оказался лучше. Но даже он не додумался до самого оптимального варианта, который я приводил 3-м по счёту.
Вобщем - компиляторы ещё пока что тупее человека.
Добавлено after 5 minutes 43 seconds:
[uquote="Мурик",url="/forum/viewtopic.php?p=3742299#p3742299"]Так приведите весь код, который нужно компилировать...
Что из себя представляет Pval, PIN_PRND_B и PIN_PRND_F?[/uquote]Посмотрите соседний пост VladislavS - он правильно угадал содержимое макросов. У него как раз и получилось от GCC то, что я ожидал. Правда не самый лучший вариант.
[uquote="Мурик",url="/forum/viewtopic.php?p=3742299#p3742299"]
Добавлено after 4 minutes 50 seconds:
[uquote="protoder",url="/forum/viewtopic.php?p=3742899#p3742899"]Кстати, вот и еще один пример, зачем может быть нужен ассемблер: в сложных случаях понять, а что же такое намудрил компилятор.[/uquote]Совершенно правы! Или "намудрил автор исходника". Я бывает когда ищу баг, гляну на результат компиляции и по нему сразу вижу баг (особенно - если что-то не так с приведением типов, расширением типов, знаками и т.п.).
Сделал тестовый код (надеюсь я правильно понял твои макросы).[/uquote]Да, именно в такое мои макросы и должны были развернуться. Единственный момент - IAR ругается warning-ом на выражения, в которых встречаются сразу несколько чтений volatile переменных. Поэтому эта строка у меня разбита на 2: сперва "3 - ((GPIOA->IDR>>10)&1)", а потом - остальное.
Ну собственно IAR-овский результат такой же как у меня - 5 команд.
[uquote="VladislavS",url="/forum/viewtopic.php?p=3742456#p3742456"]И получил как раз[/uquote]Да, собственно этого я и ожидал от IAR-а. Как минимально-оптимальный результат.
[uquote="VladislavS",url="/forum/viewtopic.php?p=3742456#p3742456"]Только разницы по тактам, как я и предполагал, никакой. Результаты под IAR и GCC[/uquote]IAR-овский результат - 5 команд. Должен быть на 1 такт длиннее. Ну а то что "нет разницы" - так там в результаты попали множество LDR, которые в сумме длиннее. И IAR их поставил меньше. Таким способом с точностью до такта не измерить. Вобщем - GCC здесь оказался лучше. Но даже он не додумался до самого оптимального варианта, который я приводил 3-м по счёту.
Вобщем - компиляторы ещё пока что тупее человека.
Добавлено after 5 minutes 43 seconds:
[uquote="Мурик",url="/forum/viewtopic.php?p=3742299#p3742299"]Так приведите весь код, который нужно компилировать...
Что из себя представляет Pval, PIN_PRND_B и PIN_PRND_F?[/uquote]Посмотрите соседний пост VladislavS - он правильно угадал содержимое макросов. У него как раз и получилось от GCC то, что я ожидал. Правда не самый лучший вариант.
[uquote="Мурик",url="/forum/viewtopic.php?p=3742299#p3742299"]
Потому что данные в __IO регистре, т. е. valatile.[/uquote]Данные, но не указатель на них (адрес этого регистра). А у Вас GCC дважды зачем-то перегрузил этот адрес. Посмотрите на результат IAR (что я приводил) - там указатель на IO-регистры грузится один раз, и потом по нему дважды читаются оба порта (со смещением, так как они находятся по близким адресам).jcxz писал(а):Компилятор у Вас зачем то перегружал повторно указатель, потратив на это лишние команды LDR.
Добавлено after 4 minutes 50 seconds:
[uquote="protoder",url="/forum/viewtopic.php?p=3742899#p3742899"]Кстати, вот и еще один пример, зачем может быть нужен ассемблер: в сложных случаях понять, а что же такое намудрил компилятор.[/uquote]Совершенно правы! Или "намудрил автор исходника". Я бывает когда ищу баг, гляну на результат компиляции и по нему сразу вижу баг (особенно - если что-то не так с приведением типов, расширением типов, знаками и т.п.).
- VladislavS
- Собутыльник Кота
- Сообщения: 2562
- Зарегистрирован: Вт май 01, 2018 19:44:47
Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?
jcxz, смысл моего поста был в том, что я на IAR получил три разных кода, выполняющихся потактово одинаково. Все LDR и STR в нём одинаковы.
GCC там вне зачёта шёл.
Добавлено after 7 minutes 54 seconds:
[uquote="protoder",url="/forum/viewtopic.php?p=3742899#p3742899"]НА AVR GCC плюсы для серьезных задач использовать практически не возможно, так как TVM они держат не во FLASH, что было бы логично, а в ОЗУ.[/uquote]С++ настолько многогранен. Можно же не применять виртуальные методы и эллоцируюшие динамическую память объекты. И без них в языке столько "серьёзности"!
Добавлено after 2 hours 23 minutes 58 seconds:
Кстати, между нами эмбеддерами.
Вот такой код делает то же самое, но выполняется на 2 такта быстрее.
Спойлер
Код: Выделить всё
LDR.N R1,??DataTable1_1 ;; 0x48000010
LDR R3,[R1, #+0]
LDR R4,[R1, #+1024]
UBFX R3,R3,#+10,#+1
LSLS R4,R4,#+1
RSB R3,R3,#+3
AND R4,R4,#0x2
SUBS R3,R3,R4
STR R3,[R1, #+2052]Код: Выделить всё
LDR.N R1,??DataTable1_1 ;; 0x48000010
LDR R3,[R1, #+0]
LDR R4,[R1, #+1024]
UBFX R3,R3,#+10,#+1
RSB R3,R3,#+3
AND R4,R4,#0x1
SUB R3,R3,R4, LSL #+1
STR R3,[R1, #+2052]
Код: Выделить всё
LDR.N R1,??DataTable1_1 ;; 0x48000010
LDR R3,[R1, #+0]
LDR R4,[R1, #+1024]
LSRS R3,R3,#+10
AND R3,R3,#0x1
RSB R3,R3,#+3
AND R4,R4,#0x1
SUB R3,R3,R4, LSL #+1
STR R3,[R1, #+2052]
GCC там вне зачёта шёл.
Добавлено after 7 minutes 54 seconds:
[uquote="protoder",url="/forum/viewtopic.php?p=3742899#p3742899"]НА AVR GCC плюсы для серьезных задач использовать практически не возможно, так как TVM они держат не во FLASH, что было бы логично, а в ОЗУ.[/uquote]С++ настолько многогранен. Можно же не применять виртуальные методы и эллоцируюшие динамическую память объекты. И без них в языке столько "серьёзности"!
Добавлено after 2 hours 23 minutes 58 seconds:
Кстати, между нами эмбеддерами.
Вот такой код делает то же самое, но выполняется на 2 такта быстрее.
Код: Выделить всё
__disable_irq();
uint32_t t1 = DWT->CYCCNT;
__NOP();
GPIOC->ODR = ~(((GPIOA->IDR>>10)&1) | ((GPIOB->IDR>>0)&1)*2) & 3;
uint32_t t2 = DWT->CYCCNT;
DEBUG_Print("TICS = %d\r\n",t2-t1);
__enable_irq();
Код: Выделить всё
//GPIOC->ODR = ~(((GPIOA->IDR>>10)&1) | ((GPIOB->IDR>>0)&1)*2) & 3;
LDR.N R1,??DataTable1_1 ;; 0x48000010
LDR R3,[R1, #+0]
LDR R4,[R1, #+1024]
UBFX R3,R3,#+10,#+1
ORR R3,R3,R4, LSL #+1
MVNS R3,R3
AND R3,R3,#0x3
STR R3,[R1, #+2052]
Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?
>> С++ настолько многогранен. Можно же не применять виртуальные методы и эллоцируюшие динамическую память объекты. И без них в языке столько "серьёзности"!
Можно. Но уже совсем не так интересно. Многое недоступно. Включая стандартную библиотеку классов. Это уже не С++, а в лучшем случае С+ какой-то
Можно. Но уже совсем не так интересно. Многое недоступно. Включая стандартную библиотеку классов. Это уже не С++, а в лучшем случае С+ какой-то
- Z_h_e
- Собутыльник Кота
- Сообщения: 2708
- Зарегистрирован: Сб май 14, 2011 21:16:04
- Откуда: г. Чайковский
Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?
[uquote="protoder",url="/forum/viewtopic.php?p=3741167#p3741167"]Ну да. Кроме каких-то совсем уж экзотических ситуаций. В принципе, на вскидку даже и в голову для примера ни чего не приходит.[/uquote]
В одном из проектов стала у меня гавкать собака по имени IWDG. Редко, непредсказуемо и проморгал на каком этапе редактирования проекта возникла такая беда, т.е. и не знал куда копать. Завел тогда собаку WWDG и обработчик прерывания от нее. В обработчиках прерывания WWDG и исключения HardFault вставил ассемблерную вставку, которая выдергивала контент со стека, а именно указатель стека и, самое главное, программный счетчик . Затем эти данные и еще кое-какие тестовые, я записывал во флеш. С помощью этого нашел где нарукожопил.
Как вставлять ассемблерную вставку в Си (компилятор GCC) читал тут.
В одном из проектов стала у меня гавкать собака по имени IWDG. Редко, непредсказуемо и проморгал на каком этапе редактирования проекта возникла такая беда, т.е. и не знал куда копать. Завел тогда собаку WWDG и обработчик прерывания от нее. В обработчиках прерывания WWDG и исключения HardFault вставил ассемблерную вставку, которая выдергивала контент со стека, а именно указатель стека и, самое главное, программный счетчик . Затем эти данные и еще кое-какие тестовые, я записывал во флеш. С помощью этого нашел где нарукожопил.
Как вставлять ассемблерную вставку в Си (компилятор GCC) читал тут.
- afz
- Опытный кот
- Сообщения: 744
- Зарегистрирован: Сб дек 22, 2012 08:17:42
- Откуда: Караганда, Казахстан
Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?
Кстати, возвращаясь к теме. Никто не сказал главного - того, что для нормальных ассемблеров (про Гнусный я ничего не знаю) нет заголовочных файлов от производителя. Все упражнения на тему ассемблера STM32, ходящие в Сети, либо оперируют "магическими числами", либо используют самодельные наборы описания периферии, в лучшем случае - полученные самодельными конвертерами из сишных файлов .h, а то и просто переделанными из этих .h вручную.
Кто мешает тебе выдумать порох непромокаемый? (К. Прутков, мысль № 133)
-
SII
- Вымогатель припоя
- Сообщения: 635
- Зарегистрирован: Пт янв 30, 2009 14:50:35
- Откуда: Солнечногорск
Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?
[uquote="afz",url="/forum/viewtopic.php?p=3744940#p3744940"]Никто не сказал главного - того, что для нормальных ассемблеров (про Гнусный я ничего не знаю) нет заголовочных файлов от производителя[/uquote]
И что ж здесь главного? При необходимости все эти описания вручную делаются по документации даже, а не по сишным заголовкам. Да, потребует некоторого времени -- но ничего принципиально сложного в этом нет.
И что ж здесь главного? При необходимости все эти описания вручную делаются по документации даже, а не по сишным заголовкам. Да, потребует некоторого времени -- но ничего принципиально сложного в этом нет.
- afz
- Опытный кот
- Сообщения: 744
- Зарегистрирован: Сб дек 22, 2012 08:17:42
- Откуда: Караганда, Казахстан
Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?
Ну да, всего лишь закат Солнца вручную...
Кто мешает тебе выдумать порох непромокаемый? (К. Прутков, мысль № 133)
Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?
[uquote="afz",url="/forum/viewtopic.php?p=3744940#p3744940"]Никто не сказал главного - того, что для нормальных ассемблеров (про Гнусный я ничего не знаю) нет заголовочных файлов от производителя.[/uquote]И что? Я описания периферии всегда сам пишу, по мануалу на МК. Даже если работа с периферией идёт только из си. и никакие "заголовочные файлы от производителя" не пользую.
Добавлено after 2 minutes 11 seconds:
[uquote="afz",url="/forum/viewtopic.php?p=3745121#p3745121"]Ну да, всего лишь закат Солнца вручную...[/uquote]Ну так всегда так: кто-то пишет программу сам (кто это умеет), а кто-то не умеет и за него это делает куб. Не всем дано быть Рафаэлями!
Добавлено after 2 minutes 11 seconds:
[uquote="afz",url="/forum/viewtopic.php?p=3745121#p3745121"]Ну да, всего лишь закат Солнца вручную...[/uquote]Ну так всегда так: кто-то пишет программу сам (кто это умеет), а кто-то не умеет и за него это делает куб. Не всем дано быть Рафаэлями!
Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?
jcxz, то есть ляпую отсебятину насрав на стандарт.
Это не "закатсолнцавручную" это полная ж. и полное пренебрежение окружающих.
Это не "закатсолнцавручную" это полная ж. и полное пренебрежение окружающих.
-
BlackKilkennyCat
- Собутыльник Кота
- Сообщения: 2905
- Зарегистрирован: Ср ноя 29, 2017 06:58:50
Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?
с заголовочными файлами для asm проблем нет.
у MDK учебник входит в комплект.
документация есть тут http://infocenter.arm.com/help/index.js ... JIHGJ.html
и есть скромный сайт http://stm32asm.ru/index.html
у MDK учебник входит в комплект.
документация есть тут http://infocenter.arm.com/help/index.js ... JIHGJ.html
и есть скромный сайт http://stm32asm.ru/index.html
Меня здесь больше нет
Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?
[uquote="dosikus",url="/forum/viewtopic.php?p=3745371#p3745371"]jcxz, то есть ляпую отсебятину насрав на стандарт.[/uquote]Какой такой "стандарт"?
[uquote="dosikus",url="/forum/viewtopic.php?p=3745371#p3745371"]Это не "закатсолнцавручную" это полная ж. и полное пренебрежение окружающих.[/uquote]Какие такие "окружающие"? И какое отношение они имеют к тому что я разрабатываю?
[uquote="dosikus",url="/forum/viewtopic.php?p=3745371#p3745371"]Это не "закатсолнцавручную" это полная ж. и полное пренебрежение окружающих.[/uquote]Какие такие "окружающие"? И какое отношение они имеют к тому что я разрабатываю?
- VladislavS
- Собутыльник Кота
- Сообщения: 2562
- Зарегистрирован: Вт май 01, 2018 19:44:47
Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?
[uquote="jcxz",url="/forum/viewtopic.php?p=3745288#p3745288"]Я описания периферии всегда сам пишу, по мануалу на МК.[/uquote]А зачем? Ведь это имеет смысл, если ты это делаешь лучше производителя. Чем твоё описание лучше? Стоит оно того, учитывая что это ещё и источник ошибок?
У меня есть хотелки по улучшению файлов описания периферии, но оценивая весь этот зоопарк, понимаю что неподъёмно.
У меня есть хотелки по улучшению файлов описания периферии, но оценивая весь этот зоопарк, понимаю что неподъёмно.
