Лучше уж ломанный Keil чем эти недоделыши ...Мурик писал(а):А если нужен не только F0?
STM32 новичку в ARM что к чему
Re: STM32 новичку в ARM что к чему
Re: STM32 новичку в ARM что к чему
Как обычно, одне общие слова. Что бы тут не говорили, EmBitz весьма неплох для полностью бесплатной среды программирования:
Последний раз редактировалось a5021 Вс окт 23, 2016 03:35:36, всего редактировалось 1 раз.
- Andrew Martin
- Вымогатель припоя
- Сообщения: 606
- Зарегистрирован: Вт июн 25, 2013 18:45:07
Re: STM32 новичку в ARM что к чему
По поводу кода.
GCC использует больше LDR, грузит две 32-битные константы из памяти программ, поэтому по размеру кода выигрыша не будет, а будет проигрыш минимум на одну инструкцию. По скорости - 32 такта против 33, если считать с Zero wait state. На высоких тактовых частотах, где wait state <> 0 LDR из флеша может занимать более 2х тактов, и тогда вариант ГЦЦ может даже проиграть.
А вообще нифига этот код не оптимальный. Посмотрите бегло на листинг - там идут два раза подряд загрузки-выгрузки по одним и тем же адресам. Можно убрать два LDR и два STR, итого сэкономим минимум 8 тактов и 8 байт. Это только БЕГЛАЯ прикидка, но и она показывает несостоятельность баек сишников про супер-пупер оптимизаторы
Вручную написанный ассемблерный код всё равно будет лучше.
GCC использует больше LDR, грузит две 32-битные константы из памяти программ, поэтому по размеру кода выигрыша не будет, а будет проигрыш минимум на одну инструкцию. По скорости - 32 такта против 33, если считать с Zero wait state. На высоких тактовых частотах, где wait state <> 0 LDR из флеша может занимать более 2х тактов, и тогда вариант ГЦЦ может даже проиграть.
А вообще нифига этот код не оптимальный. Посмотрите бегло на листинг - там идут два раза подряд загрузки-выгрузки по одним и тем же адресам. Можно убрать два LDR и два STR, итого сэкономим минимум 8 тактов и 8 байт. Это только БЕГЛАЯ прикидка, но и она показывает несостоятельность баек сишников про супер-пупер оптимизаторы
Re: STM32 новичку в ARM что к чему
Я конечно понимаю всю важность религиозных противостояний, но я разве задал слишком тупой вопрос?
Re: STM32 новичку в ARM что к чему
Компилятор делает ровно то, что от него хотят. Он видит, что нужно два раза прочесть из AFR[0](AFR[1]) и сохранить обратно, но также он знает, что AFR объявлен как volatile, потому объединять команды чтение и записи он не имеет права.Andrew Martin писал(а):А вообще нифига этот код не оптимальный. Посмотрите бегло на листинг - там идут два раза подряд загрузки-выгрузки по одним и тем же адресам. Можно убрать два LDR и два STR, итого сэкономим минимум 8 тактов и 8 байт. Это только БЕГЛАЯ прикидка, но и она показывает несостоятельность баек сишников про супер-пупер оптимизаторыВручную написанный ассемблерный код всё равно будет лучше.
Если что, вот мой вариант с gcc для F407, он покороче, можешь попробовать его оптимизировать
Спойлер
Код: Выделить всё
SET_AF(GPIOA, 2, 2);
0x08001272 ldr r6, [pc, #564] ; (0x80014a8 <main()+616>)
0x08001274 ldr r3, [r6, #32]
0x08001276 bic.w r3, r3, #3840 ; 0xf00
0x0800127a orr.w r3, r3, #512 ; 0x200
0x0800127e str r3, [r6, #32]
SET_AF(GPIOA, 4, 4);
0x08001280 ldr r3, [r6, #32]
0x08001282 bic.w r3, r3, #983040 ; 0xf0000
0x08001286 orr.w r3, r3, #262144 ; 0x40000
0x0800128a str r3, [r6, #32]
SET_AF(GPIOA, 9, 1);
0x0800128c ldr r3, [r6, #36] ; 0x24
0x0800128e bic.w r3, r3, #240 ; 0xf0
0x08001292 orr.w r3, r3, #16
0x08001296 str r3, [r6, #36] ; 0x24
SET_AF(GPIOA, 10, 1);
0x08001298 ldr r3, [r6, #36] ; 0x24
0x0800129a bic.w r3, r3, #3840 ; 0xf00
0x0800129e orr.w r3, r3, #256 ; 0x100
0x080012a2 str r3, [r6, #36] ; 0x24
Re: STM32 новичку в ARM что к чему
Reflector писал(а): он покороче, можешь попробовать его оптимизировать![]()
Код: Выделить всё
;;;100 GPIOA->AFR[1] |=(1<<(4*1)) |(1<<(4*2))|(1<<(4*3)) |(1<<(4*4));
000040 6a41 LDR r1,[r0,#0x24]
000042 4a10 LDR r2,|L4.132|
000044 4311 ORRS r1,r1,r2
000046 6241 STR r1,[r0,#0x24]
Re: STM32 новичку в ARM что к чему
Так совпало, что на скриншоте EmBitz-а, что я тут запостил, как раз кусок процедуры, которая оцифровывает по 256 семплов с сохранением в буфере через прямой доступ к памяти.aam писал(а):Я конечно понимаю всю важность религиозных противостояний, но я разве задал слишком тупой вопрос?
А вообще, в снайпетах это подробно разжевано. Я могу кусок своего кода сюда запостить, но у меня немного специфичная задачка, от вашей отличающаяся.
Опять пальцем в небо. По сравнению с оригинальным выражением отсутствует операция логического "И" (сброс битов), от чего код, разумеется, стал короче. GCC выдает почти то же самое, кстати:dosikus писал(а):Код: Выделить всё
;;;100 GPIOA->AFR[1] |=(1<<(4*1)) |(1<<(4*2))|(1<<(4*3)) |(1<<(4*4)); 000040 6a41 LDR r1,[r0,#0x24] 000042 4a10 LDR r2,|L4.132| 000044 4311 ORRS r1,r1,r2 000046 6241 STR r1,[r0,#0x24]
Код: Выделить всё
(268) GPIOA->AFR[1] |=(1<<(4*1)) |(1<<(4*2))|(1<<(4*3)) |(1<<(4*4));
080003E0 ldr r0, [pc, #760] ; (0x80006dc <main+888>)
08000414 ldr r1, [r2, #36] ; 0x24
08000418 orrs r1, r0
0800041A str r1, [r2, #36] ; 0x24- oleg110592
- Друг Кота
- Сообщения: 3832
- Зарегистрирован: Сб сен 10, 2011 17:46:25
Re: STM32 новичку в ARM что к чему
Вполне возможно никто из участников форума не решал подобной задачи, гораздо интересней хвастать у кого длиннее.aam писал(а):Я конечно понимаю всю важность религиозных противостояний...
Может поможет пример из снипетсов "07_DMA_CircularMode", там правда 4 канала в массив пишется.
Еще тут http://tomeko.net/miniscope_v2e/ есть ацп оцифровка в большой буфер через DMA
Re: STM32 новичку в ARM что к чему
Имелась в виду оптимизация с учетом того, что я говорил про volatiledosikus писал(а):Код: Выделить всё
;;;100 GPIOA->AFR[1] |=(1<<(4*1)) |(1<<(4*2))|(1<<(4*3)) |(1<<(4*4)); 000040 6a41 LDR r1,[r0,#0x24] 000042 4a10 LDR r2,|L4.132| 000044 4311 ORRS r1,r1,r2 000046 6241 STR r1,[r0,#0x24]
Код: Выделить всё
GpioD<0xC8B3>(PinMode::AF_PushPull_VeryHighSpeed, 12);
GpioE<0x0780>(PinMode::AF_PushPull_VeryHighSpeed, 12);
Код: Выделить всё
GpioD<0xC8B3>::altFunc(12);
GpioE<0x0780>::altFunc(12);
Спойлер
Код: Выделить всё
0x200008ac ldr r1, [pc, #588]
0x200008ae ldr r2, [pc, #592]
0x200008b0 ldr r3, [r1, #32]
0x200008b2 bic.w r3, r3, #4026531840 ; 0xf0000000
0x200008b6 and.w r3, r3, #4278255360 ; 0xff00ff00
0x200008ba orr.w r3, r3, #3221225472 ; 0xc0000000
0x200008be orr.w r3, r3, #13369548 ; 0xcc00cc
0x200008c2 str r3, [r1, #32]
0x200008c4 ldr r3, [r1, #36] ; 0x24
0x200008c6 bic.w r3, r3, #4278190080 ; 0xff000000
0x200008ca bic.w r3, r3, #61440 ; 0xf000
0x200008ce orr.w r3, r3, #3422552064 ; 0xcc000000
0x200008d2 orr.w r3, r3, #49152 ; 0xc000
0x200008d6 str r3, [r1, #36] ; 0x24
0x200008d8 ldr r3, [r2, #32]
0x200008da bic.w r3, r3, #4026531840 ; 0xf0000000
0x200008de orr.w r3, r3, #3221225472 ; 0xc0000000
0x200008e2 str r3, [r2, #32]
0x200008e4 ldr r3, [r2, #36] ; 0x24
0x200008e6 bic.w r3, r3, #4080 ; 0xff0
0x200008ea bic.w r3, r3, #15
0x200008ee orr.w r3, r3, #3264 ; 0xcc0
0x200008f2 orr.w r3, r3, #12
0x200008f6 str r3, [r2, #36] ; 0x24
Код: Выделить всё
GPIOD->AFR[0] = GPIOD->AFR[0] & ~0xF0FF00FF | (12 << (4 * 0)) | (12 << (4 * 1)) | (12 << (4 * 4)) | (12 << (4 * 5)) | (12 << (4 * 7));
GPIOD->AFR[1] = GPIOD->AFR[1] & ~0xFF00F000 | (12 << (4 * 3)) | (12 << (4 * 6)) | (12 << (4 * 7));
GPIOE->AFR[0] = GPIOE->AFR[0] & ~0xFF000000 | (12 << (4 * 7));
GPIOE->AFR[1] = GPIOE->AFR[1] & ~0x00000FFF | (12 << (4 * 0)) | (12 << (4 * 1)) | (12 << (4 * 2));
Re: STM32 новичку в ARM что к чему
Да я в принципе не тебе писал.Reflector писал(а): Имелась в виду оптимизация с учетом того, что я говорил про volatile![]()
А на счет конфига кучи пинов на разных портах, меня больше прикалывает сие - http://en.radzio.dxp.pl/stm32f429idiscovery/sdram.html
Ну и оттуда же ...
Код: Выделить всё
void gpio_conf(GPIO_TypeDef * GPIO, uint8_t pin, uint8_t mode, uint8_t type, uint8_t speed, uint8_t pullup, uint8_t af)
{
GPIO->MODER = (GPIO->MODER & MASK2BIT(pin)) | (mode << (pin * 2));
GPIO->OTYPER = (GPIO->OTYPER & MASK1BIT(pin)) | (type << pin);
GPIO->OSPEEDR = (GPIO->OSPEEDR & MASK2BIT(pin)) | (speed << (pin * 2));
GPIO->PUPDR = (GPIO->PUPDR & MASK2BIT(pin)) | (pullup << (pin * 2));
if(pin > 7)
{
GPIO->AFR[1] = (GPIO->AFR[1] & AFMASKH(pin)) | (af << ((pin - 8) * 4));
}
else
{
GPIO->AFR[0] = (GPIO->AFR[0] & AFMASKL(pin)) | (af << ((pin) * 4));
}
}Re: STM32 новичку в ARM что к чему
Канэшна не решал. Скрин вон с нерешенной задачей засветил случайно, предложение поделиться кодом от нее же. Впрочем, это уже не первый случай, когда иным участникам кажется офигенной идеей отрицать очевидные вещи, находящегося у них прямо перед глазами.oleg110592 писал(а):Вполне возможно никто из участников форума не решал подобной задачи, гораздо интересней хвастать у кого длиннее.![]()
Подозреваю, что особо рьяные поклонники Кернигана и Ричи опять не увидят здесь никаких волшебных цифр, а одни только самодокументирующиеся операции с битами, но я бы все-таки привел это дело к более читабельному виду. Что-то вроде такого:Reflector писал(а):Эквивалентный ему фрагмент кода на чистых регистрах(оба варианта по 76 байт) выглядит не самым привлекательным образом, а многие еще и маску разворачивают...Код: Выделить всё
GPIOD->AFR[0] = GPIOD->AFR[0] & ~0xF0FF00FF | (12 << (4 * 0)) | (12 << (4 * 1)) | (12 << (4 * 4)) | (12 << (4 * 5)) | (12 << (4 * 7)); GPIOD->AFR[1] = GPIOD->AFR[1] & ~0xFF00F000 | (12 << (4 * 3)) | (12 << (4 * 6)) | (12 << (4 * 7)); GPIOE->AFR[0] = GPIOE->AFR[0] & ~0xFF000000 | (12 << (4 * 7)); GPIOE->AFR[1] = GPIOE->AFR[1] & ~0x00000FFF | (12 << (4 * 0)) | (12 << (4 * 1)) | (12 << (4 * 2));
Спойлер
Код: Выделить всё
#define ASSIGN_AF(PIN, AF) (AF << (4 * (PIN & 7)))
GPIOD->AFR[0] = (GPIOD->AFR[0] & ~0xF0FF00FF) | (
ASSIGN_AF(0, 12) | // PD0: AF12 -- FSMC_D2
ASSIGN_AF(1, 12) | // PD1: AF12 -- FSMC_D3
ASSIGN_AF(4, 12) | // PD4: AF12 -- FSMC_NOE
ASSIGN_AF(5, 12) | // PD5: AF12 -- FSMC_NWE
ASSIGN_AF(7, 12) // PD7: AF12 -- FSMC_NE1
);
GPIOD->AFR[1] = (GPIOD->AFR[1] & ~0xFF00F000) | (
ASSIGN_AF(11, 12) | // PD11: AF12 -- FSMC_A16
ASSIGN_AF(14, 12) | // PD14: AF12 -- FSMC_D0
ASSIGN_AF(15, 12) // PD15: AF12 -- FSMC_D1
);
// и т.п.
#undef ASSIGN_AFЭто их вы обыкновенно пытаетесь кормить откровенной горбухой под видом величайших откровений?dosikus писал(а):Да я в принципе не тебе писал.Есть тут открыватели велосипедов...
Re: STM32 новичку в ARM что к чему
Ага, еще добавить сюда инициализацию остальных 4-х GPIO регистров для двух портов и будет почти то же самое, что у меня, только на два экрана вместо двух строкa5021 писал(а): По сути то же самое, но вспоминать, что там напрограммировалось года полтора назад, будет легче.![]()
Re: STM32 новичку в ARM что к чему
А попробуйте! Может и дурных вопросов будет меньше.a5021 писал(а): Канэшна не решал.
А оно ещё кому-то нужно, кроме вас?Скрин вон с нерешенной задачей засветил случайно, предложение поделиться кодом от нее же.
Да вы америку уже в 1796590006-й раз открыли, а мир от этого и не рухнул. Но вот почему-то это никого не удивляет, ну кроме вас конечно.Впрочем, это уже не первый случай, когда иным участникам кажется офигенной идеей отрицать очевидные вещи, находящегося у них прямо перед глазами.
С каких это пор вас стали посещать такие крамольные мысли?Подозреваю, что особо рьяные поклонники Кернигана и Ричи опять не увидят здесь никаких волшебных цифр, а одни только самодокументирующиеся операции с битами, но я бы все-таки привел это дело к более читабельному виду.
По сути то же самое, но вспоминать, что там напрограммировалось года полтора назад, будет легче.![]()
Это сугубо ваша прерогатива - натягивать сову на глобус, раздувать из мухи слона, не видеть очевидного и т.п. Даже сейчас непонятно, а что вы пытаетесь собственно доказать? Или вам просто "поговорить" от нечего делать?Это их вы обыкновенно пытаетесь кормить откровенной горбухой под видом величайших откровений?
Re: STM32 новичку в ARM что к чему
a5021 , не пора ли назад в свой серпентарий ? Пока своим же ядом не захлебнулся...
Re: STM32 новичку в ARM что к чему
Компактность и наглядность здесь антагонисты. Если минимум печатных знаков являются приоритетной целью, то волшебные цифры -- наше все.Reflector писал(а):Ага, еще добавить сюда инициализацию остальных 4-х GPIO регистров для двух портов и будет почти то же самое, что у меня, только на два экрана вместо двух строк
Да без вас с вашим другом-инсектом я это решу как-нибудь. Не напрягайтесь без нужды.dosikus писал(а):a5021 , не пора ли назад в свой серпентарий ? Пока своим же ядом не захлебнулся...
Re: STM32 новичку в ARM что к чему
Решите что? Вы понимаете, что у вас уже пошёл спор ради спора. Вы потеряли суть и цель ради чего всё это.a5021 писал(а):я это решу как-нибудь. Не напрягайтесь без нужды.
Re: STM32 новичку в ARM что к чему
Ваше-то какое дело?
Re: STM32 новичку в ARM что к чему
Да ты хорошенько присмотрисьa5021 писал(а): Компактность и наглядность здесь антагонисты. Если минимум печатных знаков являются приоритетной целью, то волшебные цифры -- наше все.
Код: Выделить всё
GpioD<0xC8B3>::altFunc(12);
Код: Выделить всё
GpioD<0b1100'1000'1011'0011>::altFunc(12);
Код: Выделить всё
const uint32_t mask = ...; // FSMC D2 D3 NOE NWE NE1 A16 D0 D1
GpioD<mask>::altFunc(12);
Код: Выделить всё
#define ASSIGN_AF(PIN, AF) (AF << (4 * (PIN & 7)))
GPIOD->AFR[0] = (GPIOD->AFR[0] & ~0xF0FF00FF) | (
ASSIGN_AF(0, 12) | // PD0: AF12 -- FSMC_D2
ASSIGN_AF(1, 12) | // PD1: AF12 -- FSMC_D3
ASSIGN_AF(4, 12) | // PD4: AF12 -- FSMC_NOE
ASSIGN_AF(5, 12) | // PD5: AF12 -- FSMC_NWE
ASSIGN_AF(7, 12) // PD7: AF12 -- FSMC_NE1
);
GPIOD->AFR[1] = (GPIOD->AFR[1] & ~0xFF00F000) | (
ASSIGN_AF(11, 12) | // PD11: AF12 -- FSMC_A16
ASSIGN_AF(14, 12) | // PD14: AF12 -- FSMC_D0
ASSIGN_AF(15, 12) // PD15: AF12 -- FSMC_D1
);
Re: STM32 новичку в ARM что к чему
Разница, по большому счету, только в направлении развертывания текста. У вас горизонтальное, у меня вертикальное. Горизонтальное занимает меньше строк, вертикальное более наглядно с точки зрения одна строка -- действие и комментарий все вместе.
Re: STM32 новичку в ARM что к чему
У меня всего две константы в которых теоретически можно ошибиться, у тебя уже есть 4 "магических числа" (0xF0FF00FF и т.д.) только для AFR. Это четверная маска, также понадобится две одиночных, для OTYPER, и две двойных, для трех остальных регистров. Конечно никто не заставляет их высчитывать в уме, можно все это культурно сформировать из всяких GPIO_MODER_MODERxx, но т.к. ног у нас целых 12, то компактной такую запись будет назвать очень трудно и все равно вероятность вписать не ту цифру будет в десятки раз больше, чем для кода из двух строк.a5021 писал(а):Разница, по большому счету, только в направлении развертывания текста. У вас горизонтальное, у меня вертикальное. Горизонтальное занимает меньше строк, вертикальное более наглядно с точки зрения одна строка -- действие и комментарий все вместе.
