Кто любит RISC в жизни, заходим, не стесняемся.
Ответить

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

Вс янв 03, 2021 13:16:50

покажите ассемблер

У меня есть 100 пиновые мк, при этом write/read() для списков пинов работают с uint32_t, т.е. 32 пина максимум(для всех остальных функций ограничений нет). Добавлять поддержку uint64_t просто нет смысла, а тебе зачем тестить список из 35-х пинов если собираешься использовать максимум 20-ти ногий мк? :)

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

Вс янв 03, 2021 13:30:28

а в 20-ноговом корпусе вполне могут существовать гораздо больше пинов. Вот ща 8-ногий STM8L050 изучаю - одна нога как куча пинов, настроить все правильно, особенно в мультирежимном использовании просто квест какой-то :) А в RM ещё пишут, что если оставшихся пинов нет снаружи, не переживайте, они есть внутри и учитывайте их тоже....

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

Вс янв 03, 2021 14:00:56

а в 20-ноговом корпусе вполне могут существовать гораздо больше пинов.

Ремапить пины нужно чтобы по максимуму задействовать всю имеющуюся периферию, для ногодрыжной работы со списками пинов это не нужно, наружу их все равно будет торчать максимум 18.

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

Вс янв 03, 2021 14:05:01

не, там не всегда ремапинг. одновременно живут на одной ноге.

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

Вс янв 03, 2021 14:32:59

не, там не всегда ремапинг. одновременно живут на одной ноге.

Без разницы, если на одной ноге физически объединены 4 пина, то можно использовать периферию выведенную на любой из них, или можно соединить выход одной периферии со входом другой и т.д., но наружу 4 бита не выведешь и в списке пинов будет по-прежнему какой-то один пин из имеющихся четырех.

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

Вс янв 03, 2021 15:13:42

Почему ж не выведешь... с программной стороны выведешь все 4 бита наружу, просто физически они выйдут на одной ноге. Я умудрился вывести 0 и 1 одновременно, нечаянно. На ноге примерно половина питания получилась. Полбита :)
Удивительно, но выжило.

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

Вс янв 03, 2021 15:37:13

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

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

да. поэтому настоящий программист должен использовать Си так:
Код:
int main(void)
{
 #pragma asm
....
#pragma endasm
}

и не оставить компилятору выбора :)

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

Вс янв 03, 2021 16:26:31

И везде будет разный подход вашего С++ компилятора и разный на выходе ассемблер. Это надо учитывать.

В первом случае может быть выполнена дополнительная оптимизация, в трех оставшихся код должен быть одинаковым. Именно код для write(), добавление volatile просто заставит компилятор перечитывать значение переменной "a" из памяти, а не кешировать в регистре. Изменение этой переменной в прерывании вообще ни на что не влияет.

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

Вс янв 03, 2021 17:33:04

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

Не согласен:

Скомпилируй такой код:
Код:
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 просто не посчитал циферки, и я бы не зацепился.
Всё я посчитал. Именно поэтому в твоём дурацком цикле сделал оптимизацию и убрал 64-битные вычисления. PinList на >32 пина тоже как три пальца об асфальт делается.
Код:
using TWidth = std::conditional_t<(Size>32), uint64_t, uint32_t>;
И дальше используешь для всех вычислений TWidth. Но я слабо представляю себе ногодрыжный интерфейс на 32+ пина. Можно пример какой-нибудь?

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

Вс янв 03, 2021 20:43:24

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

где ты тут увидел 64 битные вычисления?
Да несколько страниц назад. Да и вот тут при 35 битах ничего не поменялось.

асм покажешь на 64 бита, или боишься что СИ положит на лопатки С++?
Закусывать надо! :)

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

Вс янв 03, 2021 21:09:35

Свое покажи. Асм где?

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

Вс янв 03, 2021 21:31:59

Подавись. 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

VladislavS, ладно, признаю свое поражение и склоняюсь перед великим и могучим С++
СпойлерИзображение

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

Вс янв 03, 2021 22:34:46

Дарю. А то прямо кровь из глаз.
Код:
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

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

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

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