Ассемблер для STM32. Сложно ли, стоит ли пытаться?

Кто любит RISC в жизни, заходим, не стесняемся.
Reflector
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?

Сообщение Reflector »

[uquote="Dimon456",url="/forum/viewtopic.php?p=3952653#p3952653"]покажите ассемблер[/uquote]
У меня есть 100 пиновые мк, при этом write/read() для списков пинов работают с uint32_t, т.е. 32 пина максимум(для всех остальных функций ограничений нет). Добавлять поддержку uint64_t просто нет смысла, а тебе зачем тестить список из 35-х пинов если собираешься использовать максимум 20-ти ногий мк? :)
BlackKilkennyCat
Собутыльник Кота
Сообщения: 2905
Зарегистрирован: Ср ноя 29, 2017 06:58:50

Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?

Сообщение BlackKilkennyCat »

а в 20-ноговом корпусе вполне могут существовать гораздо больше пинов. Вот ща 8-ногий STM8L050 изучаю - одна нога как куча пинов, настроить все правильно, особенно в мультирежимном использовании просто квест какой-то :) А в RM ещё пишут, что если оставшихся пинов нет снаружи, не переживайте, они есть внутри и учитывайте их тоже....
Reflector
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?

Сообщение Reflector »

[uquote="BlackKilkennyCat",url="/forum/viewtopic.php?p=3952748#p3952748"]а в 20-ноговом корпусе вполне могут существовать гораздо больше пинов.[/uquote]
Ремапить пины нужно чтобы по максимуму задействовать всю имеющуюся периферию, для ногодрыжной работы со списками пинов это не нужно, наружу их все равно будет торчать максимум 18.
BlackKilkennyCat
Собутыльник Кота
Сообщения: 2905
Зарегистрирован: Ср ноя 29, 2017 06:58:50

Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?

Сообщение BlackKilkennyCat »

не, там не всегда ремапинг. одновременно живут на одной ноге.
Reflector
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?

Сообщение Reflector »

[uquote="BlackKilkennyCat",url="/forum/viewtopic.php?p=3952771#p3952771"]не, там не всегда ремапинг. одновременно живут на одной ноге.[/uquote]
Без разницы, если на одной ноге физически объединены 4 пина, то можно использовать периферию выведенную на любой из них, или можно соединить выход одной периферии со входом другой и т.д., но наружу 4 бита не выведешь и в списке пинов будет по-прежнему какой-то один пин из имеющихся четырех.
BlackKilkennyCat
Собутыльник Кота
Сообщения: 2905
Зарегистрирован: Ср ноя 29, 2017 06:58:50

Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?

Сообщение BlackKilkennyCat »

Почему ж не выведешь... с программной стороны выведешь все 4 бита наружу, просто физически они выйдут на одной ноге. Я умудрился вывести 0 и 1 одновременно, нечаянно. На ноге примерно половина питания получилась. Полбита :)
Удивительно, но выжило.
Dimon456
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?

Сообщение 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 код, будет поинтересней
И везде будет разный подход вашего С++ компилятора и разный на выходе ассемблер. Это надо учитывать.
BlackKilkennyCat
Собутыльник Кота
Сообщения: 2905
Зарегистрирован: Ср ноя 29, 2017 06:58:50

Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?

Сообщение BlackKilkennyCat »

Dimon456 писал(а):И везде будет разный подход вашего С++ компилятора и разный на выходе ассемблер.
да. поэтому настоящий программист должен использовать Си так:

Код: Выделить всё

int main(void)
{
 #pragma asm
....
#pragma endasm
}
и не оставить компилятору выбора :)
Reflector
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?

Сообщение Reflector »

[uquote="Dimon456",url="/forum/viewtopic.php?p=3952826#p3952826"]И везде будет разный подход вашего С++ компилятора и разный на выходе ассемблер. Это надо учитывать.[/uquote]
В первом случае может быть выполнена дополнительная оптимизация, в трех оставшихся код должен быть одинаковым. Именно код для write(), добавление volatile просто заставит компилятор перечитывать значение переменной "a" из памяти, а не кешировать в регистре. Изменение этой переменной в прерывании вообще ни на что не влияет.
Dimon456
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?

Сообщение Dimon456 »

Reflector писал(а):В первом случае может быть выполнена дополнительная оптимизация, в трех оставшихся код должен быть одинаковым.
Не согласен:
1 код: константное выражение, я бы сделал так, в екселе посчитал или еще как и засунул в три BSRR, если три порта используется. Больше от нее не требуется.
2 код: цикл while говорит компилятору что функция используется многократно, соответственно уже свой асм будет.
3 код: скорее всего похоже на ошибку программиста, модификатор volatile будет отброшен компилятором, так как переменная больше нигде не используется. Скорее всего асм код будет таким же как и в коде 2.
4 код: без модификатора volatile было бы ошибкой и не которые компиляторы вырезали бы переменную (а) из прерывания. Но у меня модификатор volatile, в первую очередь этот модификатор говорит компилятору, что переменная может быть использована в прерывании. Соответственно и асм код другой будет, по чему спросите вы, вы за один так не сможете pins1 = a выполнить, если а = 64 битам. 35 пинов за 1 раз не засунуть в 32 битное число.
VladislavS просто не посчитал циферки, и я бы не зацепился.
Reflector
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?

Сообщение 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 не уберет, что мы и наблюдаем, ведь у меня никакого прерывания нет.
Аватара пользователя
VladislavS
Собутыльник Кота
Сообщения: 2562
Зарегистрирован: Вт май 01, 2018 19:44:47

Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?

Сообщение 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+ пина. Можно пример какой-нибудь?
Dimon456
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?

Сообщение 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 бита, или боишься что СИ положит на лопатки С++?
Аватара пользователя
VladislavS
Собутыльник Кота
Сообщения: 2562
Зарегистрирован: Вт май 01, 2018 19:44:47

Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?

Сообщение VladislavS »

[uquote="Dimon456",url="/forum/viewtopic.php?p=3952976#p3952976"]где ты тут увидел 64 битные вычисления?[/uquote]Да несколько страниц назад. Да и вот тут при 35 битах ничего не поменялось.

[uquote="Dimon456",url="/forum/viewtopic.php?p=3952976#p3952976"]асм покажешь на 64 бита, или боишься что СИ положит на лопатки С++?[/uquote]Закусывать надо! :)
Dimon456
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?

Сообщение Dimon456 »

Свое покажи. Асм где?
Аватара пользователя
VladislavS
Собутыльник Кота
Сообщения: 2562
Зарегистрирован: Вт май 01, 2018 19:44:47

Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?

Сообщение 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
Dimon456
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?

Сообщение Dimon456 »

VladislavS, ладно, признаю свое поражение и склоняюсь перед великим и могучим С++
СпойлерИзображение
Аватара пользователя
VladislavS
Собутыльник Кота
Сообщения: 2562
Зарегистрирован: Вт май 01, 2018 19:44:47

Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?

Сообщение 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
Dimon456
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?

Сообщение 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е, ты мне не помог со скриптом линкера.
Так что ....
Аватара пользователя
VladislavS
Собутыльник Кота
Сообщения: 2562
Зарегистрирован: Вт май 01, 2018 19:44:47

Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?

Сообщение VladislavS »

Это не лечится.

PS: Любым инструментом надо уметь пользоваться. Будь то язык программирования или компилятор.
Ответить

Вернуться в «ARM»