Цитата(ViKo @ Apr 14 2014, 19:35)

Нюанс всплыл - невозможно заинлайнить функцию (DelayCY4), находящуюся в другом файле. Пришлось в один объединить.
Это не нюанс, это стандартное поведение.
Для решения подобных задач нужно всё в заголовочном файле размещать:
Код
static __inline void delay(int x)
{
....
}
Цитата(toweroff @ Apr 14 2014, 19:54)

не панацея, конечно, но позволит уйти от асма, тем более что точная задержка как таковая не критична прям уж так
Не системный подход с кучей сорного кода, заслоняющего основную идею.
Здесь асм не столько для точности, а больше для снятия зависимости от уровня оптимизации.
Тут у меня самого возник вопрос, касательно задержек в gcc.
Вот такой код упорно приводит проект в нерабочее состояние:
Код
#define delay_4cycles(cy) \
(__extension__({ \
uint32_t __x = (uint32_t)(cy); \
__asm__ __volatile__ \
( \
"loop%=: subs %[cnt],#1" "\n\t" \
" bne loop%=" "\n\t" \
: \
: [cnt]"r"(__x) \
: "cc" \
); \
}))
for(;;)
{
delay_4cycles(1);
pin_toggle(LED_RED);
}
А именно не производится перезагрузка счётчика цикла внутри цикла for.
В данном примере 1 загружается в регистр единожды перед циклом for, что собственно является нежелательным поведением:
Код
8001df6: f04f 0001 mov.w r0, #1
...
8001e0a: 3801 subs r0, #1
8001e0c: d1fd bne.n 8001e0a
8001e0e: 682b ldr r3, [r5, #0]
8001e10: ea6f 0703 mvn.w r7, r3
8001e14: 6037 str r7, [r6, #0]
8001e16: e7f8 b.n 8001e0a
А без использования асм всё нормально:
Код
8001e04: bf00 nop
8001e06: bf00 nop
8001e08: bf00 nop
8001e0a: bf00 nop
8001e0c: 6806 ldr r6, [r0, #0]
8001e0e: ea6f 0306 mvn.w r3, r6
8001e12: 602b str r3, [r5, #0]
8001e14: e7f6 b.n 8001e04
Прошу помощи у аудитории!
arm-none-eabi-gcc.EXE (GNU Tools for ARM Embedded Processors / bleeding-edge-toolchain-131005) 4.7.4 20130913 (prerelease)
CFLAGS += -flto
CFLAGS += -fomit-frame-pointer
CFLAGS += -falign-functions=16
CFLAGS += -fgraphite
CFLAGS += -funroll-loops
CFLAGS += -ffunction-sections
CFLAGS += -fdata-sections
CFLAGS += -O3
#CFLAGS += -O1