STM32 новичку в ARM что к чему

Кто любит RISC в жизни, заходим, не стесняемся.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: STM32 новичку в ARM что к чему

Сообщение ARV »

На АРМ можно себе позволить и float... А в моем плейере концептуально 256 эквивалентно 360 градусам, и далее соответственно пересчет. Погрешность есть, но для автомата светоэффектов она роли не играет.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

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

Re: STM32 новичку в ARM что к чему

Сообщение VladislavS »

Где вы там флоат увидели? :)
Аватара пользователя
Мурик
Друг Кота
Сообщения: 3383
Зарегистрирован: Пн окт 11, 2010 19:00:08

Re: STM32 новичку в ARM что к чему

Сообщение Мурик »

Reflector писал(а):Будет быстрее
Даже на МК не аппаратно поддерживающих float?
Проверил, компиль "сильно умный". :))) :)

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

;  h = h * (uint32_t) (65536 * (360.0f / 256) + 0.5f) >> 16;
20000314   ldr   r3, [r7, #4]
20000316   mov.w   r2, #92160   ; 0x16800
2000031A   mul.w   r3, r2, r3
2000031E   lsrs   r3, r3, #16
20000320   str   r3, [r7, #4]
Аватара пользователя
VladislavS
Собутыльник Кота
Сообщения: 2562
Зарегистрирован: Вт май 01, 2018 19:44:47

Re: STM32 новичку в ARM что к чему

Сообщение VladislavS »

Да причём тут компилятор? Вы код то читать умеете? Где вы там float в рантайме увидели???
Аватара пользователя
WiseLord
Друг Кота
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск
Контактная информация:

Re: STM32 новичку в ARM что к чему

Сообщение WiseLord »

А кто, если не компилятор, делает эти вычисления и подставляет в бинарник сразу готовое число 92160?
Reflector
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Re: STM32 новичку в ARM что к чему

Сообщение Reflector »

На самом деле можно даже так:

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

h = uint32_t(h * Fixed<16>(360.0f / 256));

// str r3, [sp, #0]
// movs r3, #180
// lsls r3, r3, #9
// muls r3, r7
// asrs r3, r3, #16
// str r3, [sp, #12]
Аватара пользователя
VladislavS
Собутыльник Кота
Сообщения: 2562
Зарегистрирован: Вт май 01, 2018 19:44:47

Re: STM32 новичку в ARM что к чему

Сообщение VladislavS »

Reflector, прекрати насиловать неокрепшие мозги. Всё гораздо проще

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

h = h*92160 >> 16; 
Аватара пользователя
VladislavS
Собутыльник Кота
Сообщения: 2562
Зарегистрирован: Вт май 01, 2018 19:44:47

Re: STM32 новичку в ARM что к чему

Сообщение VladislavS »

А кто, если не компилятор, делает эти вычисления и подставляет в бинарник сразу готовое число 92160?
Это сделал программист, записавший целочисленную константу в таком виде. У компилятора не было никакого выбора, даже у самого тупого.

И что-то мне подсказывает, что это

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

h = (uint32_t)h*360 >> 8; 
Аватара пользователя
Eddy_Em
Собутыльник Кота
Сообщения: 2516
Зарегистрирован: Пт июл 12, 2019 22:52:01
Контактная информация:

Re: STM32 новичку в ARM что к чему

Сообщение Eddy_Em »

Float константы удобно цепными дробями задавать. На F072 я так и делаю обычно (особенно если нужно построить таблицу для кусочно-линейной аппроксимации показаний термисторов). Завожу вместо одного массива флоатов два массива uint_16t: числитель и знаменатель. Их по заданной точности считаю в октаве (функция rat).
Вот, например: отградуировал NTC в нужном мне диапазоне (8…90℃), потом несложной функцией в октаве аппроксимировал эту кривую полиномом (с погрешностью не хуже 0.05℃), далее автоматом разбил этот диапазон на N узлов (в данном случае получилось 14) так, чтобы кусочно-линейная аппроксимация между узлами давала точность не хуже 0.1℃ (фактически же можно было меньше узлов делать: сами понимаете, что NTC лучше ±2℃ дать не способны, обычно их заявленная точность вообще 1%, т.е. ±3℃ в диапазоне комнатных температур). На каждом интервале температура вычисляется так: T=T₀+k(ADU-ADU₀), T₀ и ADU₀ затабулированы, а вот для k я посчитал числители и знаменатели при помощи rat(k*10). По умолчанию точность 1e-6, но в данном случае можно было бы даже немного уменьшить числа, установив точность 1e-4 (я этого не делал, т.к. все равно все отлично влезло в int16_t).
И все: если нужно посчитать температуру, дихотомией ищем соответствующий интервал и на нем элементарно считаем температуру. Никаких флоатов не нужно. А вот от деления, к сожалению, избавиться невозможно: точность намного хуже будет, если подбирать числитель под знаменатель, равный определенной степени двойки (да и в этом случае вполне возможна ситуация, когда число перед сдвигом вылезет за пределы int32_t).
P.S. Когда калибровал NTC, оказалось, что в моем диапазоне погрешность была всего-то ±0.5%! Кстати, это совпадает с разбросом показаний домашних китайских "термометров", основанных на тех же 10-килоомных термисторах. Они тоже где-то на полтора градуса врут. Зато для терморегулирования этого с лихвой хватает: что я в +45℃ вентилятор включу, что в +47℃ — охлаждаемой цепи от этого хуже не будет.
Linux rules! Windows must die. Здравомыслящий человек добровольно будет пользоваться мастдаем лишь в двух случаях: под дулом автомата или под влиянием анального зонда.
Я на гитхабе, в ЖЖ
Reflector
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Re: STM32 новичку в ARM что к чему

Сообщение Reflector »

И что-то мне подсказывает, что это

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

h = (uint32_t)h*360 >> 8; 

Да, результат одинаковый поскольку младший байт нулевой, но и инструкций получится столько-же, просто 360 компилятор получает сдвигая 180 на 1, а для 92160 он сдвигает 180 на 9 :) Там еще вместо деления на 60 используется умножение на 65536.0f / 60 + 0.5f, в обоих случаях под дробную часть выделено 16 бит, так проще.
Аватара пользователя
VladislavS
Собутыльник Кота
Сообщения: 2562
Зарегистрирован: Вт май 01, 2018 19:44:47

Re: STM32 новичку в ARM что к чему

Сообщение VladislavS »

Cortex-M4

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

h = (uint32_t)h*360/256;
        MOV      R0,#+360
        LDRB     R2,[R1, #+2]
        SMULBB   R2,R0,R2
        LSRS     R2,R2,#+8
        STRB     R2,[R1, #+2]

Cortex-M0+

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

h = (uint32_t)h*360/256;
        LDRB     R1,[R0, #+2]
        MOVS     R2,#+180
        LSLS     R2,R2,#+1
        MULS     R1,R2,R1
        LSRS     R1,R1,#+8
        STRB     R1,[R0, #+2]
Reflector
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Re: STM32 новичку в ARM что к чему

Сообщение Reflector »

а вот для k я посчитал числители и знаменатели при помощи rat(k*10).

Eddy, ну какие числители и знаменатели в 21 веке... Беру у тебя в коде коэффициент 0.028261, умноженный на 10 он получается делением 13 / 46 = 0.282609, что очень близко, но будет тяжелое для M0 деление и коэффициенты приходится рассчитывать самому. В то же время даже мои классы все делают быстрее и автоматически:

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

Fixed<12> k(0.028261f);
rtt.printf<"{}, {}, {}\n">(k.rawValue(), (k*10).toStr(), (float)k);      // 29634, 0.2826, 2.82611847e-2

Тут я задал 12 бит для целой части, соответственно 20 осталось для дробной, а могло быть 18 или 25...
29634 - это (1 << 20) * 0.028261 + 0.5, если умножить это число на 10000 и сдвинуть на 20 бит вправо, то получим 282.
Аватара пользователя
Eddy_Em
Собутыльник Кота
Сообщения: 2516
Зарегистрирован: Пт июл 12, 2019 22:52:01
Контактная информация:

Re: STM32 новичку в ARM что к чему

Сообщение Eddy_Em »

Reflector, хватит уже со своими крестами! Я в эту [censored] лезть не собираюсь!
А вообще, когда я впервые увидел, как абдуринщики флоатами пользуются на 8-битной фигнюшке, так охренел, что даже не знаю… Меня теперь, наверное, даже даблы на cortex-M0 не удивят ☺
Жаль, что там аппаратного деления нет.
Последний раз редактировалось Eddy_Em Вт ноя 10, 2020 12:10:39, всего редактировалось 1 раз.
Linux rules! Windows must die. Здравомыслящий человек добровольно будет пользоваться мастдаем лишь в двух случаях: под дулом автомата или под влиянием анального зонда.
Я на гитхабе, в ЖЖ
Аватара пользователя
VladislavS
Собутыльник Кота
Сообщения: 2562
Зарегистрирован: Вт май 01, 2018 19:44:47

Re: STM32 новичку в ARM что к чему

Сообщение VladislavS »

Reflector выдаёт знания в чистом виде! Вам бы на ус мотать, а вы плюётесь.
Аватара пользователя
Eddy_Em
Собутыльник Кота
Сообщения: 2516
Зарегистрирован: Пт июл 12, 2019 22:52:01
Контактная информация:

Re: STM32 новичку в ARM что к чему

Сообщение Eddy_Em »

VladislavS, у него не знания, а "магия".
Я не собираюсь использовать то, чего не в силах понять.
И про кресты я уже сказал: это — не язык программирования, а какой-то садомазо…
Linux rules! Windows must die. Здравомыслящий человек добровольно будет пользоваться мастдаем лишь в двух случаях: под дулом автомата или под влиянием анального зонда.
Я на гитхабе, в ЖЖ
Reflector
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Re: STM32 новичку в ARM что к чему

Сообщение Reflector »

хватит уже со своими крестами! Я в эту [censored] лезть не собираюсь!

При чем тут кресты... Смотри, запускаю на STM32G0, там нет умножения 32*32->64, потому оно эмулируется:

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

volatile uint32_t val = 10000;
const uint32_t k = (1 << 20) * 0.028261 + 0.5;
uint32_t out = (uint64_t)k * val >> 20; // -> 282

Если числа относительно небольшие, то во многих случаях можно обойтись без приведения к uint64_t. А у тебя будет так:

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

volatile uint32_t val = 10000;
const uint32_t N = 13;
const uint32_t D = 46 * 10;
uint32_t out = val * N / D; // -> 282

Первый код выполняется примерно за 70 тактов, второй - за 100.
Dimon456
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

Re: STM32 новичку в ARM что к чему

Сообщение Dimon456 »

Reflector писал(а):При чем тут кресты...
При том, ушли от понятной формулы

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

 uint8_t value = ((24 * h / 17) / 60) % 6;
не понятно к какой, и что бы что то поменять надо заново пересчитывать, так?
Давайте поменяем и посчитаем:

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

uint8_t value = ((25* h / 18) / 59) % 7;
Reflector
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Re: STM32 новичку в ARM что к чему

Сообщение Reflector »

При том, ушли от понятной формулы

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

 uint8_t value = ((24 * h / 17) / 60) % 6;

Изначально смысл в том, что h нужно умножить на понятные 360/256, а непонятные 24/17 появились в следствии оптимизации для 8-ми биток. Но на ARM это не оптимизация, а ее противоположность, я же напротив код именно ускорил, при этом он также стал менее читаем, точно как и оригинал, что совсем не удивительно. Если просто заменить 24 и 17 на 360 и 256, то будет и понятнее, и быстрее, т.к. вместо деления будет сдвиг.
Аватара пользователя
Ярослав555
Поставщик валерьянки для Кота
Сообщения: 2081
Зарегистрирован: Пт май 31, 2013 17:14:38
Откуда: Украина, Винница

Re: STM32 новичку в ARM что к чему

Сообщение Ярослав555 »

такой вопрос - где-то можно посмотреть как зависит время записи на флеш от питания МК? так получилось что имею почти идентичные платы. и оказалось что на одной из них стирание страницы 128kB уперлось в ватчдог (видимо на грани работало). Увеличив период ватчдога я убрал глюк, но интересно было узнать почему так. МК идентичные, единственная разница что вижу - отстающий имеет на 30мВ ниже питание.
Аватара пользователя
VladislavS
Собутыльник Кота
Сообщения: 2562
Зарегистрирован: Вт май 01, 2018 19:44:47

Re: STM32 новичку в ARM что к чему

Сообщение VladislavS »

К вопросу о том зачем нужны современные компиляторы, языки программирования и их стандарты. Есть у меня в библиотеке функция, которая считает количество установленных в числе бит.

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

constexpr auto countSetBits(uint32_t value)
{
  auto bits = 0;
  while (value)
  {
    value &= value - 1;
    bits++;
  }
  return bits;
}
Попробовал как она работает на С (убрав синтаксис С++, естественно).
СпойлерИзображение
c18_popcount.png
(64.45 КБ) 144 скачивания
А вот так она у меня в библиотеке на С++ работает. Вычисляется на этапе компиляции, если аргумент позволяет. А он, как и в прошлом примере на С, позволяет.
СпойлерИзображение
c++17_popcount.png
(55.5 КБ) 141 скачивание
Господа из комитета по стандартизации посмотрели на всё это безобразие и сказали: "Классный у тебя алгоритм, давай его в стандарт С++20 введём. А ты ещё что-нибудь полезное программируй".
СпойлерИзображение
c++20_popcount.png
(40.45 КБ) 135 скачиваний
Ответить

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