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

adnega

Свой
  • Постов

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

  • Посещение

  • Победитель дней

    3

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


  1. Я другого объяснения придумать не могу, и это легко проверить. Кста, про скорость, вроде -03, а -Os это про размер.
  2. Сравните листинги функций msDelay для разных сборок. От того, как компилятор их реализует многое будет зависеть.
  3. Только это смущает? Я вот понять не могу: в первых трех строчках одинаковое название, а ценник в два раза отличается. Это как? Может, опечатки?
  4. На самом деле исходные 8 байт идут не подряд, а с некоторым шагом (например, 4 байта). Походу, ваш алгоритм от этого становится менее быстрым. Кста, в некоторых случаях шаг может быть значительно больше, и даже не степень двойки (например, 32 + 4 = 36).
  5. Ок. Я тут прикинул: void func_bb(void *p) { 8000600: e92d 41f0 stmdb sp!, {r4, r5, r6, r7, r8, lr} volatile int *dst, *src; for(int n = 0; n < 8; n++) 8000604: 2400 movs r4, #0 { dst = &RAM_BIT_ADDR(&stat_video_digit[0], n_pos[n]); 8000606: 4d14 ldr r5, [pc, #80] ; 8000658 stat_video_digit 8000608: 4a14 ldr r2, [pc, #80] ; 800065c digit_video 800060a: 4f15 ldr r7, [pc, #84] ; 8000660 n_pos for(int j = 0; j < VALUE_SIZE; j++) { src = &RAM_BIT_ADDR(&digit_video[n * VALUE_SIZE + j], 7); 800060c: f8df e054 ldr.w lr, [pc, #84] ; 8000664 bb dst = &RAM_BIT_ADDR(&stat_video_digit[0], n_pos[n]); 8000610: 016d lsls r5, r5, #5 8000612: 0152 lsls r2, r2, #5 8000614: 4616 mov r6, r2 8000616: f817 3b01 ldrb.w r3, [r7], #1 800061a: ea45 0383 orr.w r3, r5, r3, lsl #2 800061e: f043 5308 orr.w r3, r3, #570425344 ; 0x22000000 for(int j = 0; j < VALUE_SIZE; j++) 8000622: f503 7180 add.w r1, r3, #256 ; 0x100 8000626: f503 63a0 add.w r3, r3, #1280 ; 0x500 800062a: f5a1 7080 sub.w r0, r1, #256 ; 0x100 src = &RAM_BIT_ADDR(&digit_video[n * VALUE_SIZE + j], 7); 800062e: ea46 0c0e orr.w ip, r6, lr for(int i = 0; i < 8; i++) { *dst = *src; 8000632: f85c 8904 ldr.w r8, [ip], #-4 8000636: f840 8b20 str.w r8, [r0], #32 for(int i = 0; i < 8; i++) 800063a: 4288 cmp r0, r1 800063c: d1f9 bne.n 8000632 ; 8 times * (ldr + str + cmp + bne) = 32 = LOOP1 800063e: f500 7180 add.w r1, r0, #256 ; 0x100 for(int j = 0; j < VALUE_SIZE; j++) 8000642: 428b cmp r3, r1 8000644: f106 0620 add.w r6, r6, #32 8000648: d1ef bne.n 800062a ; 4 times * (LOOP1 + sub + orr + add + cmp + add + bne) = 152 = LOOP2 for(int n = 0; n < 8; n++) 800064a: 3401 adds r4, #1 800064c: 2c08 cmp r4, #8 800064e: f102 0280 add.w r2, r2, #128 ; 0x80 8000652: d1df bne.n 8000614 ; 8 times * (LOOP2 + mov + ldrb + orr * 2 + add * 2 + cmp + bne) = 1280 src -= 1; dst += 8; } } } } 8000654: e8bd 81f0 ldmia.w sp!, {r4, r5, r6, r7, r8, pc} ; total = LOOP3 + 9 = 1290 8000658: 0000022c .word 0x0000022c ; stat_video_digit 800065c: 2000024c .word 0x2000024c ; digit_video 8000660: 08003ead .word 0x08003ead ; n_pos 8000664: 2200001c .word 0x2200001c ; bb Получается 1290 инструкций. Пусть в среднем 2 такта на инструкцию и увеличим число инструкций до 1800. При развертке 100 Гц получается 360к тактов, что при 72 МГц тактовой частоты дает нагрузку 0.5%. Ядро Cortex-M3. Добавьте в ваш код таблицу n_pos. Она константная, поэтому будем считать, что ничего не изменяется в плане быстродействия, но в плане сопровождения просто хочется видеть насколько это муторно. У вас код 85 тактов. Умножаем на 4 (VALUE_SIZE) получается 340, т.е. примерно в 8 раз быстрее. Кста, размер кода у меня порядка 100 байт, у вас - в три * 4 раза больше. Т.е. по размеру я выигрываю в 12 раз ;)
  6. for(n = 0; n < 8; n++) { dst = &RAM_BIT_ADDR(&stat_video_digit[0], n_pos[n]); for(j = 0; j < VALUE_SIZE; j++) { src = &RAM_BIT_ADDR(&digit_video[n * VALUE_SIZE + j], 7); for(i = 0; i < 8; i++) { *dst = *src; src -= 1; dst += 8; } } } где #define VALUE_SIZE (4) // размер одного "вагончика" const BYTE n_pos[8] = {5, 7, 4, 6, 3, 1, 2, 0}; // таблица подключений В копилку рабочих кодов ;)
  7. На MCO обычно 8 МГц от ST-Link`а.
  8. MCO1 - это 8 МГц с ST-Link`а? Тогда не понятно как у вас USB вообще работает. У меня много разных NUCLEO на ST-Link_v3, и МК там со своими кварцами. Есть одна STM32F767 со старым (вторым) ST-Link - на нем частота MCO для таргета 7.99989 МГц. У третьих - примерно 7.98890 МГц (частота плавает в районе 0.01 МГц). На Discovery со вторым ST-Link`ом - 8.00062 МГц
  9. Нужен исходник. Какие именно у вас значения. Не замечал, чтоб таймеры в STM32 как-то не так делили, точность определяется только точностью опорной частоты. Кста, внутри не кварц, а RC-генератор. У него точность хуже и примерно 1% (как в вашем случае) - это типичная ошибка. Вам нужен именно кварцевый резонатор/генератор в качестве опоры.
  10. Предделитель и делитель должны быть на единицу меньше требуемого значения.
  11. И я готовлю. Только беда: контроллер одновременно поддерживает два вида подключения модулей - "паравозиком" и "параллельно". Есть 8 модулей (например, цены на АЗС) их могут подключить паравозиком, но неисправность одного модуля приведет к неработоспособности оставшейся части. Поэтому есть альтернативное подключение: 8 портов для индивидуального подключения модулей. Первый тип, очевидно, SPI+DMA. Второй - FSMC+DMA (как бы octo-spi). Второй буфер получается из первого транспонированием. Транспонировать проще (меньше матана) чем два варианта setpixel.
  12. У меня задача сложнее была нужно было выполнять транспонирование битов: есть 8 байт, нужно первые биты всех байт по порядку сложить в первый выходной байт, вторые биты - во второй и т.д. И делать это 100 раз в секунду, и байтов там под тыщу - вывод картинки на матрицу светодиодов. Делал с использованием BB. Вот бы одну инструкцию или трюк какой...
  13. Думается мне, что все эти перекодирования кнопок матричной клавиатуры ничто в масштабе передачи по интерфейсу. Тут оптимизировать лучше не поток команд, а качество исходника на ЯВУ. Кто сказал, что "оптимально" - это ="быстро"? Я читаю, что "оптимально" это про качество исходника, его многократной применимости в других проектах, скорости разработки, защиты от глупых ошибок - денег в конце концов. Да, если нужен быстрый код, то UBFX + BFI - самый лучший вариант, и довольно универсальный. Но это ASM, совсем другие требования к разработчику, легко допустить ошибку, сложно сопровождать (например, битик в протоколе потребуется поменять местом или раскладка матричной клавиатуры поменяется из-за снабжения). И самое главное - это прибивание гвоздями исходника к процессору. Я бы завел одну структуру с битовыми полями под клавиатуру, вторую - под пакет протокола. В исходнике - присвоение всех битов протокола битам клавиатуры. Если меняется клавиатура - меняем только ее поля в структуре. Аналогично для протокола. Дальше пусть компилятор оптимизирует - я показал на что он способен.
  14. У ТС Cortex-M3, а в них эта фича встроенная. У М4-моделей - опциональная. У М0 - отсутствует. У М7 и прочих - не в курсе. Забавно, что jcxz указал, что фича может отсутствовать, но когда я дополнил, что и инструкций выбранных может не быть - вспомнили о М3. С М4 и М7 соглашусь, но М3-то есть без Bit-banding ?
  15. Тогда можете показать Cortex-M без Bit-banding ?
  16. У них за последние несколько лет (сужу по сайту) много в этом плане годноты. Если б это можно было закупать без проблем, то много чего мог бы импортозаместить из своей продукции.
  17. В начале апреля КП на 200 шт К1986ВЕ92QI было со сроком 2 дня. Но шепчутся, что это остатки распродают, и больше не будет. Кто-то может прояснить ситуацию?
  18. Как и Поэтому лучше не мудрить с ASM и сделать на Си.
  19. typedef struct s_b { union { DWORD dw; struct { DWORD b0:1; DWORD b1:1; ... DWORD b30:1; DWORD b31:1; }; }; } s_b; void foo(void) { s_b src, dst; src.dw = var_1; dst.b0 = src.b10; dst.b1 = src.b11; dst.b2 = src.b12; dst.b3 = src.b8; ... dst.b28 = src.b23; dst.b29 = src.b20; dst.b30 = src.b24; dst.b31 = src.b25; var_2 = dst.dw; } Тупо в лоб на Си: Видим, что Си все сделает за вас (без сдвигов и масок). Правда, смежные битики в одну транзакцию не объединяет.
  20. Можно по-изучать map-файл - там быстро можно найти куда килобайты утекают.
×
×
  • Создать...