ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Вторник
9 июля
301028 Топик полностью
Cepгeй Бopщ (21.01.2012 15:15 - 15:26, просмотров: 126) ответил Точка опоры из дому на Я ещё только учусь, поэтому никак не могу победить Си. Имеется некий "черный ящик" в памяти программ, а именно - начальный загрузчик. О нём известно несколько точек входа в подпрограммы и регистры процессора принимающие данные и
GCC позволяет это сделать очень красиво и эффективно. Он позволяет объяснить компилятору, что функция принимает параметры в конкретных регистрах и в конкретных отдает, и компилятор строит код с учетом этого. inline uint16_t driver::serial_no() { // drv_serial_no возвращает результат в R16:R17 register uint16_t result asm ("r16"); asm volatile ( " RCALL drv_serial_no\n\t" : "=r" (result) : ); return result; } inline void driver::rf::init(uint16_t coeff) { // drv_synth_init ожидает параметр в R16:R17 и портит их содержимое register uint16_t Tmp asm("r16"); Tmp = coeff; asm volatile ( " RCALL drv_synth_init\n " :"+r" (Tmp) ); } inline void driver::rrt::send(void const * data, uint8_t size) { // drv_rrt_send ожидает указатель в R30:R31, размер в R16 и портит их содержимое register void const * Src asm("r30"); register uint8_t Size asm("r16"); Src = data; Size = size; asm volatile ( " RCALL drv_rrt_send\n\t" :"+r" (Src), "+r" (Size) ); } Адреса функций прописываются в скрипте линкера drv_serial_no = 0x1832; drv_rrt_send = 0x1838; drv_synth_init = 0x183A; либо в командной строке линкера: LDFLAGS += -Wl,--defsym,drv_serial_no=0x1832 LDFLAGS += -Wl,--defsym,drv_rrt_send=0x1838 LDFLAGS += -Wl,--defsym,drv_synth_init=0x183A Вам надо будет почитать по поводу constrains асмовых вставок, там выбирая '+' '=' и '' можно еще объяснить, что функция не портит входные параметры и тогда компилятор не будет обновлять их при вызове функции в цикле. В общем штука довольно мощная, но надо почитать доку. В комплектк WinAVR это описано в доке на avr-libc в файле с названием чего-то-там-inline-чего-то-там.html А, ну и если функция не требует параметров или параметры передаются в соответствии с принятым в gcc соглашнеии о вызовах, то тогда в заголовочном файле пишем extern void Bootloader(); а в командной строке линкера LDFLAGS += -Wl,--defsym,BootLoader=0x1800