Перейти к содержанию
    

Salamander

Участник*
  • Постов

    637
  • Зарегистрирован

  • Посещение

Весь контент Salamander


  1. Вроде все нормально. Но немного глючит DMA2D. У меня последовательно осуществляется несколько посылок информации через DMA2D, то есть есть несколько вот таких конструкций (с отличиями), идущих друг за другом hdma2d.Init.Mode = DMA2D_R2M; hdma2d.Init.ColorMode = DMA2D_OUTPUT_ARGB8888; hdma2d.Init.OutputOffset =0; HAL_DMA2D_Init(&hdma2d); if(HAL_DMA2D_Start(&hdma2d, 0xFFFFFFFF, 0xD0400000, 1024, 600) == HAL_OK) { HAL_DMA2D_PollForTransfer(&hdma2d, 10); } Вот текст функции HAL_DMA2D_PollForTransfer Это выше моих сил.... Скажите - эта функция дожидается окончания передачи? Программа идет дальше после окончания передачи или сразу же после запуска копирования? HAL_StatusTypeDef HAL_DMA2D_PollForTransfer(DMA2D_HandleTypeDef *hdma2d, uint32_t Timeout) { uint32_t tickstart; uint32_t layer_start; __IO uint32_t isrflags = 0x0U; /* Polling for DMA2D transfer */ if((hdma2d->Instance->CR & DMA2D_CR_START) != 0U) { /* Get tick */ tickstart = HAL_GetTick(); while(__HAL_DMA2D_GET_FLAG(hdma2d, DMA2D_FLAG_TC) == 0U) { isrflags = READ_REG(hdma2d->Instance->ISR); if ((isrflags & (DMA2D_FLAG_CE|DMA2D_FLAG_TE)) != 0U) { if ((isrflags & DMA2D_FLAG_CE) != 0U) { hdma2d->ErrorCode |= HAL_DMA2D_ERROR_CE; } if ((isrflags & DMA2D_FLAG_TE) != 0U) { hdma2d->ErrorCode |= HAL_DMA2D_ERROR_TE; } /* Clear the transfer and configuration error flags */ __HAL_DMA2D_CLEAR_FLAG(hdma2d, DMA2D_FLAG_CE | DMA2D_FLAG_TE); /* Change DMA2D state */ hdma2d->State = HAL_DMA2D_STATE_ERROR; /* Process unlocked */ __HAL_UNLOCK(hdma2d); return HAL_ERROR; } /* Check for the Timeout */ if(Timeout != HAL_MAX_DELAY) { if(((HAL_GetTick() - tickstart ) > Timeout)||(Timeout == 0U)) { /* Update error code */ hdma2d->ErrorCode |= HAL_DMA2D_ERROR_TIMEOUT; /* Change the DMA2D state */ hdma2d->State = HAL_DMA2D_STATE_TIMEOUT; /* Process unlocked */ __HAL_UNLOCK(hdma2d); return HAL_TIMEOUT; } } } } /* Polling for CLUT loading (foreground or background) */ layer_start = hdma2d->Instance->FGPFCCR & DMA2D_FGPFCCR_START; layer_start |= hdma2d->Instance->BGPFCCR & DMA2D_BGPFCCR_START; if (layer_start != 0U) { /* Get tick */ tickstart = HAL_GetTick(); while(__HAL_DMA2D_GET_FLAG(hdma2d, DMA2D_FLAG_CTC) == 0U) { isrflags = READ_REG(hdma2d->Instance->ISR); if ((isrflags & (DMA2D_FLAG_CAE|DMA2D_FLAG_CE|DMA2D_FLAG_TE)) != 0U) { if ((isrflags & DMA2D_FLAG_CAE) != 0U) { hdma2d->ErrorCode |= HAL_DMA2D_ERROR_CAE; } if ((isrflags & DMA2D_FLAG_CE) != 0U) { hdma2d->ErrorCode |= HAL_DMA2D_ERROR_CE; } if ((isrflags & DMA2D_FLAG_TE) != 0U) { hdma2d->ErrorCode |= HAL_DMA2D_ERROR_TE; } /* Clear the CLUT Access Error, Configuration Error and Transfer Error flags */ __HAL_DMA2D_CLEAR_FLAG(hdma2d, DMA2D_FLAG_CAE | DMA2D_FLAG_CE | DMA2D_FLAG_TE); /* Change DMA2D state */ hdma2d->State= HAL_DMA2D_STATE_ERROR; /* Process unlocked */ __HAL_UNLOCK(hdma2d); return HAL_ERROR; } /* Check for the Timeout */ if(Timeout != HAL_MAX_DELAY) { if(((HAL_GetTick() - tickstart ) > Timeout)||(Timeout == 0U)) { /* Update error code */ hdma2d->ErrorCode |= HAL_DMA2D_ERROR_TIMEOUT; /* Change the DMA2D state */ hdma2d->State= HAL_DMA2D_STATE_TIMEOUT; /* Process unlocked */ __HAL_UNLOCK(hdma2d); return HAL_TIMEOUT; } } } } /* Clear the transfer complete and CLUT loading flags */ __HAL_DMA2D_CLEAR_FLAG(hdma2d, DMA2D_FLAG_TC|DMA2D_FLAG_CTC); /* Change DMA2D state */ hdma2d->State = HAL_DMA2D_STATE_READY; /* Process unlocked */ __HAL_UNLOCK(hdma2d); return HAL_OK; } По тексту функции вроде бы должна дожидаться. ПО факту: HAL_DMA2D_Init(&hdma2d); if(HAL_DMA2D_Start(&hdma2d, 0xFFFFFFFF, 0xD0400000, 1024, 600) == HAL_OK) { HAL_DMA2D_PollForTransfer(&hdma2d, 10); } ЗДЕСЬ БРЕЙКПОИНТ HAL_DMA2D_Init(&hdma2d); if(HAL_DMA2D_Start(&hdma2d, 0xFFFFFFFF, 0xD0400000, 1024, 600) == HAL_OK) { HAL_DMA2D_PollForTransfer(&hdma2d, 10); } ЗДЕСЬ БРЕЙКПОИНТ HAL_DMA2D_Init(&hdma2d); if(HAL_DMA2D_Start(&hdma2d, 0xFFFFFFFF, 0xD0400000, 1024, 600) == HAL_OK) { HAL_DMA2D_PollForTransfer(&hdma2d, 10); } ЗДЕСЬ БРЕЙКПОИНТ если наставить брейкпоинтов и спокойно шагать, никаких артефактов не наблюдается. Если работать в обычном режиме - артефакты.
  2. Поборол таки и Z-буфер и нормали.... Непонятным пока остается то что запись через DMA2D идет нормально, а вот через *(__IO uint32_t*)(adr + (x + y * 1024)*3)=color- с артефактами.... Пытаюсь теперь интегрировать этот код не в основную программу, а внутрь функций toochGFX - странные проблемы.....Тут уже вопросы к знатокам KEIL файл dsp3d.c - добавлен в проект #include <dsp3d.h> - добавлено в main.c Все работает. Беру другой файл, сгенерированный системой touchgfx - mainscreenview.cpp добавляю в него #include <dsp3d.h> вызываю в тексте dsp3D_renderGouraud(dsp3dModel2) (просто одна из функций файла dsp3d.c) Проект компилируется, но не линкуется Error: L6218E: Undefined symbol dsp3D_renderGouraud(float*) (referred from mainscreenview.o). Как так? Функция видна в одном месте проекта, но не видна в другом, хотя в обоих местах библиотека подключена одинаково....
  3. Есть специалисты в области 3D? На видео кубик, в коде я включил использование при визуализации Z-буфера. Первые кадры визуализируются нормально, потом же кубик постепенно "растворяется". Скажу сразу - нормали у меня от балды (не понял пока, как расчитывать их), это заметно по тому, как по разному освещаются полигоны одной грани, но мне пока терпимо. Так вот, а могут ли неправильные нормали давать такой эффект? Или это только проблемы Z-буфера? Или еще чего-то? https://cloud.mail.ru/public/DGUX/TZoRw7stw Пардон, правильное видео тут https://cloud.mail.ru/public/4h2M/DeoFPhWme
  4. Я полагаю, что в этом случае восприятие результата библиотекой и учет особенностей float остается на совести самой библиотеки. Меня волнует лишь - избранный мной способ записи в буфер - он обеспечивает корректную передачу и извлечение данных, скажем так в битовом выражении? Вы, похоже, невнимательно прочли - у меня ускорение в 1,5-2 раза получилось.
  5. Так... следующий вопрос Он, возможно, потребует еще и знаний 3d, но все же.... Вот функции чтения и записи в Z-буфер void dsp3D_LL_writeToDepthBuffer(uint32_t pos, float32_t value) { // YOUR IMPLEMENTATION *(__IO float32_t*)(0xD0200000 + pos*sizeof(float32_t))=value; } float32_t dsp3D_LL_readFromDepthBuffer(uint32_t pos) { //return 0; // YOUR IMPLEMENTATION return *(__IO float_t*)(0xD0200000 + pos*sizeof(float32_t)); } прописал я их - ан нет, отображаются все грани, даже видимые. Я подозреваю несколько причин - часть из них исследую сам, а вот про одну хотел спросить вас. Проверил я, как на практике работают эти функции - принудительно записал в них 3.14. При чтении каждый раз получаю что-то вроде 3.1400001 1. С точки зрения программирования - почему так и как с этим бороться? 2. С точки зрения 3D программирования - повлияет ли это на работу с Z-буфером?
  6. Вот оно че!!!! Заменил z = dsp3D_interpolate(z1, z2, (float32_t)(x - sx) * divider_multiplier); на z= z1 + (z2 - z1) * MAX(0.0f, MIN((float32_t)(x - sx) * divider_multiplier, 1.0f)); ну это к вопросу об инлайнах - с ними не получилось, я просто действие, заложенное в функции, подставил в формулу. FPS был 9 стабильно, стал колебаться от 16 до 22. Вот что оптимизация животворящая делает)))
  7. Математически? Так это не тождественно термину "кибернетически" К примеру, 2-4 - математически это минус два, а для типа uint8t - это 253. Что-то не учли значит.... А то что математически не должно меняться, я согласен.
  8. Ни на такт меньше не стало, а вот результат другой - кубик стал кривой))) Но это мелочь, 21 такт всего и вызываается нечасто.
  9. у этого макаронника и емайл указан и скайп - молчит
  10. А вот тут сам Фабио (автор библиотеки) сдулся и сделал себе самому пометку // OPTIMIZE IT! void dsp3D_transformVertex(float32_t *v, float32_t *m, float32_t *tv) { float32_t w; tv[0] = v[0]*m[0] + v[1]*m[4] + v[2]*m[8] + m[12]; tv[1] = v[0]*m[1] + v[1]*m[5] + v[2]*m[9] + m[13]; tv[2] = v[0]*m[2] + v[1]*m[6] + v[2]*m[10] + m[14]; w = 1.0f / (v[0]*m[3] + v[1]*m[7] + v[2]*m[11] + m[15]); tv[0] *= w; tv[1] *= w; tv[2] *= w; } А по-моему, тут ничего не оптимизировать..... Я не прав? А вот тут наверное можно, что скажете? m[0] = coordinates[0] * (float32_t)SCREEN_WIDTH + (float32_t)SCREEN_WIDTH / 2.0f;
  11. Я не так инлайню? inline float32_t dsp3D_interpolate(float32_t min, float32_t max, float32_t gradient) { return (min + (max - min) * dsp3D_clamp(gradient)); } есть у меня сравнивалка файлов. Погляжу.
  12. Упаси бог меня требовать от вас делать что-то для меня в ущерб своей работе. Так я так и делаю, не совсем я "бум-бум" )) Наверное я содержимое того, что инлайнится, перенесу внутрь целиком, посмотрю, что выйдет.
  13. вот что он выдумывает sx = dsp3D_interpolate(pa[0], pb[0], gradient1); 0000a8 ed991a00 VLDR s2,[r9,#0] 0000ac eef00a41 VMOV.F32 s1,s2 0000b0 ed951a00 VLDR s2,[r5,#0] 0000b4 eeb00a41 VMOV.F32 s0,s2 0000b8 eeb01a49 VMOV.F32 s2,s18 0000bc f7fffffe BL dsp3D_interpolate 0000c0 eefd8ac0 VCVT.S32.F32 s17,s0 а вот без и инлайна ;;;550 sx = dsp3D_interpolate(pa[0], pb[0], gradient1); 0000ba ed951a00 VLDR s2,[r5,#0] 0000be eef00a41 VMOV.F32 s1,s2 0000c2 ed911a00 VLDR s2,[r1,#0] 0000c6 eeb00a41 VMOV.F32 s0,s2 0000ca eeb01a44 VMOV.F32 s2,s8 0000ce f7fffffe BL dsp3D_interpolate 0000d2 eefd3ac0 VCVT.S32.F32 s7,s0 разницы нет, но что добавилось, я не знаю, но адреса, если вы обратите внимание, сместились, значит что-то добавилось.
  14. то есть, нужно приводить к int, а именно это и делается в вашем объявлении переменной? Иными словами, это нельзя оптимизировать?
  15. Проверю. А пока вопрос.... Хочу заменить конструкцию #define ASSEMBLE_ARGB(A,R,G,B) (A << 24 | R << 16 | G << 8 | B) const uint32_t rt = r * ndl; // нет смысла преобразовывать цвет в uint8_t, это лишние операции для процессора const uint32_t gt = g * ndl; // также нет смысла приводить цвет к float, его тип будет расширен автоматически, а текста будет меньше const uint32_t bt = b * ndl; *(__IO uint32_t*)(0xD0000000 + 3*(y * SCREEN_WIDTH + x))=ASSEMBLE_ARGB(a, r, g, b); на прямое присваивание. *(__IO uint32_t*)(0xD0000000 + 3*(y * SCREEN_WIDTH + x))=(a << 24) | ((r * ndl) << 16) | ((r * ndl) << 8) | (r * ndl); но компилятор негодует ..\Middlewares\Third_Party\dsp3D\src\dsp3D.c(515): error: #1460: expression must have integral or fixed-point type const uint32_t col =(a << 24) | ((r * ndl) << 16) | ((r * ndl) << 8) | (r * ndl); Во первых, мне непонятно, почему он не хочет сдвигать влево заключенное в скобках произведение, а во вторых - в теории, должно ли это сократить число тактов?
  16. Ух... это точно... в упор не увидел обновление r,g,b. До этого не застревал и, в общем-то работу провел большую. Один кубик в режиме flat дает 11 FPS на 1024х600. В режиме Gouraud - 6 FPS. И то - у меня пока не отсекается Z-буфер, по непонятным причинам в него идут кривые данные. А теперь результаты каждого из шагов: const float32_t divider_multiplier = 1.0f / (ex - sx); gradient = (float32_t)(x - sx) * divider_multiplier; было 31, стало 12 шагов const uint32_t rt = r * ndl; // нет смысла преобразовывать цвет в uint8_t, это лишние операции для процессора const uint32_t gt = g * ndl; // также нет смысла приводить цвет к float, его тип будет расширен автоматически, а текста будет меньше const uint32_t bt = b * ndl; было 48, стало 31 А вот "заинлайнивание" inline float32_t dsp3D_clamp(float32_t value) { return MAX(0.0f, MIN(value, 1.0f)); } inline float32_t dsp3D_interpolate(float32_t min, float32_t max, float32_t gradient) { return (min + (max - min) * dsp3D_clamp(gradient)); } наоборот добавило тормозов В одном месте было 216, стало 270 В другом было 70 стало 84. Листинг не смотрел, мне пора убегать. Но так, для информации.
  17. Почистил. Софтового FPU не стало. Но все равно ужасно медленно. Очень много времени (до 30 000 тактов) занимает вот этот фрагмент, выводящий одну линию. for (x = sx; x < ex; x++) { gradient = (float32_t)(x - sx) / (float32_t)(ex - sx); z = dsp3D_interpolate(z1, z2, gradient); ndl = dsp3D_interpolate(snl, enl, gradient); a = (color >> 24); r = (color >> 16); g = (color >> 8); b = (color); r = (uint8_t)((float32_t)r * ndl); g = (uint8_t)((float32_t)g * ndl); b = (uint8_t)((float32_t)b * ndl); dsp3D_drawPointDepthBuffer(x, y, z, ASSEMBLE_ARGB(a, r, g, b)); } НИЖЕ ТАК, ДЛЯ СПРАВКИ СОДЕРЖАНИЕ ИСПОЛЬЗУЕМЫХ ФУНКЦИЙ float32_t dsp3D_clamp(float32_t value) { return MAX(0.0f, MIN(value, 1.0f)); } float32_t dsp3D_interpolate(float32_t min, float32_t max, float32_t gradient) { return (min + (max - min) * dsp3D_clamp(gradient)); } Есть мысли по оптимизации? А вот дальше - может быть я туплю... смотрите, еще раз приведу фрагмент: for (x = sx; x < ex; x++) { gradient = (float32_t)(x - sx) / (float32_t)(ex - sx); z = dsp3D_interpolate(z1, z2, gradient); ndl = dsp3D_interpolate(snl, enl, gradient); a = (color >> 24); // значения a,r,g,b r = (color >> 16);// в этой части цикла всегда одни и те же g = (color >> 8);// логично же вынести эти 4 строки до начала цикла for? и пользоваться единожды вычисленными значениями... b = (color);// но если я это делаю - отрисовка меняется r = (uint8_t)((float32_t)r * ndl); g = (uint8_t)((float32_t)g * ndl); b = (uint8_t)((float32_t)b * ndl); dsp3D_drawPointDepthBuffer(x, y, z, ASSEMBLE_ARGB(a, r, g, b)); } Скажите, почему меняется работа функции, если я указанные 4 строки переношу до начала цикла? Ведь вычисление a,r,g,b из неменяющегося color дает одни и те же значения, так почему бы их не вычислить заранее и потом просто использовать? Чего я в упор не вижу?
  18. Ужо продают. Но... В компании База Электроники мне выставили 5000 за одну микросхему. Зато 36 штук могут продать по 1100. Я расстроился и даже не поинтересовался о сроках поставки.
  19. Вернемся теперь к выходу за границы Тут самое интересное. Выход за границы вызывается макросом ASSEMBLE_ARGB - #define ASSEMBLE_ARGB(A,R,G,B) (A << 24 | R << 16 | G << 8 | B) Если написать к примеру так dsp3D_drawFaceGouraud(vertex_transform_a, vertex_transform_b, vertex_transform_c, 0xFFFFFFFF); // замена ASSEMBLE_ARGB на 0xFFFFFF То ошибка исчезает. Почему же? А вот почему - в нее подставляется RGBr, RGBg, RGBb. А они берутся из массива float32_t dsp3dModel[122] = {8,12, ...................} Задумка автора такова, что в однородном массиве запакованы и цвета и координаты и нормали. Поскольку нормали могут быть float32_t, то и все остальные данные - float32_t. Это не есть гуд? У меня так #define ARM_MATH_CM7 #if defined(ARM_MATH_CM7) #include "core_cm7.h" #define ARM_MATH_DSP #elif defined (ARM_MATH_CM4) #include "core_cm4.h" #define ARM_MATH_DSP #elif defined (ARM_MATH_CM3) #include "core_cm3.h" #elif defined (ARM_MATH_CM0) #include "core_cm0.h" #define ARM_MATH_CM0_FAMILY Да вот что странно - вроде бы расчеты там, где деление меняли на умножение сократили с 200 до 14, а функция отрисовки одной точки все так же длится около 340 попугаев.... Может в измерениях напутал, но тормоза на экране говорят об обратном. Буду искать, что грузит сильнее всего....
  20. Быстрее конечно стало, но в целом еще дофига где тормозов.... хотя везде, где значения указаны как 1.0, 3.0 и пр., я сделал замены. Вот тут никаких фортелей типа замены деления на умножение не надо сделать? yScale = 1.0f / tan(fov * 0.5f); Смущает еще вот такая шляпа в листинге ;;;187 arm_sub_f32(lightPosition, vertex, lightDirection, 3); 00000e 2303 MOVS r3,#3 000010 aa07 ADD r2,sp,#0x1c 000012 4621 MOV r1,r4 000014 4630 MOV r0,r6 000016 f7fffffe BL arm_sub_f32 В конце вызывается функция, которая в библиотеке arm_math... Вот ее текст? void arm_sub_f32( float32_t * pSrcA, float32_t * pSrcB, float32_t * pDst, uint32_t blockSize) { uint32_t blkCnt; /* loop counter */ #if defined (ARM_MATH_DSP) /* Run the below code for Cortex-M4 and Cortex-M3 */ float32_t inA1, inA2, inA3, inA4; /* temporary variables */ float32_t inB1, inB2, inB3, inB4; /* temporary variables */ /*loop Unrolling */ blkCnt = blockSize >> 2U; /* First part of the processing with loop unrolling. Compute 4 outputs at a time. ** a second loop below computes the remaining 1 to 3 samples. */ while (blkCnt > 0U) { /* C = A - B */ /* Subtract and then store the results in the destination buffer. */ /* Read 4 input samples from sourceA and sourceB */ inA1 = *pSrcA; inB1 = *pSrcB; inA2 = *(pSrcA + 1); inB2 = *(pSrcB + 1); inA3 = *(pSrcA + 2); inB3 = *(pSrcB + 2); inA4 = *(pSrcA + 3); inB4 = *(pSrcB + 3); /* dst = srcA - srcB */ /* subtract and store the result */ *pDst = inA1 - inB1; *(pDst + 1) = inA2 - inB2; *(pDst + 2) = inA3 - inB3; *(pDst + 3) = inA4 - inB4; /* Update pointers to process next sampels */ pSrcA += 4U; pSrcB += 4U; pDst += 4U; /* Decrement the loop counter */ blkCnt--; } /* If the blockSize is not a multiple of 4, compute any remaining output samples here. ** No loop unrolling is used. */ blkCnt = blockSize % 0x4U; #else /* Run the below code for Cortex-M0 */ /* Initialize blkCnt with number of samples */ blkCnt = blockSize; #endif /* #if defined (ARM_MATH_DSP) */ while (blkCnt > 0U) { /* C = A - B */ /* Subtract and then store the results in the destination buffer. */ *pDst++ = (*pSrcA++) - (*pSrcB++); /* Decrement the loop counter */ blkCnt--; } } Это явно "софтовая тягомотина". Она имеет аналог в аппаратном исполнении? Это ошибка автора библиотеки - использовать эту функцию вместо аппаратной или это вынужденная мера?
  21. Ну что я хочу сказать, вот число тиков DWT; vnFace[0] = (v1[6] + v2[6] + v3[6]) / 3.0; - от 160 до 190 vnFace[1] = (v1[7] + v2[7] + v3[7]) / 3.0; - от 110 до 280 vnFace[2] = (v1[8] + v2[8] + v3[8]) / 3.0; - от 85 до 205 А если аппаратно vnFace[0] = (v1[6] + v2[6] + v3[6]) / 3.0f; - 32 vnFace[1] = (v1[7] + v2[7] + v3[7]) / 3.0f; -35 vnFace[2] = (v1[8] + v2[8] + v3[8]) / 3.0f; -30 Не в 10 раз, но все же в разы быстрее. Все понял, буду чистить библиотеку...
  22. Вот что я сделал h[0] = (a[0] + b[0] + c[0]) / 3.0; h[1] = (a[1] + b[1] + c[1]) / 3.0f; То есть, в одном месте поставил f, в другом оставил как есть. И вот листинг ;;;698 h[0] = (a[0] + b[0] + c[0]) / 3.0; 000016 ed950a00 VLDR s0,[r5,#0] 00001a edd60a00 VLDR s1,[r6,#0] 00001e ee300a20 VADD.F32 s0,s0,s1 000022 edd70a00 VLDR s1,[r7,#0] 000026 ee300a20 VADD.F32 s0,s0,s1 00002a ee101a10 VMOV r1,s0 00002e 4608 MOV r0,r1 000030 f7fffffe BL __aeabi_f2d 000034 ec410b19 VMOV d9,r0,r1 000038 ed9f0b37 VLDR d0,|L1.280| 00003c ec532b10 VMOV r2,r3,d0 000040 f7fffffe BL __aeabi_ddiv 000044 ec410b18 VMOV d8,r0,r1 000048 f7fffffe BL __aeabi_d2f 00004c 9003 STR r0,[sp,#0xc] ;;;699 h[1] = (a[1] + b[1] + c[1]) / 3.0f; 00004e ed950a01 VLDR s0,[r5,#4] 000052 edd60a01 VLDR s1,[r6,#4] 000056 ee300a20 VADD.F32 s0,s0,s1 00005a edd70a01 VLDR s1,[r7,#4] 00005e ee300a20 VADD.F32 s0,s0,s1 000062 eef00a08 VMOV.F32 s1,#3.00000000 000066 ee801a20 VDIV.F32 s2,s0,s1 00006a ed8d1a04 VSTR s2,[sp,#0x10] с "f" определенно короче. А судя по командам - FPU работает. И, как я понял, "BL __aeabi_f2d" - это не просто одна команда, а отсыл к жуткой софтовой тягомотине? Не серчайте на мое упрямство. Я не знал некоторых тонкостей и, думал, что это вы меня не понимаете. Спасибо за то, что терпеливо разъяснили.
  23. Это об этом мне компилятор говорит? ..\Middlewares\Third_Party\dsp3D\src\dsp3D.c(233): warning: #1035-D: single-precision operand implicitly converted to double-precision
  24. То есть, если я подправлю математическую операцию, как мне советовали (в частности, поставлю символ f), должно уменьшить я количество тактов счётчика DWT, затрачиваемое на эту операцию, правильно? Я почему спрашиваю - операций этих уйма, хочется не гадать, все ли я отредактировал, а отслеживать эффективность каждого шага...
×
×
  • Создать...