Страница 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: Любым инструментом надо уметь пользоваться. Будь то язык программирования или компилятор.