Флоаты в STM32F303

Кто любит RISC в жизни, заходим, не стесняемся.
jcxz
Мудрый кот
Сообщения: 1717
Зарегистрирован: Вт авг 15, 2017 10:51:13

Re: Флоаты в STM32F303

Сообщение jcxz »

[uquote="VladislavS",url="/forum/viewtopic.php?p=4180802#p4180802"]Но было бы достаточно посмотреть в стеке данные после вот этой пары команд

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

 0xED94 0x0B02      VLDR     D0,[R4, #+8][/uquote]В стеке данные нормальные. Я это сразу проверил (поэтому там присутствует m[8] и memset()). Кроме того - если параметр один (типа double), то он вообще через регистры передаётся, а не через стек. В примере два сделал для того, чтобы поверить оба вида передачи.

[uquote="VladislavS",url="/forum/viewtopic.php?p=4180802#p4180802"]Я вот стек руками не двигаю от слов совсем никогда.[/uquote]Я тоже не двигаю. Но если размер стека для задачи указать (случайно) не кратный 8, то дальше он везде пойдёт невыровненный.

[quote="Eddy_Em"]Даже с оптимизацией -O3 он пишет именно так вместо   bic.w   r2, r2, 0xc3c00000[/quote]Затем, что иначе ему пришлось бы добавлять команду LDR. А это дороже и по размеру и по тактам.
Компилятор знает систему команд CPU. В отличие от вас.   :dont_know:
Реклама
Аватара пользователя
VladislavS
Собутыльник Кота
Сообщения: 2562
Зарегистрирован: Вт май 01, 2018 19:44:47

Re: Флоаты в STM32F303

Сообщение VladislavS »

[uquote="Eddy_Em",url="/forum/viewtopic.php?p=4180951#p4180951"]Что-то gcc дурью мается.[/uquote]Ох и на скользкую дорожку ты встал. С твоей категоричностью смотреть листинги компиляторов вредно для здоровья :) Возможно, тебе IAR больше подойдёт, он обычно более прямолинеен.

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

GPIOA->MODER = (GPIOA->MODER & ~(GPIO_MODER_MODE15_Msk | GPIO_MODER_MODE11_Msk | GPIO_MODER_MODE12_Msk));
        
        MOV      R1,#+1207959552  ; GPIOA.MODER
        LDR.N    R0,??DataTable0  ; 0x3C3F'FFFF
        LDR      R2,[R1, #+0]   
        ANDS     R2,R0,R2       
        STR      R2,[R1, #+0]

??DataTable0:
        DC32     0x3c3fffff 
Реклама
Аватара пользователя
Eddy_Em
Собутыльник Кота
Сообщения: 2516
Зарегистрирован: Пт июл 12, 2019 22:52:01
Контактная информация:

Re: Флоаты в STM32F303

Сообщение Eddy_Em »

Да черт с ним. Просто мне непонятно, зачем gcc разбивает то, что можно в один присест сделать, на две операции!
Зато вот это:

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

TRUE_INLINE uint32_t AFRf(uint8_t afr, uint8_t pin){
    if(pin > 7) pin -= 8;
    return (afr << (pin * 4));
}
Оптимизирует до константы. Жаль, нельзя как в С++ проверку диапазона сделать на стадии препроцессора. Хотя, для F303 особо и не проверишь: и AFR, и пины с номерами от 0 до 15…
Linux rules! Windows must die. Здравомыслящий человек добровольно будет пользоваться мастдаем лишь в двух случаях: под дулом автомата или под влиянием анального зонда.
Я на гитхабе, в ЖЖ
Аватара пользователя
VladislavS
Собутыльник Кота
Сообщения: 2562
Зарегистрирован: Вт май 01, 2018 19:44:47

Re: Флоаты в STM32F303

Сообщение VladislavS »

Загружать длинные константы в регистры дорого. Я же тебе показывал вчера на разрешении домтупа к FPU.
Реклама
Эиком - электронные компоненты и радиодетали
Reflector
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Re: Флоаты в STM32F303

Сообщение Reflector »

[uquote="Eddy_Em",url="/forum/viewtopic.php?p=4181102#p4181102"]Просто мне непонятно, зачем gcc разбивает то, что можно в один присест сделать, на две операции![/uquote]
Сейчас у тебя две 4-х байтных инструкции с встроенными константами, выполняемые за 2 такта суммарно. Можно использовать AND с парой регистров, но сначала во второй придется загрузить 32-х битную константу, это можно сделать загружая половинки регистра при помощи тех же двух 4-х байтных инструкций, или читая в регистр из флеша, а это 2-х байтная LDR плюс 4 байта где-то во флеше, чтение из которого не такое и быстрое.
Реклама
Аватара пользователя
Eddy_Em
Собутыльник Кота
Сообщения: 2516
Зарегистрирован: Пт июл 12, 2019 22:52:01
Контактная информация:

Re: Флоаты в STM32F303

Сообщение Eddy_Em »

[uquote="VladislavS",url="/forum/viewtopic.php?p=4181108#p4181108"]Загружать длинные константы в регистры дорого.[/uquote]
Ну так ладно бы разбили на 2 16-битные операции. Но нет, там ведь 32-битные!!! Так чего ж здесь дорогого?
Linux rules! Windows must die. Здравомыслящий человек добровольно будет пользоваться мастдаем лишь в двух случаях: под дулом автомата или под влиянием анального зонда.
Я на гитхабе, в ЖЖ
Реклама
Аватара пользователя
VladislavS
Собутыльник Кота
Сообщения: 2562
Зарегистрирован: Вт май 01, 2018 19:44:47

Re: Флоаты в STM32F303

Сообщение VladislavS »

Можно я его укушу? :) Считай
GCC

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

0x200007c2 4F F0 90 45          mov.w r5, #1207959552	; 0x48000000 
0x200007c6 2B 68                ldr r3, [r5, #0] 
0x200007c8 23 F0 43 43          bic.w r3, r3, #3271557120	; 0xc3000000 
0x200007cc 23 F4 40 03          bic.w r3, r3, #12582912	; 0xc00000 
0x200007d0 2B 60                str r3, [r5, #0] 
IAR

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

  0x2000'1466: 0xf04f 0x4490  MOV.W     R4, #1207959552         ; 0x4800'0000
  0x2000'146a: 0x4827         LDR.N     R0, ??DataTable3        ; 0x3c3f'ffff
  0x2000'146c: 0x6821         LDR       R1, [R4]
  0x2000'146e: 0x4001         ANDS      R1, R1, R0
  0x2000'1470: 0x6021         STR       R1, [R4]

??DataTable3:
  0x2000'1508: 0x3c3f'ffff    DC32      0x3c3f'ffff
Keil

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

0x20001FA2 F04F4090  MOV           r0,#0x48000000
0x20001FA6 6801      LDR           r1,[r0,#0x00]
0x20001FA8 F64F72FF  MOVW          r2,#0xFFFF
0x20001FAC F6C3423F  MOVT          r2,#0x3C3F
0x20001FB0 4011      ANDS          r1,r1,r2
0x20001FB2 6001      STR           r1,[r0,#0x00]
Аватара пользователя
Eddy_Em
Собутыльник Кота
Сообщения: 2516
Зарегистрирован: Пт июл 12, 2019 22:52:01
Контактная информация:

Re: Флоаты в STM32F303

Сообщение Eddy_Em »

VladislavS, еще раз: какого хрена gcc сразу не делает bic.w r3, r3, 0xc3c00000 ???
Или ты считаешь, что это - нормально? Какая ему, нафиг, разница: забульбенить константу 0xc3000000, а потом 0xc00000, или же сразу готовую?

Ну маразм же!!!!!1111
Linux rules! Windows must die. Здравомыслящий человек добровольно будет пользоваться мастдаем лишь в двух случаях: под дулом автомата или под влиянием анального зонда.
Я на гитхабе, в ЖЖ
Аватара пользователя
VladislavS
Собутыльник Кота
Сообщения: 2562
Зарегистрирован: Вт май 01, 2018 19:44:47

Re: Флоаты в STM32F303

Сообщение VladislavS »

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

Re: Флоаты в STM32F303

Сообщение Eddy_Em »

Ух, епта! ОК, спасибо. Теперь понятно. Я-то думал, что пофиг, какая константа - абы 32 бита… А тут, оказывается, нужно, чтобы только 8 бит разными были…
Linux rules! Windows must die. Здравомыслящий человек добровольно будет пользоваться мастдаем лишь в двух случаях: под дулом автомата или под влиянием анального зонда.
Я на гитхабе, в ЖЖ
kote52
Встал на лапы
Сообщения: 120
Зарегистрирован: Пт мар 19, 2021 08:58:45

Re: Флоаты в STM32F303

Сообщение kote52 »

Вот такой код, выполняется за 5.11mS с вроде бы как включенными FPU. т.к только начинаю изучать stm32 не знаю как оценить результат. Прошу подсказать по использованию FPU и настроек.
Библиотека <math.h>,
--specs=nano.specs -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -Wl,--start-group -lc -lm -Wl,--end-group
в int main() вызываю вначале и только потом инициализация пртов, ацп дма таймеров цап ит.п.:

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

 void SystemInit(void) 
{
/* FPU settings --------------------------------------------------------------*/
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
  SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2));  /* set CP10 and CP11 Full Access */
#endif
}
прочитал всю эту тему не понял где находится reset_handler и где по этому поводу инфы найти.
Сам код:

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

			GPIOC->BSRR = GPIO_BSRR_BS_14;
			for (uint16_t i = 0; i < ADC_BUFFER_SIZE; i++) //#define ADC_BUFFER_SIZE 512U
			{	uint16_t j = i / 2;
				float step = (float)j / SAMPLES_NO; // SAMPLES_NO (ADC_BUFFER_SIZE/2)	 
				if (i % 2 == 0) //четность массива
				{
					BufInArray[j] = Buffer_ADC[i];
					Re += (float)BufInArray[j] * cosf(TWOPI_F * step);
					Im += (float)BufInArray[j] * sinf(TWOPI_F * step);
				}
				else
				{
					BufInArray_2[j] = Buffer_ADC[i];
					Re_2 += (float)BufInArray_2[j] * cosf(TWOPI_F * step);
					Im_2 += (float)BufInArray_2[j] * sinf(TWOPI_F * step);
				}
			}
			
			Angle = atan2f(Im, Re); 
			Angle = Angle * RAD; // RAD=(180/ПИ)
			Angle_2 = atan2f(Im_2, Re_2);
			Angle_2 = Angle_2 * RAD;
			Re = 0; Re_2 = 0; Im = 0; Im_2 = 0;
			GPIOC->BSRR = GPIO_BSRR_BR_14;
Аватара пользователя
VladislavS
Собутыльник Кота
Сообщения: 2562
Зарегистрирован: Вт май 01, 2018 19:44:47

Re: Флоаты в STM32F303

Сообщение VladislavS »

kote52, первым делом надо научиться смотреть листинг, либо в режиме отладки пошагово смотреть.

reset_handler в стартапе.
kote52
Встал на лапы
Сообщения: 120
Зарегистрирован: Пт мар 19, 2021 08:58:45

Re: Флоаты в STM32F303

Сообщение kote52 »

[uquote="VladislavS",url="/forum/viewtopic.php?p=4545801#p4545801"]kote52, reset_handler в стартапе.[/uquote]
Это предположу что найду в папке Startup>startup_stm32f303cctx.s
jcxz
Мудрый кот
Сообщения: 1717
Зарегистрирован: Вт авг 15, 2017 10:51:13

Re: Флоаты в STM32F303

Сообщение jcxz »

[uquote="kote52",url="/forum/viewtopic.php?p=4545722#p4545722"]Вот такой код, выполняется за 5.11mS с вроде бы как включенными FPU. т.к только начинаю изучать stm32 не знаю как оценить результат. Прошу подсказать по использованию FPU и настроек.[/uquote]Наличие использования FPU в коде определяется одним взглядом в файлы листингов. Включение генерации листингов (при компиляции) - ищите где включается в вашем компиляторе.

[uquote="kote52",url="/forum/viewtopic.php?p=4545722#p4545722"]

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

			for (uint16_t i = 0; i < ADC_BUFFER_SIZE; i++) //#define ADC_BUFFER_SIZE 512U
			{	uint16_t j = i / 2;
...
[/uquote]Совет: Рабочие целочисленные переменные внутри функций следует делать типа int или unsigned int (т.е. - равными основной разрядности процессора). Не менее. Чтобы понять "почему", опять-же - изучайте листинги.

Добавлено after 7 minutes 8 seconds:
[uquote="kote52",url="/forum/viewtopic.php?p=4545722#p4545722"]...
{
BufInArray[j] = Buffer_ADC;
Re += (float)BufInArray[j] * cosf(TWOPI_F * step);
Im += (float)BufInArray[j] * sinf(TWOPI_F * step);
}
else
{
BufInArray_2[j] = Buffer_ADC;
Re_2 += (float)BufInArray_2[j] * cosf(TWOPI_F * step);
Im_2 += (float)BufInArray_2[j] * sinf(TWOPI_F * step);
}
}
...[/code][/uquote]Зачем дважды одно и то же вычисляете?
Вам за размер исходника платят? 8)
kote52
Встал на лапы
Сообщения: 120
Зарегистрирован: Пт мар 19, 2021 08:58:45

Re: Флоаты в STM32F303

Сообщение kote52 »

[uquote="jcxz",url="/forum/viewtopic.php?p=4546335#p4546335"]Наличие использования FPU в коде определяется одним взглядом в файлы листингов. Включение генерации листингов (при компиляции) - ищите где включается в вашем компиляторе.[/uquote]
VisualStudio+VisualGDB.Направление правильно понял - дисассемблер
[uquote="jcxz",url="/forum/viewtopic.php?p=4546335#p4546335"]Добавлено after 7 minutes 8 seconds:
[uquote="kote52",url="/forum/viewtopic.php?p=4545722#p4545722"]...
{
BufInArray[j] = Buffer_ADC;
Re += (float)BufInArray[j] * cosf(TWOPI_F * step);
Im += (float)BufInArray[j] * sinf(TWOPI_F * step);
}
else
{
BufInArray_2[j] = Buffer_ADC;
Re_2 += (float)BufInArray_2[j] * cosf(TWOPI_F * step);
Im_2 += (float)BufInArray_2[j] * sinf(TWOPI_F * step);
}
}
...[/code][/uquote]Зачем дважды одно и то же вычисляете?
Вам за размер исходника платят? 8)[/uquote]
ну у меня по таймеру3 ацп1 и ацп2 в режиме Dual mode работают, ДМА настроено на полное слово, поэтому я данные в прерывании ДМА из буфера забираю в Buffer_ADC[] по половине и полной передаче, и потом сортирую в этом цикле четные это ацп1 BufInArray[], нечетные ацп2 BufInArray_2[]. Тут нет двойной работы. НЕ конечно можно не перекидывать в два разных буфера четное и не четное - минус два массива, а сразу вычислять - пока просто так играюсь.
[uquote="jcxz",url="/forum/viewtopic.php?p=4546335#p4546335"]Совет: Рабочие целочисленные переменные внутри функций следует делать типа int или unsigned int (т.е. - равными основной разрядности процессора). Не менее. Чтобы понять "почему", опять-же - изучайте листинги.[/uquote]
Вы об этом. для 8-битных микроконтроллеров char — 8бит, int 16бит, long 32бита. Для 32-х битных char — 8бит, short 16бит, int 32бита, long 64 бита.
jcxz
Мудрый кот
Сообщения: 1717
Зарегистрирован: Вт авг 15, 2017 10:51:13

Re: Флоаты в STM32F303

Сообщение jcxz »

[uquote="kote52",url="/forum/viewtopic.php?p=4546405#p4546405"]Тут нет двойной работы.[/uquote]Есть дважды написанные одни и те же вычисления - вычисление синуса и косинуса (и вычисления вокруг них).
Вот так будет без двойной работы (если я правильно угадал разрядность BufInArray[] и BufInArray_2[]):

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

uint i;
u16 *p = &BufInArray[j];
if (i % 2) p = &BufInArray_2[j]; //нечётность массива
*p = i = Buffer_ADC[i];
float x0 = i * cosf(TWOPI_F * step);
float x1 = i * sinf(TWOPI_F * step);
if (i % 2) {
  Re_2 += x0;
  Im_2 += x1;
} else {
  Re += x0;
  Im += x1;
}
Можно и ещё лаконичнее написать, если вместо двух массивов BufInArray[] и BufInArray_2[] завести один двумерный BufInArray[2][] (или BufInArray[][2]) и вместо Re/Im и Re_2/Im_2 завести также массив из двух экземпляров:

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

struct {
  float Re, Im;
} x[2];
[uquote="kote52",url="/forum/viewtopic.php?p=4546405#p4546405"]Вы об этом. для 8-битных микроконтроллеров char — 8бит, int 16бит, long 32бита. Для 32-х битных char — 8бит, short 16бит, int 32бита, long 64 бита.[/uquote]Тогда зачем у вас рабочие переменные (счётчики) - 16-разрядные? У вас же ARM. Их лучше делать типа uint.
kote52
Встал на лапы
Сообщения: 120
Зарегистрирован: Пт мар 19, 2021 08:58:45

Re: Флоаты в STM32F303

Сообщение kote52 »

[uquote="jcxz",url="/forum/viewtopic.php?p=4546463#p4546463"]Есть дважды написанные одни и те же вычисления - вычисление синуса и косинуса (и вычисления вокруг них).
Вот так будет без двойной работы (если я правильно угадал разрядность BufInArray[] и BufInArray_2[]):

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

uint i;
u16 *p = &BufInArray[j];
if (i % 2) p = &BufInArray_2[j]; //нечётность массива
*p = i = Buffer_ADC[i];
float x0 = i * cosf(TWOPI_F * step);
float x1 = i * sinf(TWOPI_F * step);
if (i % 2) {
  Re_2 += x0;
  Im_2 += x1;
} else {
  Re += x0;
  Im += x1;
}
Можно и ещё лаконичнее написать, если вместо двух массивов BufInArray[] и BufInArray_2[] завести один двумерный BufInArray[2][] (или BufInArray[][2]) и вместо Re/Im и Re_2/Im_2 завести также массив из двух экземпляров[/uquote]
Ну я ж написал что вообще можно обойтись без массивов BufInArray[] и BufInArray_2[], и работать только Buffer_ADC, хватило бы скорости вычислений, можно еще (TWOPI_F * step) считать один раз, а не два.
Еще раз спрошу, а точно двойная? Что вы, что я - посчитали sin и cos ровно 512, у меня после сортировки четность/нечетность был расчет, у вас до и потом раскидали. В чем фокус?
[uquote="jcxz",url="/forum/viewtopic.php?p=4546463#p4546463"]Тогда зачем у вас рабочие переменные (счётчики) - 16-разрядные? У вас же ARM. Их лучше делать типа uint.[/uquote]
для 8-битных микроконтроллеров char — 8бит, int 16бит, long 32бита, такое случается с новичками постоянно :dont_know:
Аватара пользователя
КРАМ
Друг Кота
Сообщения: 25261
Зарегистрирован: Чт янв 10, 2008 22:01:02
Откуда: Московская область, Фрязино

Re: Флоаты в STM32F303

Сообщение КРАМ »

[uquote="kote52",url="/forum/viewtopic.php?p=4546524#p4546524"]посчитали sin и cos ровно 512[/uquote]
Я так понимаю, что вы пытаетесь написать ДПФ.
Внезапно вопрос. А вы понимаете уровень боковых лепестков у прямоугольного окна?
Внезапно второй вопрос. Много ли бинов вы собираетесь считать в одном цикле накопления массивов?
ЗЫ. У меня тоже один кадр накопления содержит 512 отсчетов. Но вычисление скалярной амплитуды (фаза мне не нужна) ШЕСТИ каналов в каждом по 512 отсчетов занимает примерно 700 мкс. Причем окно не прямоугольное, а Хемминга (можно любое другое - это не принципиально). И делаю я это не во флоатах, а в целых числах. Ибо АЦП 12 разрядов для FIR не требует флоатов от слова совсем. Флоаты для такой разрядности если и нужны (а скорее просто удобны) - это для IIR фильтрации.
kote52
Встал на лапы
Сообщения: 120
Зарегистрирован: Пт мар 19, 2021 08:58:45

Re: Флоаты в STM32F303

Сообщение kote52 »

КРАМ, не пытайтесь тему утянуть в нужную для вас сторону, её название ДРУГОЕ и тематика ДРУГАЯ! Выше все вопросы озвучены, хотите помочь? пожалуйста!
Аватара пользователя
КРАМ
Друг Кота
Сообщения: 25261
Зарегистрирован: Чт янв 10, 2008 22:01:02
Откуда: Московская область, Фрязино

Re: Флоаты в STM32F303

Сообщение КРАМ »

Тема та же самая. Я пытаюсь понять зачем вы СЧИТАЕТЕ синус и косинус. Обычно их забивают таблицей. Причем сразу умножают на оконную функцию. Вы интересуетесь с чего вдруг 5 с лишним миллисекунд, а сами 1024 раза считаете ПЕРИОДИЧЕСКУЮ функцию в МК, где нет CORDIC-а... В чем сакральный смысл этого мазохизма?
Впрочем, все обсуждение свелось не к тому, как включить FPU, а к обсуждению самого кода. Так что все вопросы по содержанию - это не ко мне.
Ответить

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