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

 
 
> port definition for IAR C++, компилятор выдает предупреждения
prottoss
сообщение May 27 2006, 14:31
Сообщение #1


Гуру
******

Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659



Всем доброго времени суток!



Для написания программ для AVR всегда пользовал язык С, хотя С++ знаю, но как то применял для МК, на Си было попроще. Сейчас встала необходимость применять С++ ...В принципе, все компилируется и работает, но линкер сыпет предупреждениями типа:



Warning[w35]: There is more than one definition for the struct/union type with tag '__C1'; class/struct/union field names do not match: UCSRA_Bit0 vs DDRC_Bit0
struct __C1 /* Elements: 8, Bytes: 1 */
{
unsigned char UCSRA_Bit0 : 1 /* disp: 0 */;
unsigned char UCSRA_Bit1 : 1 /* disp: 1 */;
unsigned char UCSRA_Bit2 : 1 /* disp: 2 */;
unsigned char UCSRA_Bit3 : 1 /* disp: 3 */;
unsigned char UCSRA_Bit4 : 1 /* disp: 4 */;
unsigned char UCSRA_Bit5 : 1 /* disp: 5 */;
unsigned char UCSRA_Bit6 : 1 /* disp: 6 */;
unsigned char UCSRA_Bit7 : 1 /* disp: 7 */;
};


etc.



Я понимаю так, что определения бит одного порта, используемого мною, перекрывают определения бит другого порта, который я тоже использую в своей программе. Как избавиться от этих предупреждений? Я привык составлять прогрмму так, что бы не было никаких предупреждений)))...

Спасибо.


--------------------
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
prottoss
сообщение May 27 2006, 17:35
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659



реплика не в тему созданную мной, но дабы не занимать пространство форума продолжу сдесь задавать вопросы по Embedded C++ и моих траблах с ним)



в итоге я содал класс:

Код


/*****************************************************************************
Описание класса USART
******************************************************************************/
class clUSART
{
/****************************************************************************/
protected:
   UINT RX_Flags;       // флаги ошибок
    UCHAR RX_Count;       // количество принятых байт в буфере
UCHAR RX_WrIndex;      // индекс для принимаемых в буфер данных
UCHAR RX_RdIndex;      // индекс для читаемых из буфера данных
   UCHAR  RX_Buffer[USART_RX_BUFFER_SIZE];// кольцевой FIFO буфер приемника

public:
void RX_Reset(void);    // сброс буфера приемника
BOOL RX_GetChar(UCHAR *dest);  // получить байт из буфера приемника
UCHAR RX_GetCount(void);   // проверить, если принятые данные
UCHAR RX_GetState(void);   // получить состояние приемника

/****************************************************************************/
protected:
UINT TX_Flags;       // флаги ошибок
    UCHAR TX_Count;       // количество отправляемых байт в буфере
UCHAR TX_WrIndex;      // индекс для принимаемых в буфер данных
UCHAR TX_RdIndex;      // индекс для читаемых из буфера данных
    UCHAR  TX_Buffer[USART_TX_BUFFER_SIZE];// кольцевой FIFO буфер передатчика

public:
void TX_Reset(void);   // сброс буфера передатчика
BOOL TX_PutChar(UCHAR srch); // отправить байт в буфер передатчика
UCHAR TX_GetCount(void);   // проверить, если данные для отправки
    UCHAR TX_GetState(void);   // получить состояние передатчика

/****************************************************************************/
protected:
    UCHAR Timeout;       // счетчик для подсчета таймаутов

public:
   BOOL IsFrameTimeout(void);  // проверить таймаут кадра

/****************************************************************************/
protected:

/****************************************************************************/
public:
   clUSART(void);
    void UDR_Empty(void);
    void RX_Complete(void);
    void TX_Complete(void);
    void TIMER_Timeout(void);
};




В модуле создал глобальную переменную, которую конструктор класса инициализирует адресом класса:



Код
  

/*****************************************************************************
Глобальные переменные
******************************************************************************/
clUSART *g_usart = NULL;


....





/*****************************************************************************
Инциализация USART
******************************************************************************/
clUSART::clUSART(void)
{



     g_usart = this;

....

}






А прерывания использовал так:



Код


/*****************************************************************************
Обработчик опустошения регистра данных передатчика USART UDR
******************************************************************************/
__interrupt void UDR_Empty(void)
{ g_usart->UDR_Empty();
}

void clUSART::UDR_Empty(void)
{

.....

}



// и так все остальные прерывания




В итоге когда я посмотрел листинг то опешил, каждое прерывание сопровождается массовым сохранением в стек регистров, в начале, и таким же массовым в конце, что не есть хорошо на больших скоростях обмена по USART. В принципе я знаю про такой эффект компилятора, но надеялся что когда я перейду на Си++, компилятор "поумнеет". Увы.. Может быть кто занет как решить проблему, или подскажет способ, как внедрить прерывание в класс?


--------------------
Go to the top of the page
 
+Quote Post
defunct
сообщение May 27 2006, 19:07
Сообщение #3


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(prottoss @ May 27 2006, 20:35) *
В итоге когда я посмотрел листинг то опешил, каждое прерывание сопровождается массовым сохранением в стек регистров, в начале, и таким же массовым в конце, что не есть хорошо на больших скоростях обмена по USART. В принципе я знаю про такой эффект компилятора, но надеялся что когда я перейду на Си++, компилятор "поумнеет". Увы.. Может быть кто занет как решить проблему, или подскажет способ, как внедрить прерывание в класс?

Увы и ах, такое поведение характерно не только для AVR Embedded C++, поэтому драйвера обычно пишутся без использования возможностей ООП.

Если посмотреть на это с другой стороны, то 32 байта стека и 128 циклов CPU не такая уж и большая цена за использование возможностей ООП. На 115200 с частотой следования байтов 11.52 Khz накладные расходы составят 13.3% от общей произодительности МК при частоте тактирования 11.059Mhz. Вполне терпимо..

Код
/*****************************************************************************
Глобальные переменные
******************************************************************************/
clUSART *g_usart = NULL;
....


/*****************************************************************************
Обработчик опустошения регистра данных передатчика USART UDR
******************************************************************************/
__interrupt void UDR_Empty(void)
{ g_usart->UDR_Empty();
}


Код у Вас небезопастный, а это плохо..
В обработчике прерывания, обязательно следовало бы добавить:
if (g_usart != NULL) ....

И наверное, коль Вы пишете класс, то вероятно для возможности обслуживания нескольких UART'ов одинаковыми средствами, поэтому глобальным должен быть не один объект, а список объектов, который логично формировать взависимости от, например, наличия аппаратных USART'ов МК (#ifdef UDR0, #ifdef UDR1 и т.п.)..

PS: избежать накладных расходов, на мой взгляд, можно в случае если скомбинировать обработку прерываний средствами inline функций, и постобработку принятых данных в основном цикле программы методами классов. Только такая организация потребует строго определенной структуры программы, что сделает Ваш драйвер менее универсальным, хотя и более эффективным.
Go to the top of the page
 
+Quote Post



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

 


RSS Текстовая версия Сейчас: 22nd July 2025 - 12:35
Рейтинг@Mail.ru


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