Т.е. так вполне сносно будет?
На так давно ReAl провёл целое исследование на эту тему. Я позволю себе процитировать фрагмент его письма:
Цитата
-------- CPL ------------------------------------------------------
---- через ODR ^=
521 0012 DA68 ldr r2, [r3, #12]
522 0014 82F00202 eor r2, r2, #2
523 0018 DA60 str r2, [r3, #12]
-- 8 байтов, 9 циклов, 125 ns -- всё как у On/Off через ODR |=, что и
должно было быть
---- через Latched() ? Off() : On()
Полные глупости при компиляции, компилируется в условные переходы,
нестабильный и плохой результат.
---- через GPIOx->BSRR = Latched() ? mask << 16 : mask;
551 001a DA68 ldr r2, [r3, #12]
556 001c 12F0020F tst r2, #2
557 0020 0CBF ite eq
558 0022 0222 moveq r2, #2
559 0024 4FF40032 movne r2, #131072
561 0028 1A61 str r2, [r3, #16]
-- 14 байтов, 12 циклов (около 167 ns импульс)
Опять выходит немного больше, чем по рассчёту -- как и для ODR |= / &= / ^=
---- через bit-band
525 0010 5A68 ldr r2, [r3, #4]
526 0012 D243 mvns r2, r2
527 0014 5A60 str r2, [r3, #4]
-- 6 байтов, те же самые 12 циклов, что и выше.
По коду короче даже ODR ^=
По времени дольше, зато атомарно.
---- через GPIOx->BSRR = Latched() ? mask << 16 : mask;
Но Latched() сделано через bit-band
619 004a 5268 ldr r2, [r2, #4]
624 004c 002A cmp r2, #0
625 004e 0CBF ite eq
626 0050 0222 moveq r2, #2
627 0052 4FF40032 movne r2, #131072
629 0056 1A61 str r2, [r3, #16]
Немного короче и бстрее, чем с Latched() через считывание ODR и маскирование.
Тут использовать особого смысла нет, так как почти не быстрее
bit-band, но длиннее.
Но сам Latched() стоит сделать через bit-band. Разница между
556 001c 12F0020F tst r2, #2
и
624 004c 002A cmp r2, #0
мелочь, а приятно. А где-то просто эта единичка/нолик сразу в bool
пойдёт для возврата из функции.
---- через ODR ^=
521 0012 DA68 ldr r2, [r3, #12]
522 0014 82F00202 eor r2, r2, #2
523 0018 DA60 str r2, [r3, #12]
-- 8 байтов, 9 циклов, 125 ns -- всё как у On/Off через ODR |=, что и
должно было быть
---- через Latched() ? Off() : On()
Полные глупости при компиляции, компилируется в условные переходы,
нестабильный и плохой результат.
---- через GPIOx->BSRR = Latched() ? mask << 16 : mask;
551 001a DA68 ldr r2, [r3, #12]
556 001c 12F0020F tst r2, #2
557 0020 0CBF ite eq
558 0022 0222 moveq r2, #2
559 0024 4FF40032 movne r2, #131072
561 0028 1A61 str r2, [r3, #16]
-- 14 байтов, 12 циклов (около 167 ns импульс)
Опять выходит немного больше, чем по рассчёту -- как и для ODR |= / &= / ^=
---- через bit-band
525 0010 5A68 ldr r2, [r3, #4]
526 0012 D243 mvns r2, r2
527 0014 5A60 str r2, [r3, #4]
-- 6 байтов, те же самые 12 циклов, что и выше.
По коду короче даже ODR ^=
По времени дольше, зато атомарно.
---- через GPIOx->BSRR = Latched() ? mask << 16 : mask;
Но Latched() сделано через bit-band
619 004a 5268 ldr r2, [r2, #4]
624 004c 002A cmp r2, #0
625 004e 0CBF ite eq
626 0050 0222 moveq r2, #2
627 0052 4FF40032 movne r2, #131072
629 0056 1A61 str r2, [r3, #16]
Немного короче и бстрее, чем с Latched() через считывание ODR и маскирование.
Тут использовать особого смысла нет, так как почти не быстрее
bit-band, но длиннее.
Но сам Latched() стоит сделать через bit-band. Разница между
556 001c 12F0020F tst r2, #2
и
624 004c 002A cmp r2, #0
мелочь, а приятно. А где-то просто эта единичка/нолик сразу в bool
пойдёт для возврата из функции.
По результатам этих исследований победил вариант с BB
