реклама на сайте
подробности

 
 
> Что линковщику не понятно
Sirko
сообщение Apr 23 2011, 21:32
Сообщение #1


Местный
***

Группа: Участник
Сообщений: 245
Регистрация: 15-08-07
Пользователь №: 29 795



Пишу на СИ, компилятор - WinAVR-20100110, Makefile - студийный.
Необходимо реализовать исходник, работающий на Меге128 и на Меге8515
У Мега8515 есть отличие - при использовании UART приходится дергать разряд URSEL.
Поэтому я решил при помощи препроцессора подставлять разную реализацию при компиляции, но...
Цитата
Build started 24.4.2011 at 00:26:16
avr-gcc -mmcu=atmega128 -Wl,-Map=AVR_Bootloader.map main.o Signal_UART.o -o AVR_Bootloader.elf
Signal_UART.o: In function `UART_WRITE_CTRL2':
D:\_Projects\AVR_Bootloader\default/../BootConfig.h:138: multiple definition of `UART_WRITE_CTRL2'
main.o:D:\_Projects\AVR_Bootloader\default/../BootConfig.h:138: first defined here
Signal_UART.o: In function `UART_READ_CTRL2':
D:\_Projects\AVR_Bootloader\default/../BootConfig.h:139: multiple definition of `UART_READ_CTRL2'
main.o:D:\_Projects\AVR_Bootloader\default/../BootConfig.h:139: first defined here
make: *** [AVR_Bootloader.elf] Error 1
Build failed with 1 errors and 0 warnings...

Если эти эти функции реализовать как макрос - ошибок нет. Но я не представляю, как реализовать UART_READ_CTRL2() для Меги8515.

Код
#if defined(    __AVR_ATmega128__)        \
    || defined(    __AVR_ATmega64__)

    #ifndef UART_USE_SECOND
        #define UART_BAUD_HIGH        UBRR0H
        #define UART_BAUD_LOW        UBRR0L
        #define UART_STATUS            UCSR0A
        #define UART_CTRL                UCSR0B
        #define UART_CTRL2            UCSR0C
        #define UART_DATA                UDR0
        .
        .
        .
    #else
        #define UART_BAUD_HIGH        UBRR1H
        #define UART_BAUD_LOW        UBRR1L
        #define UART_STATUS            UCSR1A
        #define UART_CTRL                UCSR1B
        #define UART_CTRL2            UCSR1C
        #define UART_DATA                UDR1
        .
        .
        .
    #endif
    volatile void    UART_WRITE_CTRL2(u08 data){UART_CTRL2 = data; return;}
    volatile u08    UART_READ_CTRL2(void){return UART_CTRL2;}

#elif defined(    __AVR_ATmega8__)            \
    || defined(    __AVR_ATmega8515__)

    #define UART_BAUD_HIGH        UBRRH
    #define UART_BAUD_LOW        UBRRL
    #define UART_URSEL            URSEL
    #define UART_CTRL2            UCSRC
    volatile void    UART_WRITE_CTRL2(u08 data){UART_CTRL2 = data | _BV(UART_URSEL); return;}
    volatile u08    UART_READ_CTRL2(void){u08 tmp=UART_BAUD_HIGH; tmp=UART_URSEL; return tmp;}


#else
#error "Unknown"
#endif


help.gif
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов (1 - 3)
Kolia
сообщение Apr 24 2011, 08:34
Сообщение #2


Частый гость
**

Группа: Свой
Сообщений: 188
Регистрация: 28-09-06
Из: Minsk
Пользователь №: 20 762



volatile void UART_WRITE_CTRL2(u08 data){UART_CTRL2 = data; return;}
volatile u08 UART_READ_CTRL2(void){return UART_CTRL2;}

Эти функции следует описывать в файле "C"

В файле "H" соответственно


volatile void UART_WRITE_CTRL2(u08 data);
volatile u08 UART_READ_CTRL2(void);
Go to the top of the page
 
+Quote Post
Sirko
сообщение Apr 24 2011, 14:21
Сообщение #3


Местный
***

Группа: Участник
Сообщений: 245
Регистрация: 15-08-07
Пользователь №: 29 795



Прототипы - это все, конечно, хорошо.
Только вот их реализация будет разная - для разных процов.
Т.е. в СИ-файле придется делать директивами те же самые действия, что и в Н-файле.
Неуж-то нет более красивого решения!

На данный момент, вместо функции
Код
volatile u08 UART_READ_CTRL2(void){u08 tmp=UART_BAUD_HIGH; tmp=UART_URSEL; return tmp;}

я использую макрос
Код
#define UART_READ_CTRL2(reg) do{u08 tmp=UART_BAUD_HIGH; reg=UART_URSEL;}while(0)

но и это, мне кажется, не самый красивый вариант.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Apr 26 2011, 09:47
Сообщение #4


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



QUOTE (Sirko @ Apr 24 2011, 17:21) *
На данный момент, вместо функции
CODE
volatile u08 UART_READ_CTRL2(void){u08 tmp=UART_BAUD_HIGH; tmp=UART_URSEL; return tmp;}

я использую макрос
CODE
#define UART_READ_CTRL2(reg) do{u08 tmp=UART_BAUD_HIGH; reg=UART_URSEL;}while(0)

но и это, мне кажется, не самый красивый вариант.
Если функция из одной команды или вызывается один раз, то можно сделать ее inline. Если компилятор не поддерживает inline (к avr-gcc это не относится), или требуется портируемый исходник, то можно функцию в заголовочном файле объявить как static.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 27th June 2025 - 22:34
Рейтинг@Mail.ru


Страница сгенерированна за 0.01423 секунд с 7
ELECTRONIX ©2004-2016