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

 
 
> GCC и C++ для Cortex-M3
Pavel V.
сообщение Feb 6 2012, 12:20
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 211
Регистрация: 3-06-06
Пользователь №: 17 742



Пытаюсь собрать следующий код:

CODE
#include "LPC17xx.h"

typedef enum
{
ePort0,
ePort1,
ePort2,
ePort3,
ePort4
} LPCPort;

typedef enum
{
eHigh,
eLow
} LPCActive;

typedef enum
{
eInput,
eOutput
} LPCDirection;

template<LPCPort port, uint8_t pin, LPCActive activestate = eHigh> struct Pin;

template<LPCPort port, uint8_t pin, LPCActive activestate>
struct Pin
{
static const uint32_t mask = 1UL << pin;
LPC_GPIO_TypeDef* GetPointer()
{
return (port == ePort0 ? LPC_GPIO0 :
port == ePort1 ? LPC_GPIO1 :
port == ePort2 ? LPC_GPIO2 :
port == ePort3 ? LPC_GPIO3 :
LPC_GPIO4);
}
void On()
{
activestate == eHigh ?
GetPointer()->FIOSET = mask :
GetPointer()->FIOCLR = mask;
}
void Off()
{
activestate == eHigh ?
GetPointer()->FIOCLR = mask :
GetPointer()->FIOSET = mask;
}
void Mode(LPCDirection dir)
{
dir == eOutput ?
GetPointer()->FIODIR |= mask :
GetPointer()->FIODIR &= ~mask;
}
uint32_t IsActive()
{
uint32_t ret = GetPointer()->FIOPIN & mask;
if (activestate == eHigh)
{
return ret > 0 ? 1 : 0;
}
else
{
return ret > 0 ? 0 : 1;
}
}
};


CODE
class IOutput
{
public:
IOutput()
{
}
virtual ~IOutput()
{
}

virtual void Set(uint32_t state) = 0;
virtual uint32_t Get() = 0;
};

template<LPCPort port, uint8_t pin, LPCActive activestate>
class Output: public Pin<port, pin, activestate> , IOutput
{
public:

Output()
{
_pin.Off();
_pin.Mode(eOutput);
}

virtual ~Output()
{
}

virtual void Set(uint32_t state)
{
state ? _pin.On() : _pin.Off();
}

virtual uint32_t Get()
{
return _pin.IsActive();
}
private:
Pin<port, pin, activestate> _pin;
};


Если собирать вот такой main.cpp:

Код
Pin<ePort4, 29, eHigh> g_testPin;

int main(void)
{
    while (1) {
        g_testPin.On();
        g_testPin.Off();
    }
}


Все ОК, выходной файл 800 байт.

Но если попробовать вот такой main.cpp:

Код
Output<ePort4, 29, eHigh> g_testPin;

int main(void)
{
    while (1) {
        g_testPin.Set(1);
        g_testPin.Set(0);
    }
}


Линкер начинает ругаться:

Код
/opt/arm-kgp-eabi/lib/gcc/arm-kgp-eabi/4.7.0/../../../../arm-kgp-eabi/lib/thumb/cortex-m3/libc.a(lib_a-abort.o): In function `abort':
abort.c:(.text.abort+0xa): undefined reference to `_exit'
/opt/arm-kgp-eabi/lib/gcc/arm-kgp-eabi/4.7.0/../../../../arm-kgp-eabi/lib/thumb/cortex-m3/libc.a(lib_a-sbrkr.o): In function `_sbrk_r':
sbrkr.c:(.text._sbrk_r+0xc): undefined reference to `_sbrk'
/opt/arm-kgp-eabi/lib/gcc/arm-kgp-eabi/4.7.0/../../../../arm-kgp-eabi/lib/thumb/cortex-m3/libc.a(lib_a-signalr.o): In function `_kill_r':
signalr.c:(.text._kill_r+0xe): undefined reference to `_kill'
/opt/arm-kgp-eabi/lib/gcc/arm-kgp-eabi/4.7.0/../../../../arm-kgp-eabi/lib/thumb/cortex-m3/libc.a(lib_a-signalr.o): In function `_getpid_r':
signalr.c:(.text._getpid_r+0x0): undefined reference to `_getpid'
/opt/arm-kgp-eabi/lib/gcc/arm-kgp-eabi/4.7.0/../../../../arm-kgp-eabi/lib/thumb/cortex-m3/libc.a(lib_a-writer.o): In function `_write_r':
writer.c:(.text._write_r+0x10): undefined reference to `_write'
/opt/arm-kgp-eabi/lib/gcc/arm-kgp-eabi/4.7.0/../../../../arm-kgp-eabi/lib/thumb/cortex-m3/libc.a(lib_a-closer.o): In function `_close_r':
closer.c:(.text._close_r+0xc): undefined reference to `_close'
/opt/arm-kgp-eabi/lib/gcc/arm-kgp-eabi/4.7.0/../../../../arm-kgp-eabi/lib/thumb/cortex-m3/libc.a(lib_a-fstatr.o): In function `_fstat_r':
fstatr.c:(.text._fstat_r+0xe): undefined reference to `_fstat'
/opt/arm-kgp-eabi/lib/gcc/arm-kgp-eabi/4.7.0/../../../../arm-kgp-eabi/lib/thumb/cortex-m3/libc.a(lib_a-isattyr.o): In function `_isatty_r':
isattyr.c:(.text._isatty_r+0xc): undefined reference to `_isatty'
/opt/arm-kgp-eabi/lib/gcc/arm-kgp-eabi/4.7.0/../../../../arm-kgp-eabi/lib/thumb/cortex-m3/libc.a(lib_a-lseekr.o): In function `_lseek_r':
lseekr.c:(.text._lseek_r+0x10): undefined reference to `_lseek'
/opt/arm-kgp-eabi/lib/gcc/arm-kgp-eabi/4.7.0/../../../../arm-kgp-eabi/lib/thumb/cortex-m3/libc.a(lib_a-readr.o): In function `_read_r':
readr.c:(.text._read_r+0x10): undefined reference to `_read'
collect2: error: ld returned 1 exit status
make: *** [Test2.elf] Error 1


Пытался подсунуть заглушки системных функций, тогда собирается, но размер выходного файла больше 40 Кб sm.gif

Если для класса Output убрать наследование от абстрактного класса IOutput, линкер требует только функцию _sbrk, хотя тоже непонятно почему, ведь в программе нигде не используется динамическое выделение памяти..

Тулчейны пробовал разные - эффект сохраняется.

Ключи компиляции и сборки:

Код
Оптимизация -O2

# GCC
GCFLAGS = -O$(OPTIMIZATION) -gdwarf-2 -mcpu=cortex-m3 -mthumb -mthumb-interwork -mlong-calls -ffunction-sections -fdata-sections -Wall -Wextra --std=gnu99 -DTNKERNEL_PORT_CORTEXM3
GCFLAGS += $(patsubst %,-I%,$(INCDIRS)) -I.

# G++
GPFLAGS = -O$(OPTIMIZATION) -gdwarf-2 -mcpu=cortex-m3 -mthumb -mthumb-interwork -mlong-calls -ffunction-sections -fdata-sections -Wall -Wextra -fno-rtti -fno-exceptions -DTNKERNEL_PORT_CORTEXM3
GPFLAGS += $(patsubst %,-I%,$(INCDIRS)) -I.

# Assembler
ASFLAGS = $(LISTING) -mcpu=cortex-m3 -mthumb -x assembler-with-cpp
ASFLAGS += $(patsubst %,-I%,$(INCDIRS)) -I.

# Linker
LDFLAGS = -T$(LSCRIPT) -mcpu=cortex-m3 -mthumb -O$(OPTIMIZATION) -Wl,-Map=$(PROJECT).map,--cref -nostartfiles -fno-exceptions -fno-rtti -Wl,--gc-sections


Что я неправильно делаю? smile3046.gif

Сообщение отредактировал IgorKossak - Feb 6 2012, 19:48
Причина редактирования: [codebox]


--------------------
Good News Everyone!
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Brain13
сообщение Jan 16 2013, 06:50
Сообщение #2


Участник
*

Группа: Участник
Сообщений: 65
Регистрация: 28-08-09
Пользователь №: 52 078



Чтобы не плодить новые темы пишу здесь.

Здравствуйте.

Решил попробовать использовать полиморфизм в МК.
написал такой код:
CODE

// IOutDevice.h
class IOutDevice
{
public:
virtual void On(void) = 0;
virtual void Off(void) = 0;
};

// PC0LED.h
class PC0_LED : public IOutDevice
{
public:
PC0_LED();

virtual void On(void);
virtual void Off(void);
};

// PC0LED.cpp
PC0_LED::PC0_LED()
{
}

void PC0_LED::On()
{
GPIO_PinOutSet(gpioPortC, 0);
}

void PC0_LED::Off()
{
GPIO_PinOutClear(gpioPortC, 0);
}

// PC1LED.h
class PC1_LED : public IOutDevice
{
public:
PC1_LED();

virtual void On(void);
virtual void Off(void);
};

// PC1LED.cpp
PC1_LED::PC1_LED()
{
}

void PC1_LED::On()
{
GPIO_PinOutSet(gpioPortC, 1);
}

void PC1_LED::Off()
{
GPIO_PinOutClear(gpioPortC, 1);
}


// main.cpp
int main(void)
{
init();

PC0_LED pc0;
PC1_LED pc1;

IOutDevice*dev[2];
dev[0] = &pc0;
dev[1] = &pc1;


while (1)
{
dev[0]->On();
dev[1]->On();
delay(2000000);

dev[0]->Off();
dev[1]->Off();
delay(2000000);
}

}

// Интерфейс IOutDevice, и 2 класса его реализующих для PC0 и PC1.

Все время думал, что для абстрактных методов необходим rtti. И компилировал без опции -fno-rtti (размер программы 10456). В этом топике увидел, что работает и с опцией -fno-rtti, попробовал - раотает (размер программы 2228).

Вопрос: почему код успешно компилируется с опцией -fno-rtti без ошибок? Разве для использования абстрактных методов не нужен rtti?
Go to the top of the page
 
+Quote Post
dxp
сообщение Jan 16 2013, 08:37
Сообщение #3


Adept
******

Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343



QUOTE (Brain13 @ Jan 16 2013, 13:50) *
Все время думал, что для абстрактных методов необходим rtti. И компилировал без опции -fno-rtti (размер программы 10456). В этом топике увидел, что работает и с опцией -fno-rtti, попробовал - раотает (размер программы 2228).

Вопрос: почему код успешно компилируется с опцией -fno-rtti без ошибок? Разве для использования абстрактных методов не нужен rtti?

1. Что такое абстрактные методы?

2. RTTI - Run-Time Type Identification - определение типа на этапе выполнения. Причём тут полиморфизм, который требует просто наследования и виртуальных функций, механизм реализации которых - это таблицы указателей на функции? Для полиморфизма не требуется никакая информация о типах на этапе выполнения.

RTTI потребуется, если будете использовать dynamic_cast<>.


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
Brain13
сообщение Jan 18 2013, 05:48
Сообщение #4


Участник
*

Группа: Участник
Сообщений: 65
Регистрация: 28-08-09
Пользователь №: 52 078



Цитата(dxp @ Jan 16 2013, 11:37) *
1. Что такое абстрактные методы?

Абстрактный метод = виртуальный метод без реализации.

Цитата(dxp @ Jan 16 2013, 11:37) *
2. RTTI - Run-Time Type Identification - определение типа на этапе выполнения. Причём тут полиморфизм, который требует просто наследования и виртуальных функций, механизм реализации которых - это таблицы указателей на функции? Для полиморфизма не требуется никакая информация о типах на этапе выполнения.

RTTI потребуется, если будете использовать dynamic_cast<>.


Хммм... а я думал что, для вызова виртуальных методов необходимо вначале узнать реальный тип объекта, а лишь затем вызвать его переопределенный метод. Я считал, что определением реального типа объекта и занимается rtti. Походу я чего-то не понимаю.

Вот в вике написано о виртуальных методах:
Цитата(http://ru.wikipedia.org/wiki/%D0%92%D0%B8%D1%80%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B9_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4)
То есть, в случае виртуальной функции, для определения реализации функции используется информация о типе объекта и вызывается «правильная» реализация, независимо от типа указателя. При вызове невиртуальной функции, компилятор руководствуется типом указателя или ссылки, поэтому вызываются две разные реализации function2(), несмотря на то, что используется один и тот же объект.

Так получается что инфа о типе не используется, а используется таблица указателей на виртуальные функции (vtbl)?

А что тогда делает rtti, и зачем нужен dynamic_cast<>? Можно примерчик?
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- Pavel V.   GCC и C++ для Cortex-M3   Feb 6 2012, 12:20
- - neiver   Деструкторы надо выкинуть, они всё равно никогда н...   Feb 6 2012, 14:33
|- - Pavel V.   Цитата(neiver @ Feb 6 2012, 18:33) Дестру...   Feb 6 2012, 15:43
|- - AHTOXA   Это только до тех пор, пока вы не используете Get(...   Feb 6 2012, 18:01
|- - Pavel V.   Цитата(AHTOXA @ Feb 6 2012, 22:01) Это то...   Feb 7 2012, 05:51
|- - AHTOXA   Цитата(Pavel V. @ Feb 7 2012, 11:51) Убра...   Feb 7 2012, 08:10
|- - Pavel V.   Цитата(AHTOXA @ Feb 7 2012, 12:10) Ух ты,...   Feb 7 2012, 09:38
- - alx2   Цитата(Pavel V. @ Feb 6 2012, 17:20) Если...   Feb 7 2012, 05:25
- - neiver   Да, кстати, а зачем делать абстрактные интерфейсы ...   Feb 7 2012, 09:45
|- - ReAl   Цитата(neiver @ Feb 7 2012, 11:45) Еще мн...   Feb 7 2012, 11:21
|- - Pavel V.   neiver Спасибо за ссылки, буду изучать По коду не...   Feb 7 2012, 12:39
- - Pavel V.   Кстати, заметил еще одну особенность - при уровне ...   Feb 9 2012, 07:00
- - Сергей Борщ   QUOTE (Brain13 @ Jan 16 2013, 08:50) Разв...   Jan 16 2013, 08:22
- - dxp   QUOTE (Brain13 @ Jan 18 2013, 12:48) Абст...   Jan 18 2013, 12:01


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

 


RSS Текстовая версия Сейчас: 20th July 2025 - 03:07
Рейтинг@Mail.ru


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