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

 
 
 
Reply to this topicStart new topic
> WinAVR 20071221 Warning
swisst
сообщение Dec 31 2008, 10:07
Сообщение #1


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

Группа: Свой
Сообщений: 163
Регистрация: 16-02-07
Из: Харьков
Пользователь №: 25 425



Доброго дня !

Есть 3 вопроса, на которые я самостоятельно не смог найти ответ - решил обратится за помощью:

1. Ругается варнингом:
Код
In function 'Load_Default_Parametrs' passing argument 1 of 'eeprom_write_block' discards qualifiers from pointer target type

на эту строку :
Код
eeprom_write_block((void*)&Parametrs_Ram, (void*) 0x01, sizeof(Parametrs_Ram));


что касается первого аргумента Parametrs_Ram:

Код
volatile Params_Struct Parametrs_Ram;       //объявление

typedef struct{                                           //переопределение типа

    unsigned char Ind_Period;
    unsigned char Querry_Tout;
    unsigned char RS_Address;
    unsigned char RS_Speed;
    unsigned int CRC;
}Params_Struct;


как только убираю модификатор volatile из объявления Parametrs_Ram - варнинги уходят, но мне нужна Parametrs_Ram именно как volatile.
Явное приведение в функции eeprom_write_block к какому-либо типу ни к чему не приводит.

Боротся с варнингами или пустить на самотек ? Если бороться, то что я делаю не так ?

2. Вопрос по inline-функции. Как правильно объявить, определить, вызвать ?
Делаю так:

Прототип: void func ();
Определение: inline void func (){...код...}
Вызов: void func ();

Ругается так:
warning: C99 inline functions are not supported; using GNU89 to disable this warning use -fgnu89-inline or the gnu_inline function attribute

Добавление в опциях проекта -fgnu89-inline варнинг не отключило.

3. То, что меня убило наповал... Есть проект, есть 2 машины на которых установлены одинаковые версии AVR Studio и WinAVR20071221. На десктопе все ок. В процессе разработки проекта ничего сверхъестественного не было. Копирую проект на ноут, компилирую - размер кода +700 байт, +256 байт озу. Вот эта магическая строчка из map-файла:
Код
.data          0x00800060      0x100 c:/winavr-20071221/bin/../lib/gcc/avr/4.2.2/avr5\libgcc.a(_clz.o)
                 0x00800060                __clz_tab


с __clz_tab дело уже имел (тему старую не смого найти, к сожалению) - тогда подключал математическую библиотеку libm.a и как рукой снимало. На этот раз - на ноуте не помогает. Настройки проекта естественно не меняю...библиотеки подключаю те же, что и на десктопе...
Также осознаю, что звучит это как-то глупо, но я в ступоре...
Устанавливал последнюю версию WinAVR20081205 - проблем с __clz_tab нет. Объём кода при компиляции отличается на 6 байт (на ноуте больше)...
Go to the top of the page
 
+Quote Post
xelax
сообщение Dec 31 2008, 11:10
Сообщение #2


Местный
***

Группа: Свой
Сообщений: 370
Регистрация: 7-11-06
Пользователь №: 22 035



Цитата(swisst @ Dec 31 2008, 13:07) *
Доброго дня !

Есть 3 вопроса, на которые я самостоятельно не смог найти ответ - решил обратится за помощью:

1. Ругается варнингом:
Код
In function 'Load_Default_Parametrs' passing argument 1 of 'eeprom_write_block' discards qualifiers from pointer target type

на эту строку :
Код
eeprom_write_block((void*)&Parametrs_Ram, (void*) 0x01, sizeof(Parametrs_Ram));


Боротся с варнингами или пустить на самотек ? Если бороться, то что я делаю не так ?


Хотелось бы так же видеть прототип функции. Какой тип первого передаваемого аргумента. А вообще char и volatile char это не одно и тоже для компилятора.

Я по возможности стараюсь все ворнинги убивать, как потенциальные места глюков.

Цитата(swisst @ Dec 31 2008, 13:07) *
2. Вопрос по inline-функции. Как правильно объявить, определить, вызвать ?
Делаю так:

Прототип: void func ();
Определение: inline void func (){...код...}
Вызов: void func ();

Ругается так:
warning: C99 inline functions are not supported; using GNU89 to disable this warning use -fgnu89-inline or the gnu_inline function attribute

Добавление в опциях проекта -fgnu89-inline варнинг не отключило.


Типичные грабли на которые сам наступал пару раз. Модификатор inline должен быть в объявлении функции, а не в описании.

Код
inline void f(void);

int main()
{

f();

return 0;
}

void f(void)
{
while(1){;}
}


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

Чтобы такого избегать реализую встроенные функции в хидере, либо если архитектура ПО не позволяет, то добавляю спецатрибуты компилятор, которые гарантируют встроенность функции.

Цитата(swisst @ Dec 31 2008, 13:07) *
3. То, что меня убило наповал... Есть проект, есть 2 машины на которых установлены одинаковые версии AVR Studio и WinAVR20071221. На десктопе все ок. В процессе разработки проекта ничего сверхъестественного не было. Копирую проект на ноут, компилирую - размер кода +700 байт, +256 байт озу. Вот эта магическая строчка из map-файла:
Код
.data          0x00800060      0x100 c:/winavr-20071221/bin/../lib/gcc/avr/4.2.2/avr5\libgcc.a(_clz.o)
                 0x00800060                __clz_tab


с __clz_tab дело уже имел (тему старую не смого найти, к сожалению) - тогда подключал математическую библиотеку libm.a и как рукой снимало. На этот раз - на ноуте не помогает. Настройки проекта естественно не меняю...библиотеки подключаю те же, что и на десктопе...
Также осознаю, что звучит это как-то глупо, но я в ступоре...
Устанавливал последнюю версию WinAVR20081205 - проблем с __clz_tab нет. Объём кода при компиляции отличается на 6 байт (на ноуте больше)...


Что-то не так в этом королевстве. Одинаковый код собранный одинаковыми компиляторами должен давать одинаковый результат.
Могу сказать одно, что например наш проект собираемый на разных писишках, и под винду и под линуха даёт строго один и тот же показатель и по памяти данный и по памяти кода и по поведению на железе. Сначала были разночтения, но как оказалось на практике дело было в самосборном компиляторе на линухе, после установки патчей от винавра, всё стало полностью идентичным.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Dec 31 2008, 12:40
Сообщение #3


Гуру
******

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



Цитата(swisst @ Dec 31 2008, 12:07) *
Вызов: void func ();
Это не вызов - это объявление вложенной (локальной) функции. Вызов будет func();


--------------------
На любой вопрос даю любой ответ
"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
swisst
сообщение Dec 31 2008, 12:44
Сообщение #4


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

Группа: Свой
Сообщений: 163
Регистрация: 16-02-07
Из: Харьков
Пользователь №: 25 425



Цитата(Сергей Борщ @ Dec 31 2008, 14:40) *
Это не вызов - это объявление вложенной (локальной) функции. Вызов будет func();


да описка имела место. Вы правы, так и вызываю func();.


inline-функция может быть только статична или нет ? дело в том, что я вызываю эту функцию в обработчике прерывания...можно,конечно, просто вставить код, но это не рационально...как по мне...
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Jan 2 2009, 10:05
Сообщение #5


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(swisst @ Dec 31 2008, 15:44) *
inline-функция может быть только статична или нет ? дело в том, что я вызываю эту функцию в обработчике прерывания...можно,конечно, просто вставить код, но это не рационально...как по мне...
Если она будет не static, то с большой долей вероятности у Вас будет несколько копий этой функции. Одна оригинал, а вторая во встроенном виде как inline. Только static позволяет компилятору поступать более рационально. Иначе нет гарантии того, что ни в одном другом модуле не происходит ни вызов этой функции ни взятие её адреса... Посмотрите еще на: __attribute__((always_inline))


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
swisst
сообщение Jan 10 2009, 13:06
Сообщение #6


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

Группа: Свой
Сообщений: 163
Регистрация: 16-02-07
Из: Харьков
Пользователь №: 25 425



Цитата(demiurg_spb @ Jan 2 2009, 12:05) *
Если она будет не static, то с большой долей вероятности у Вас будет несколько копий этой функции. Одна оригинал, а вторая во встроенном виде как inline.


Именно этого я и пытаюсь добиться. Функция определена в одном модуле. Вызывается в 3-х местах (одно из которых - обработчик прерывания). И лишь в обработчике прерывания я хочу, чтобы она была inline, а в остальных местах вызывалась.

Цитата(demiurg_spb @ Jan 2 2009, 12:05) *
Посмотрите еще на: __attribute__((always_inline))


Почитал, посмотрел примеры, попробовал - работает...но в связке с квалификатором static.


Хотелось бы услышать комментарии пользователей WinAVR20071221 по поводу первого вопроса и использования функции eepro_write_block ()

прототип функции:
Код
static inline void __attribute__ ((always_inline))
eeprom_write_block (const void *pointer_ram,
                               void *pointer_eeprom,
                               size_t size);
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Jan 11 2009, 16:15
Сообщение #7


;
******

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



Цитата(swisst @ Jan 10 2009, 17:06) *
 И лишь в обработчике прерывания я хочу, чтобы она была inline, а в остальных местах вызывалась.

Заверните ее в другую, не  инлайн , функцию. Будете уверены, что в ISR вызвался тот, что надо.
Go to the top of the page
 
+Quote Post

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

 


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


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