Страница 14 из 15
Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?
Добавлено: Вс янв 03, 2021 13:16:50
Reflector
[uquote="Dimon456",url="/forum/viewtopic.php?p=3952653#p3952653"]покажите ассемблер[/uquote]
У меня есть 100 пиновые мк, при этом write/read() для списков пинов работают с uint32_t, т.е. 32 пина максимум(для всех остальных функций ограничений нет). Добавлять поддержку uint64_t просто нет смысла, а тебе зачем тестить список из 35-х пинов если собираешься использовать максимум 20-ти ногий мк?

Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?
Добавлено: Вс янв 03, 2021 13:30:28
BlackKilkennyCat
а в 20-ноговом корпусе вполне могут существовать гораздо больше пинов. Вот ща 8-ногий STM8L050 изучаю - одна нога как куча пинов, настроить все правильно, особенно в мультирежимном использовании просто квест какой-то

А в RM ещё пишут, что если оставшихся пинов нет снаружи, не переживайте, они есть внутри и учитывайте их тоже....
Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?
Добавлено: Вс янв 03, 2021 14:00:56
Reflector
[uquote="BlackKilkennyCat",url="/forum/viewtopic.php?p=3952748#p3952748"]а в 20-ноговом корпусе вполне могут существовать гораздо больше пинов.[/uquote]
Ремапить пины нужно чтобы по максимуму задействовать всю имеющуюся периферию, для ногодрыжной работы со списками пинов это не нужно, наружу их все равно будет торчать максимум 18.
Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?
Добавлено: Вс янв 03, 2021 14:05:01
BlackKilkennyCat
не, там не всегда ремапинг. одновременно живут на одной ноге.
Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?
Добавлено: Вс янв 03, 2021 14:32:59
Reflector
[uquote="BlackKilkennyCat",url="/forum/viewtopic.php?p=3952771#p3952771"]не, там не всегда ремапинг. одновременно живут на одной ноге.[/uquote]
Без разницы, если на одной ноге физически объединены 4 пина, то можно использовать периферию выведенную на любой из них, или можно соединить выход одной периферии со входом другой и т.д., но наружу 4 бита не выведешь и в списке пинов будет по-прежнему какой-то один пин из имеющихся четырех.
Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?
Добавлено: Вс янв 03, 2021 15:13:42
BlackKilkennyCat
Почему ж не выведешь... с программной стороны выведешь все 4 бита наружу, просто физически они выйдут на одной ноге. Я умудрился вывести 0 и 1 одновременно, нечаянно. На ноге примерно половина питания получилась. Полбита

Удивительно, но выжило.
Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?
Добавлено: Вс янв 03, 2021 15:37:13
Dimon456
Reflector писал(а):а тебе зачем тестить список из 35-х пинов
Прежде чем писать вот это
VladislavS писал(а):Код: Выделить всё
port_write (pins, sizeof(pins)/sizeof(port_pin), 0b00100101101001001000001010010100100);
сначала надо было подумать.
А раз написал, будь добр отвечай.
А так, получается следующее:
Спойлер
Код: Выделить всё
PinList<... напишите что нибудь в разноброс 35 пинов> pins1;
int main(void)
{
pins1 = 0b00100101101001001000001010010100100;
while (1)
{
}
}
это 1 код будетСпойлер
Код: Выделить всё
PinList<... напишите что нибудь в разноброс 35 пинов> pins1;
int main(void)
{ static auto a = 0b00100101101001001000001010010100100;
while (1)
{
pins1 = a++;
}
}
Это 2 кодСпойлер
Код: Выделить всё
PinList<... напишите что нибудь в разноброс 35 пинов> pins1;
volatile auto a = 0b00100101101001001000001010010100100;
int main(void)
{
while (1)
{
pins1 = a++;
}
}
Это 3 кодСпойлер
Код: Выделить всё
PinList<... напишите что нибудь в разноброс 35 пинов> pins1;
volatile auto a = 0b00100101101001001000001010010100100;
int main(void)
{
while (1)
{
pins1 = a;
}
}
void ..._IRQHandler(void)
{
a++;
}
А вот этот 4 код, будет поинтереснейИ везде будет разный подход вашего С++ компилятора и разный на выходе ассемблер. Это надо учитывать.
Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?
Добавлено: Вс янв 03, 2021 15:54:06
BlackKilkennyCat
Dimon456 писал(а):И везде будет разный подход вашего С++ компилятора и разный на выходе ассемблер.
да. поэтому настоящий программист должен использовать Си так:
Код: Выделить всё
int main(void)
{
#pragma asm
....
#pragma endasm
}
и не оставить компилятору выбора

Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?
Добавлено: Вс янв 03, 2021 16:26:31
Reflector
[uquote="Dimon456",url="/forum/viewtopic.php?p=3952826#p3952826"]И везде будет разный подход вашего С++ компилятора и разный на выходе ассемблер. Это надо учитывать.[/uquote]
В первом случае может быть выполнена дополнительная оптимизация, в трех оставшихся код должен быть одинаковым. Именно код для write(), добавление volatile просто заставит компилятор перечитывать значение переменной "a" из памяти, а не кешировать в регистре. Изменение этой переменной в прерывании вообще ни на что не влияет.
Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?
Добавлено: Вс янв 03, 2021 17:33:04
Dimon456
Reflector писал(а):В первом случае может быть выполнена дополнительная оптимизация, в трех оставшихся код должен быть одинаковым.
Не согласен:
1 код: константное выражение, я бы сделал так, в екселе посчитал или еще как и засунул в три BSRR, если три порта используется. Больше от нее не требуется.
2 код: цикл while говорит компилятору что функция используется многократно, соответственно уже свой асм будет.
3 код: скорее всего похоже на ошибку программиста, модификатор volatile будет отброшен компилятором, так как переменная больше нигде не используется. Скорее всего асм код будет таким же как и в коде 2.
4 код: без модификатора volatile было бы ошибкой и не которые компиляторы вырезали бы переменную (а) из прерывания. Но у меня модификатор volatile, в первую очередь этот модификатор говорит компилятору, что переменная может быть использована в прерывании. Соответственно и асм код другой будет, по чему спросите вы, вы за один так не сможете pins1 = a выполнить, если а = 64 битам. 35 пинов за 1 раз не засунуть в 32 битное число.
VladislavS просто не посчитал циферки, и я бы не зацепился.
Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?
Добавлено: Вс янв 03, 2021 18:00:20
Reflector
[uquote="Dimon456",url="/forum/viewtopic.php?p=3952865#p3952865"]Не согласен:[/uquote]
Скомпилируй такой код:
Код: Выделить всё
int val = 10;
while(true) { GPIOB->ODR = val; }
// 0x24001702 37 4A ldr r2, [pc, #220]
// 0x24001704 0D 23 movs r3, #10
// 0x24001706 53 61 str r3, [r2, #20]
// 0x24001708 FD E7 b.n 0x24001706
Тут 10 загрузится регистр и в цикле будет запись в ODR из регистра.
Код: Выделить всё
volatile int val = 10;
while(true) { GPIOB->ODR = val; }
// 0x24001706 37 4A ldr r2, [pc, #220]
// 0x24001708 02 94 str r4, [sp, #8]
// 0x2400170a 02 9B ldr r3, [sp, #8]
// 0x2400170c 53 61 str r3, [r2, #20]
// 0x2400170e FC E7 b.n 0x2400170a
А здесь загрузка в регистр должна выполняться на каждой итерации, вдруг где-то в прерывании данная переменная перезаписывается. От того действительно ли она перезаписывается будет зависеть значение переменной, на генерацию кода это никак не влияет. Естественно если ничего в прерывании не изменяется, то компилятор это ошибкой программиста не посчитает и volatile не уберет, что мы и наблюдаем, ведь у меня никакого прерывания нет.
Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?
Добавлено: Вс янв 03, 2021 20:21:05
VladislavS
[uquote="Dimon456",url="/forum/viewtopic.php?p=3952865#p3952865"]
VladislavS просто не посчитал циферки, и я бы не зацепился.[/uquote]Всё я посчитал. Именно поэтому в твоём дурацком цикле сделал оптимизацию и убрал 64-битные вычисления. PinList на >32 пина тоже как три пальца об асфальт делается.
Код: Выделить всё
using TWidth = std::conditional_t<(Size>32), uint64_t, uint32_t>;
И дальше используешь для всех вычислений TWidth. Но я слабо представляю себе ногодрыжный интерфейс на 32+ пина. Можно пример какой-нибудь?
Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?
Добавлено: Вс янв 03, 2021 20:43:24
Dimon456
VladislavS писал(а): сделал оптимизацию и убрал 64-битные вычисления.
где ты тут увидел 64 битные вычисления?
Спойлер
Код: Выделить всё
#define k_bit uint32_t//uint64_t-64пина uint32_t-32пина uint16_t-16пин uint8_t-8пин
void port_write (volatile const port_pin *p, uint8_t a, k_bit data)
{ k_bit s=1;
for(uint8_t i=0; i<a; i++, s<<=1){
if (data & s)
((GPIO_TypeDef *) p->port)->BSRR = p->or;
else
((GPIO_TypeDef *) p->port)->BSRR = p->and;
p++;
}
}
VladislavS писал(а):Можно пример какой-нибудь?
асм покажешь на 64 бита, или боишься что СИ положит на лопатки С++?
Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?
Добавлено: Вс янв 03, 2021 21:06:26
VladislavS
[uquote="Dimon456",url="/forum/viewtopic.php?p=3952976#p3952976"]где ты тут увидел 64 битные вычисления?[/uquote]
Да несколько страниц назад. Да и
вот тут при 35 битах ничего не поменялось.
[uquote="Dimon456",url="/forum/viewtopic.php?p=3952976#p3952976"]асм покажешь на 64 бита, или боишься что СИ положит на лопатки С++?[/uquote]Закусывать надо!

Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?
Добавлено: Вс янв 03, 2021 21:09:35
Dimon456
Свое покажи. Асм где?
Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?
Добавлено: Вс янв 03, 2021 21:31:59
VladislavS
Подавись. 48 ног.
Спойлер
Код: Выделить всё
//volatile uint64_t x;
x:
DS8 8
//int main()
//{
main:
// using TPL = PinList<GpioB<0xFFFF>,GpioC<0xFFFF>,GpioD<0xFFFF>>;
LDR.N R2,??main_0 ;; 0x48000414
LDR.N R3,??main_0+0x4
// for(;;) TPL::write(x++);
??main_1:
LDRD R0,R1,[R3, #+0]
ADDS R4,R0,#+1
SBC R5,R1,#-1
STRD R4,R5,[R3, #+0]
UXTH R6,R1
STR R6,[R2, #+0]
LSRS R7,R0,#+16
STR R7,[R2, #+1024]
UXTH R0,R0
STR R0,[R2, #+2048]
B.N ??main_1
DATA
??main_0:
DATA32
DC32 0x48000414
DC32 x
Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?
Добавлено: Вс янв 03, 2021 22:05:42
Dimon456
VladislavS, ладно, признаю свое поражение и склоняюсь перед великим и могучим С++
Спойлер

Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?
Добавлено: Вс янв 03, 2021 22:34:46
VladislavS
Дарю. А то прямо кровь из глаз.
Код: Выделить всё
volatile uint64_t x;
int main()
{
for(;;)
{
uint64_t tmp = x++;
GPIOA->ODR = tmp>>48;
GPIOB->ODR = tmp>>32;
GPIOC->ODR = (uint16_t)(tmp>>16);
GPIOD->ODR = tmp;
}
}
Спойлер
Код: Выделить всё
//volatile uint64_t x;
x:
DS8 8
//int main()
//{
main:
LDR.N R6,??main_0 ;; 0x48000014
LDR.N R7,??main_0+0x4
//for(;;)
//{
// uint64_t tmp=x++;
??main_1:
LDRD R2,R3,[R5, #+0]
ADDS R6,R2,#+1
SBC R7,R3,#-1
STRD R6,R7,[R5, #+0]
// GPIOA->ODR = tmp>>48;
LSRS R0,R3,#+16
STR R0,[R4, #+0]
// GPIOB->ODR = tmp>>32;
STR R3,[R4, #+1024]
// GPIOC->ODR = (uint16_t)(tmp>>16);
LSRS R0,R2,#+16
STR R0,[R4, #+2048]
// GPIOD->ODR = tmp;
STR R2,[R4, #+3072]
B.N ??main_1
Nop
DATA
??main_0:
DATA32
DC32 0x48000014
DC32 x
Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?
Добавлено: Вс янв 03, 2021 22:50:12
Dimon456
VladislavS писал(а):Дарю. А то прямо кровь из глаз.
Да не ужели.
Твой код
Спойлер
Код: Выделить всё
volatile uint64_t x;
int main(void)
{
for(;;) {
uint64_t tmp=x++;
GPIOA->ODR = tmp>>48;
GPIOB->ODR = tmp>>32;
GPIOC->ODR = tmp>>16;
GPIOD->ODR = tmp;
}
}
Program Size:
text data bss dec hex filename
628 0 1040 1668 684 port_103.elf
Мой код
Спойлер
Код: Выделить всё
union BytByte {
struct {
uint16_t data[4];
} bit;
volatile uint64_t byte;
}__attribute__((aligned(4)));
union BytByte myBByte;
int main(void)
{
for(;;) {
myBByte.byte++;
GPIOA->ODR = myBByte.bit.data[0];
GPIOB->ODR = myBByte.bit.data[1];
GPIOC->ODR = myBByte.bit.data[2];
GPIOD->ODR = myBByte.bit.data[3];
}
}
Program Size:
text data bss dec hex filename
612 0 1032 1644 66c port_103.elf
Асм показывать не надо?
Могу еще на указателях, но те же самые 612 байт выдает.
Я не спорю что IAR делает эффективный код, но как бы мне не удалось собрать тот проект на IARе, ты мне не помог со скриптом линкера.
Так что ....
Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?
Добавлено: Вс янв 03, 2021 22:57:20
VladislavS
Это не лечится.
PS: Любым инструментом надо уметь пользоваться. Будь то язык программирования или компилятор.