|
WinAVR-20080610, делимся впечатлениями |
|
|
|
Jun 24 2008, 03:57
|

Познающий...
     
Группа: Свой
Сообщений: 2 963
Регистрация: 1-09-05
Из: г. Иркутск
Пользователь №: 8 125

|
Скачал. Установил. Приятно удивил результат. Проект скомпилированный на WinAVR-20070525 занимает 6452 байт. Работает. Проект скомпилированный новым компиляторм занимает 5396 байт. Полностью не работает. Детальный анализ пока не проводил. Серьезных багов не видел. makefile используется один и тот же, только пути разные подставляются для вызова разных версий утилит. Самое интересное, что при очистке проекта Код make clean вылетает такая ошибка Код 0 [main] rm 3292 handle_exceptions: Exception: STATUS_ACCESS_VIOLATION 111988 [main] rm 3292 open_stackdumpfile: Dumping stack trace to rm.exe.stackdump make.exe: *** [clean] Error -1073741819 Компилирует на первый взгляд нормально, но при заливке кода в МК ничего не работает. Вот... P.S. Версия WinAVR-20071221 полет нормальный. Только очистка вылетает с такой же ошибкой. Свои makefile прикрепляю на всякий случай. Они абсолютно одинаковы, за исключением путей к утилитам пакетов WinAVR.
--------------------
Выбор.
|
|
|
|
|
 |
Ответов
(1 - 90)
|
Jun 24 2008, 08:48
|
Местный
  
Группа: Свой
Сообщений: 466
Регистрация: 21-06-05
Пользователь №: 6 205

|
Цитата(haker_fox @ Jun 24 2008, 06:57)  ..... Самое интересное, что при очистке проекта Код make clean вылетает такая ошибка ..... У меня та же самая проблема, но только я поставил WinAVR-20071221, а до этого стоял(и продолжает стоять) WinAVR-20070525. Причем в том же месте где лежит makefile создается еще rm.exe.stackdump. Так что видимо проблема не в новом релизе
|
|
|
|
|
Jun 25 2008, 01:40
|

Познающий...
     
Группа: Свой
Сообщений: 2 963
Регистрация: 1-09-05
Из: г. Иркутск
Пользователь №: 8 125

|
Цитата(733259 @ Jun 24 2008, 16:56)  По сравнению с 3.4.6 по прежнему проигрывает.
ЗЫ Залил одну прошивку, все работает. Хм. В чем же дело у меня? Видимо придется листинги смотреть, но времени пока нет. Проект хоть не горит, но делать надо... Цитата(kurtis @ Jun 24 2008, 17:48)  У меня та же самая проблема, но только я поставил WinAVR-20071221, а до этого стоял(и продолжает стоять) WinAVR-20070525. Причем в том же месте где лежит makefile создается еще rm.exe.stackdump. Так что видимо проблема не в новом релизе Странно,что проблема не устраняется уже полгода. Может быть такая ошибка возникает, если стоят предыдущие версии? Но вроде не должно...
--------------------
Выбор.
|
|
|
|
|
Jun 25 2008, 03:53
|
Местный
  
Группа: Участник
Сообщений: 290
Регистрация: 9-12-05
Из: г. Пермь
Пользователь №: 12 002

|
Цитата(haker_fox @ Jun 24 2008, 08:57)  Полностью не работает. Разобраться бы почему. У меня тоже проекты все на winavr-20070525 писаны, при переходе на новые версии начинаются глюки. Есть подозрение , что дело в оптимизации.
Сообщение отредактировал viakon - Jun 25 2008, 03:54
|
|
|
|
|
Jun 25 2008, 04:54
|

Познающий...
     
Группа: Свой
Сообщений: 2 963
Регистрация: 1-09-05
Из: г. Иркутск
Пользователь №: 8 125

|
Цитата(733259 @ Jun 25 2008, 13:33)  ИМХО это уже не раз обсуждалось, в четверке новые методы оптимизации, в том числе - "GCC can now do a form of partial dead code elimination (PDCE) that allows code motion of expressions to the paths where the result of the expression is actually needed. This is not always a win, so the pass has been limited to only consider profitable cases." Выкидывает код, может где volatile не хватает, может глюки.
ИМХО на четверку для AVR вооще нет смысла переходить, прошивка всегда больше, скорость меньше. Был бы рад узнать, что не так. Сейчас проверил, что даже при отключенной оптимизации не работает код. На данный момент стабильно работают версии WinAVR-20070525, WinAVR-20071221. Последняя генерит код байт на 300 меньше. Программа, написанная мной, активно использует классы, наследование и т.д. Может быть это является камнем предкновения? Обычный Си код не проверял.
--------------------
Выбор.
|
|
|
|
|
Jun 25 2008, 05:30
|

Познающий...
     
Группа: Свой
Сообщений: 2 963
Регистрация: 1-09-05
Из: г. Иркутск
Пользователь №: 8 125

|
Цитата(733259 @ Jun 25 2008, 13:33)  ИМХО это уже не раз обсуждалось, в четверке новые методы оптимизации Прошу пролщения, а о какой четверке идет речь? Эти три версии все 4.x.x Четверки во второй цифре версии вообще нет. PS Могу полностью выложить свой проект. Коммерческой тайны пока не представляет, но очень громоздок. Может быть это поможет улучшить компилятор или мои мозги) Проект заточен для управления движком. Но его достаточно зашить в МК. При сбросе в UART на скорости 19200 выведется строка Код [Motor Controller "FREESTYLE-1", v. 0.01] Еслит компилировать новой версией, то сразу при сбросе выводится вот прмерно такой мусор Код ’¤2±Щ?a¤a?aА’¬;±a?aИaРaА"—ю”Г-A5NE?” ”C- ”‘‘y‘o‘_‘O‘?‘/‘ѕ•’’¶’$/”?”O” _”o”””Ÿ”Ї”?”i”y”?”П”I·Ю· a’a”¦П‘?‘y‘i‘?‘Ї‘Ÿ‘‘y‘o‘_‘O‘?‘/‘ѕ•’’¶’$/”?”O”_”o”””Ÿ”Ї”?”i”y”?”П”I·Ю·ˆ‘† ?ˆ”†ˆ‘‡?ˆ”‡ˆ‘?ˆ” a’a”?П‘?‘y‘i‘?‘Ї‘Ÿ‘‘y‘o‘_‘O‘?‘/‘
--------------------
Выбор.
|
|
|
|
|
Jun 25 2008, 05:41
|
Знающий
   
Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484

|
Цитата(viakon @ Jun 25 2008, 09:29)  А пользую только С никаких С++, так что дело вряд ли в этом. ставил я апрельскую версию этого года, один проект частично заработал когда на переменные volatile поставил, но полностью это не помогло. Склоняюсь, что дело в оптимизаторе, надо понять что ему не нравится. Разбираться некогда, вернул старую версию. Все сборки WinAVR 2008 года (с avr-gcc 4.3) до майской могут не сохранять используемые регистры в обработчиках прерываний. Анатолий.
|
|
|
|
|
Jun 25 2008, 05:43
|
Местный
  
Группа: Участник
Сообщений: 290
Регистрация: 9-12-05
Из: г. Пермь
Пользователь №: 12 002

|
интересно, и уменя проблемы c UART были. Работал c GPRS модемом и все команды ответы выводились на консоль. С новой версией при инициализации с какойто команды начинал валиться мусор. А часть проходила нормально. Цитата(aesok @ Jun 25 2008, 10:41)  Все сборки WinAVR 2008 года (с avr-gcc 4.3) до майской могут не сохранять используемые регистры в обработчиках прерываний.
Анатолий. Читал про это. Пробовал я и майскую, тоже самое  Недогадался попробовать оптимизацию выключить.
Сообщение отредактировал viakon - Jun 25 2008, 05:45
|
|
|
|
|
Jun 25 2008, 05:50
|

Познающий...
     
Группа: Свой
Сообщений: 2 963
Регистрация: 1-09-05
Из: г. Иркутск
Пользователь №: 8 125

|
Цитата(viakon @ Jun 25 2008, 14:43)  интересно, и уменя проблемы c UART были. Работал c GPRS модемом и все команды ответы выводились на консоль. С новой версией при инициализации с какойто команды начинал валиться мусор. А часть проходила нормально. Читал про это. Пробовал я и майскую, тоже самое  Недогадался попробовать оптимизацию выключить. C UART просто более наглядно наверное + прерывания используются. Если без них, то может проблем и не будет. Хотя кроме юартовских есть несколько других прерываний. Вот еще что интересно, разительно отличаются секции data по размеру. Код 20071221 text data bss dec hex filename 6312 0 152 6464 1940 mcontrol.out
20080610 text data bss dec hex filename 5918 452 152 6522 197a mcontrol.out
--------------------
Выбор.
|
|
|
|
|
Jun 25 2008, 06:00
|
Местный
  
Группа: Участник
Сообщений: 205
Регистрация: 8-03-05
Пользователь №: 3 146

|
Цитата Прошу пролщения, а о какой четверке идет речь? Эти три версии все 4.x.x Четверки во второй цифре версии вообще нет. Виноват, не слежу за 200xxxxx. Обычно сравниваю с 3.4.6 и вижу только недостатки и сырость. Речь конечно шла о первой цифре.
|
|
|
|
|
Jun 27 2008, 08:43
|
Группа: Участник
Сообщений: 13
Регистрация: 23-10-04
Пользователь №: 968

|
Цитата(viakon @ Jun 27 2008, 11:29)  Новый проект откомпилил на SUBJ работает. Только он на 100 байт больше оказался чем 20070525 Попробуйте ключик --param inline-call-cost, если вам важен размер. Например, "--param inline-call-cost=0" см. http://electronix.ru/forum/index.php?s=&am...st&p=393595
|
|
|
|
|
Jun 28 2008, 18:55
|
Знающий
   
Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484

|
Цитата(kurtis @ Jun 28 2008, 22:50)  Заметил что компилятор все символьные строки запихнул в ОЗУ, хотя они объявлены как prog_char, и из-за этого и фигня на ЖКИ влезла...в более ранних версиях GCC (4.2.2) такого небыло. Тестовый пример пожалуйста приведите. Анатолий.
|
|
|
|
|
Jun 30 2008, 03:59
|
Местный
  
Группа: Участник
Сообщений: 290
Регистрация: 9-12-05
Из: г. Пермь
Пользователь №: 12 002

|
Цитата(kurtis @ Jun 28 2008, 23:50)  Заметил что компилятор все символьные строки запихнул в ОЗУ У меня все нормально, лежат во флеш. Подпрограмма вызываемая 1 раз подставлена инлайн соответственно получилось 2 копии. Из-за этого и длина больше. попробую ключик --param inline-call-cost
|
|
|
|
|
Jun 30 2008, 09:21
|
Знающий
   
Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484

|
Цитата(viakon @ Jun 30 2008, 07:59)  Подпрограмма вызываемая 1 раз подставлена инлайн соответственно получилось 2 копии. Из-за этого и длина больше. попробую ключик --param inline-call-cost Лучше объявите эту функцию как static. Анатолий.
Сообщение отредактировал aesok - Jun 30 2008, 09:21
|
|
|
|
|
Jun 30 2008, 09:32
|

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

|
Цитата(aesok @ Jun 30 2008, 12:21)  Лучше объявите эту функцию как static. или --ffunction-sections, -Wl,--gc-sections. Ведь часто исходник кочует из проекта в проект, в каком-то используются одни функции, в каком-то другие, или написали функцию, попользовали ее в другом файле, потом в процессе эволюции необходимость в функции пропала. Если линкер может выкинуть неиспользуемый код - пусть он это делает.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Jun 30 2008, 18:03
|
Группа: Новичок
Сообщений: 5
Регистрация: 30-06-08
Пользователь №: 38 657

|
Здравствуйте уважаемые форумчане! У меня проблемка нарисовалась с поддержкой ядер AVR с размером памяти 256к. При обращении к библиотечным функциям с переменным числом параметров (например fprint) компилятор встраивает вызовы к встроенным макросам пролог/эпилог (__prologue_saves__ / __epilogue_restores__ - если быть точным) из библиотеки libgcc.a. Беда в том, что данные для этих макросов, которые готовятся на этапе вызова функций, совершенно не учитывают размера памяти больше чем 128к (64к слов), то есть, инициализируются регистры Z (ZH,ZL), а в макросах используеться инструкция EIJMP, для полноценной работы которой надо еще установить регистр EIND. Вот и получается, что если библиотечные функции с переменным числов параметров располагаються в адресах выше чем 128к, то вся програма перестает работать. Решение проблемы - или исправлять libgcc.a (что для меня слишком сложно - я программирующий апаратчик) или заставить линкер располагать эти функции в нижних адресах (а как это сделать я не смог разобраться)... Может кто подскажет другой вариант? Я перепробовал все версии WinAVR начиная с 20070122, привожу фрагменты листинга (при компиляции нету ни ошибок ни предупреждений): Вот одна из библиотечных функций: 00020896 <fprintf_P>: 20896: a0 e0 ldi r26, 0x00 ; 0 20898: b0 e0 ldi r27, 0x00 ; 0 // здесь загружается адрес возврата // из __prologue_saves__ - это должен быть // адрес инструкции "ldd r16, Y+8" - 0х0208а2 // а у нас только 0х0451 х 2 = 0х08а2, // а старшая часть адреса 0х02 нигде не фиксируется!! 2089a: e1 e5 ldi r30, 0x51 ; 81 2089c: f4 e0 ldi r31, 0x04 ; 4 2089e: 0d 94 d9 0c jmp 0x219b2 ; 0x219b2 <__prologue_saves__+0x1c> 208a2: 08 85 ldd r16, Y+8 ; 0x08 208a4: 19 85 ldd r17, Y+9 ; 0x09 а вот злополучная __prologue_saves__ : 00021996 <__prologue_saves__>: 21996: 2f 92 push r2 ... 219b4: 1f 93 push r17 219b6: cf 93 push r28 219b8: df 93 push r29 219ba: cd b7 in r28, 0x3d ; 61 219bc: de b7 in r29, 0x3e ; 62 219be: ca 1b sub r28, r26 219c0: db 0b sbc r29, r27 219c2: 0f b6 in r0, 0x3f ; 63 219c4: f8 94 cli 219c6: de bf out 0x3e, r29 ; 62 219c8: 0f be out 0x3f, r0 ; 63 219ca: cd bf out 0x3d, r28 ; 61 219cc: 19 94 eijmp // естественно после этой инструкции мы "улетаем" // по адресу 0х0008а2 (проверено в отладчике)! Help!
|
|
|
|
|
Jun 30 2008, 18:43
|
Знающий
   
Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484

|
Цитата(Chak @ Jun 30 2008, 22:03)  Help!  Хм... посылали Эрику патч для решения этой проблемы но почему-то он его не добавил... Ждите следующую версию WinAVR. А пока исключите из проекта функции которые используют __prologue_saves__ / __epilogue_restores__ и выкинете ключик -mcall-prologues если вы его использовали. Можете еще поискать кого нибудь кто сможет вам собрать avr-libc внеся изменения в файл avr-libc/devtools/gen-avr-lib-tree.sh: -СFLAGS_SPACE="-mcall-prologues -Os" +CFLAGS_SPACE="-Os" Правда устанавливать avr-libc нужно будет ручками... хотя будет достаточно заменить *.a файлы в директори /avr/lib/avr6/. Анатолий.
Сообщение отредактировал aesok - Jun 30 2008, 19:06
|
|
|
|
|
Jul 1 2008, 06:44
|
Группа: Новичок
Сообщений: 5
Регистрация: 30-06-08
Пользователь №: 38 657

|
К Анатолию
Спасибо за информацию о скором выходе нового WinAVR - буду ждать.
А пока выкручусь через "левое ухо" - выкинуть функции использующие пролог/эпилог я пока не готов - ведь им надо или писать или искать замену (слишком много дел), я скомпилировал проект в версии 20070122 с библиотеками libc версии 1.6.1 и ключом -Os. Получилось 128866 байт (в версии 20080610 - 143844). Таким образом проблема решилась - но проект постоянно растет и если патчи не будут учтены в новой версии WinAVR - беда!
А может есть способ заставить линкер собирать сначала библиотечные функциии (из libc.a libm.a libgcc.a) а потом остальные модули?
Сообщение отредактировал Chak - Jul 1 2008, 06:45
|
|
|
|
|
Jul 1 2008, 08:13
|
Местный
  
Группа: Свой
Сообщений: 466
Регистрация: 21-06-05
Пользователь №: 6 205

|
Цитата(aesok @ Jun 28 2008, 21:55)  Тестовый пример пожалуйста приведите.
Анатолий. Есть строка вида (к примеру) Код const prog_char glob_menu_str[3][14]= { "Строка 1", "Строка 2", "Строка 3", }; После компилирования получаю Project.elfдалее делаю avr.nm -n Project.elf > file.txt и поиском ищу glob_menu_str.... в версии gcc 4.2.2 и более ранних получаю Код 00000326 t glob_menu_str т.е. если судить по символу t то оно легло в секцию с кодом но когда я использую gcc 4.3.0 то получаю такую вот картину Код 00800591 d _ZL13glob_menu_str оно легло во внешнее озу Далее в коде используется strlen_P, strncpy_P, pgm_read_byte и тд, т.е. думается что мы работаем с переменными расположенными в секции кода... З.Ы. При использовании GCC 4.2.2 (и более ранних) проект полностью рабочий!!!
|
|
|
|
|
Jul 1 2008, 08:53
|
Знающий
   
Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484

|
Цитата(kurtis @ Jul 1 2008, 12:13)  Есть строка вида (к примеру) Код const prog_char glob_menu_str[3][14]= { "Строка 1", "Строка 2", "Строка 3", }; Прочтите [TUT] [C] GCC and the PROGMEM Attribute , PART II - More advanced uses of PROGMEM. Анатлий.
|
|
|
|
|
Jul 1 2008, 09:42
|
Местный
  
Группа: Свой
Сообщений: 466
Регистрация: 21-06-05
Пользователь №: 6 205

|
Цитата(aesok @ Jul 1 2008, 11:53)  Простите, но я там не нашел ответа на свой вопрос, на что именно вы хотели мне указать??? Может я неправильно задал вопрос....Есть кусок кода Код const char MenuItem1[] PROGMEM = "Menu Item 1"; int main() { unsigned int a; a = pgm_read_word(&MenuItem1[4]); mTest1 = a; ............. return 0; } строку MenuItem1 GCC 4.2.2 ложит во flash, а GCC 4.3.0 ложит в ram!!! Как сделать, чтоб GCC 4.3.0 входящий в состав WinAVR-20080610, клал строку во flash (как это делала более ранняя версия)???
|
|
|
|
|
Jul 1 2008, 12:59
|
Местный
  
Группа: Свой
Сообщений: 466
Регистрация: 21-06-05
Пользователь №: 6 205

|
Но если пойти по приведенной aesok ссылке, то там некий товарищь, именно таким вот методом Код const char MenuItem1[] PROGMEM = "Menu Item 1"; размещает константы не там где хочет оптимизатор, а там где нада! У меня вызывает искреннее удивление, когда в новой версии компилятора, вдруг перестает работать код, который до этого работал много-много лет....Возможно я зациклился на том что код работал, и значит он корректен, и не вижу какой-то явной ошибки....
|
|
|
|
|
Jul 1 2008, 13:15
|

Начинающий профессионал
    
Группа: Свой
Сообщений: 1 215
Регистрация: 25-10-06
Из: СПб
Пользователь №: 21 648

|
Цитата(kurtis @ Jul 1 2008, 16:59)  Но если пойти по приведенной aesok ссылке, то там некий товарищь, именно таким вот методом Код const char MenuItem1[] PROGMEM = "Menu Item 1"; размещает константы не там где хочет оптимизатор, а там где нада! У меня вызывает искреннее удивление, когда в новой версии компилятора, вдруг перестает работать код, который до этого работал много-много лет....Возможно я зациклился на том что код работал, и значит он корректен, и не вижу какой-то явной ошибки.... Полный код примера из описания avr-libc: Код #include <avr/pgmspace.h>
const char foo[] PROGMEM = "Foo"; const char bar[] PROGMEM = "Bar";
PGM_P array[2] PROGMEM = { foo, bar };
int main (void) { char buf[32]; PGM_P p; int i;
memcpy_P(&p, &array[i], sizeof(PGM_P)); strcpy_P(buf, p); return 0; } Это для WinAVR-20071221. Для новых версий не смотрел. aesok скорее всего указывал на массив строк Код PGM_P array , а не на определения строк.
--------------------
Наука изощряет ум; ученье вострит память. Козьма Прутков
|
|
|
|
|
Jul 1 2008, 15:48
|
Местный
  
Группа: Свой
Сообщений: 466
Регистрация: 21-06-05
Пользователь №: 6 205

|
Заменил все prog_char на char имя_строки[] PROGMEM и без изменения кода функций вывода, все вдруг чудесно заработало... Собсно, а что случилось с prog_char в новых версиях??? почему выражения Код const prog_char Punkt1[] = {"Строка"}; и Код const char Punkt1[] PROGMEM = {"Строка"}; не равносильны??? Вроде это одно и тоже....
|
|
|
|
|
Jul 1 2008, 17:07
|
Знающий
   
Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484

|
Цитата(kurtis @ Jul 1 2008, 19:48)  почему выражения Код const prog_char Punkt1[] = {"Строка"}; и Код const char Punkt1[] PROGMEM = {"Строка"}; не равносильны??? Вроде это одно и тоже.... В первом случае указатель Punkt1 ссылается на const char с атрибутом "progmem", то есть на константную строку расположенную в памяти программ. Во втором указатель Punkt1 с атрибутом "progmem" ссылается на const char, то есть Punkt1 расположен в памяти программ, а константная строка в RAM. Для общего развития: Цитата Код const Pointers
The keyword const for pointers can appear before the type, after the type, or in both places. The following are legal declarations:
const int * ptr1; /* A pointer to a constant integer: the value pointed to cannot be changed */ int * const ptr2; /* A constant pointer to integer: the integer can be changed, but ptr2 cannot point to anything else */ const int * const ptr3; /* A constant pointer to a constant integer: neither the value pointed to nor the pointer itself can be changed */
Declaring an object to be const means that the this pointer is a pointer to a const object. A const this pointer can by used only with const member functions. Анатолий.
Сообщение отредактировал aesok - Jul 1 2008, 17:08
|
|
|
|
|
Jul 3 2008, 10:39
|
Местный
  
Группа: Свой
Сообщений: 466
Регистрация: 21-06-05
Пользователь №: 6 205

|
Анатолий, спасибо за ответы, очень помогло!!!=) Я пытаюсь разобраться, но все-равно есть некоторые вопросы... есть массив строк Код const char glob_menu_str[8][14] PROGMEM = { "1.Строка1", "1.Строка1", ...... }; далее где-то в коде вызывается функция вывода на ЖКИ (на самом деле это функция копирования значения из памяти в массив данных, который затем уже будет куда-то выводится, не обязательно на ЖКИ) Код LCD_abc1(glob_menu_str[glob_counter],1); ну и собственно сам код этой функции Код void LCD_abc1(const char * [b]_str[/b], uint8_t _pos) { uint8_t i = _pos; //size_t _strlen; uint8_t _strlen; uint8_t lcd_temp[32]; _strlen=strlen_P([b]_str[/b]); if(_strlen>(32-_pos)) _strlen=32-_pos;
strncpy_P((char*)(&lcd_temp),[b]_str[/b],_strlen+1);
while(i<32) { if(lcd_temp[i-_pos]==0x00) break; LCD_str[i] = pgm_read_byte(&LCD_simb[lcd_temp[i-_pos]]); ++i; } //LCD_str[i] - Временные массив, где хранится текущий "экран" //LCD_simb - Таблица символов для ЖКИ } Вроде все красиво, все в железе работает, но компилятор ругается Цитата warning: only initialized variables can be placed into program memory area на все строки описанные подобным образом Код const char glob_menu_str[8][14] PROGMEM = Непонятно почему возникает такое предупреждение, скомпилировал код в более ранних версиях WinAVR - компилятор такого предупреждения не выдает...
|
|
|
|
|
Jul 18 2008, 10:53
|
Знающий
   
Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484

|
Цитата(777777 @ Jul 18 2008, 11:02)  Глупые строки вида lds r24, 0x013A lds r25, 0x013B mov r18, r24 mov r19, r25 - остались. Исходники компилятора находятся здесь: http://gcc.gnu.org/. Сделать компилятор менее глупым в ваших силах. Цитата(777777 @ Jul 18 2008, 11:02)  В чем отличие и кому нужны 32 байта - так и не понял. На этом форуме было несколько рекомендаций как заставить avr-gcc 4.3 гененрировать более компактный код, поищите. (--param inline-call-cost, атрибут OS_main...) Анатолий.
|
|
|
|
|
Jul 18 2008, 11:56
|

Профессионал
    
Группа: Участник
Сообщений: 1 091
Регистрация: 25-07-07
Из: Саратов
Пользователь №: 29 357

|
Цитата(aesok @ Jul 18 2008, 14:53)  Исходники компилятора находятся здесь: http://gcc.gnu.org/. Сделать компилятор менее глупым в ваших силах. А поточнее можно ссылочку? Может и правда стоит попробовать... Когда-то давно с энтузиазмом дорабатывал компилятор Small-C для процессора 8080, он у меня стал полностью соответствовать стандарту, не понимал только элипсисы (...) Там даже оптимизатор был неслабый. Прада, он был pure-C... Цитата(aesok @ Jul 18 2008, 14:53)  На этом форуме было несколько рекомендаций как заставить avr-gcc 4.3 гененрировать более компактный код, поищите. (--param inline-call-cost, атрибут OS_main...) param inline-call-cost есть, а OS_main - это что? Надо сказать, документация у WinAVR весьма неудачно сделана, все разбросано по каким-то закоулкам.
|
|
|
|
|
Jul 18 2008, 12:27
|
Участник

Группа: Участник
Сообщений: 60
Регистрация: 11-07-06
Из: Челябинск
Пользователь №: 18 726

|
Цитата(MrYuran @ Jul 18 2008, 18:03)  А мне наоборот, очень понравилась, хотя бы тем, что она вообще есть c WinAvr идет документация по avr-libc, а остальную документацию нужно искать, как сказали выше, на http://gcc.gnu.org и на http://sources.redhat.com/binutils/
Сообщение отредактировал kaf - Jul 18 2008, 12:28
|
|
|
|
|
Jul 20 2008, 20:21
|
Знающий
   
Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484

|
Цитата(777777 @ Jul 18 2008, 15:56)  а OS_main - это что? Цитата Код This patch add "OS_main" and 'OS_task' attributes in GCC .... Function with "OS_main" and 'OS_task' attributes do not save any "call-saved" registers.
1. "OS_main" attribute used when there IS guarantee that interrupts are disabled at that time when function is called. For example "main" function in avr-libc. If this function has local variables that a prologue will look so: in r28, 0x3d; 61 in r29, 0x3e; 62 sbiw r28, 0x08; 8 out 0x3e, r29; 62 out 0x3d, r28; 61
No save/clear/restore "I" flag.
2. "OS_task" attribute used when there is NO guarantee that interrupts are disabled at that time when function is called. For example task functions multi-threading operating systems. In this case save/clear/restore "I" flag is need for changing SP register. Prologue (if this function has local variables) will look so:
in r28, 0x3d; 61 in r29, 0x3e; 62 sbiw r28, 0x08; 8 in r0, 0x3f; 63 cli out 0x3e, r29; 62 out 0x3f, r0; 63 out 0x3d, r28; 61
|
|
|
|
|
Jul 30 2008, 10:31
|
Участник

Группа: Участник
Сообщений: 39
Регистрация: 11-05-07
Из: Коряжма
Пользователь №: 27 672

|
У меня вот такой вопрос. поставил тут сегодня AVR Studio v4.14 build 589 затем установил WinAVR-20071221. Далее создаю новый проект в AVR GCC на микроконтроллере ATmega16. Далее нажимаю компиляцию и приехали называется. При компиляции выдаётся два сообщения Код Build started 30.7.2008 at 14:30:11 make: Makefile: No such file or directory make: *** No rule to make target `Makefile'. Stop. Build failed with 2 errors and 0 warnings... Я как понимаю не может создать Mafefile только вот почему. Люди добрые помогите обойти проблему.
|
|
|
|
|
Jul 30 2008, 18:16
|
Участник

Группа: Участник
Сообщений: 39
Регистрация: 11-05-07
Из: Коряжма
Пользователь №: 27 672

|
Самое интересное что дома попробывал сейчас немного по другому. Установил в начале WinAVR-20080610 затем устанвил AVR Studio 4.14 build589 и всё заработало...хм интресно...завтра на работе попробую такую же комбинцию.  В общем тут немного поэксперементировал и пришёл к выводу. Если создаёшь проект то в пути до проекта не ДОЛЖНО БЫТЬ РУССКИХ БУКВ Например (C:\Documents and Settings\Admin\Мои документы\test) Иначе Makefail не создастся...Для его создание необходимо исключить русские символы в пути до проекта....
Сообщение отредактировал Антон Малыгин - Jul 30 2008, 18:30
|
|
|
|
|
Jul 31 2008, 03:48
|

Познающий...
     
Группа: Свой
Сообщений: 2 963
Регистрация: 1-09-05
Из: г. Иркутск
Пользователь №: 8 125

|
Цитата(Антон Малыгин @ Jul 31 2008, 03:16)  Самое интересное что дома попробывал сейчас немного по другому. Установил в начале WinAVR-20080610 затем устанвил AVR Studio 4.14 build589 и всё заработало...хм интресно...завтра на работе попробую такую же комбинцию.  Наверно студия при установки смотрит, установлен ли WinAVR, и если да - то она готова для работы с ним. В противном случае начинаются проблемы. Цитата(Антон Малыгин @ Jul 31 2008, 03:16)  В общем тут немного поэксперементировал и пришёл к выводу. Если создаёшь проект то в пути до проекта не ДОЛЖНО БЫТЬ РУССКИХ БУКВ Например (C:\Documents and Settings\Admin\Мои документы\test) Иначе Makefail не создастся...Для его создание необходимо исключить русские символы в пути до проекта.... Это верно. При разработке программ под что угодно, в путях не должно быть русских имен. Я даже имена каталогов и файлов стараюсь не делать длинее 8 символов. Хотя здесь проблем не возникало никогда.
--------------------
Выбор.
|
|
|
|
|
Jul 31 2008, 07:22
|
Участник

Группа: Участник
Сообщений: 60
Регистрация: 11-07-06
Из: Челябинск
Пользователь №: 18 726

|
Цитата(haker_fox @ Jul 31 2008, 09:48)  Наверно студия при установки смотрит, установлен ли WinAVR, и если да - то она готова для работы с ним. В противном случае начинаются проблемы. Если сама не нешла, то достаточно прописать в плагине пути до make и gcc
|
|
|
|
|
Jul 31 2008, 14:09
|
Группа: Новичок
Сообщений: 5
Регистрация: 29-06-08
Из: Город Невест
Пользователь №: 38 619

|
Сам я пользуюсь WinAVR+AVRStudio+иногда Proteus. Но уже посматриваю на что-нибудь, где все в одном флаконе. И является именно IDE, а не набором разных программ, написанных разными авторами. Если кто-нибудь бывал на собрании кооператива(или смотрел фильм "Гараж"), то мы понимаем друг-друга. Пусть даже прийдется искать к этому вечно "хрюки". У меня установлен WinAVR-20060421, и не потому что я не в курсе выхода новых версий-просто я привык к "особенностям" этой. Плюс в более новых версиях в Протеусе не видно переменных, расположенных в Static RAM с выводом некорректного расположения адреса этой памяти. На это накладываются чудеса версий AVRStudio(в каком то сочетании WinAVR и AVRStudio попытка отладки Си кода в студии приводила к 100% вылету последней). Новая версия студии прекрасно отлаживает extcoff и виснет на ELF . RM.exe в указанной мною версии 20060421 (и еще какаято утилита) находятся в другой директории, какие-то файлы дублируются. Затолкав в протеус не вижу фрагмента кода, хотя в LSS файле все есть. Все это отнимает время. Человек должен ездить на машине, а не копаться в ней,это только у нас принято. Не скажу, что это совсем плохо, дает знания, но если для написания программы нужно начать с ремонта блока питания компа-это как-то не совсем. Я не против данного продукта, тем более в бесплатности есть большой плюс для написания коммерческих вещей. Для Антон Малыгин: возможно у вас что-то с путями доступа к файлам проекта или несоответствие названий. Попробуйте создать makefile вручную или с помощью утилиты из комплекта WinAVR. В студии определите Use external makefile, при составлении в ручную не забудьте все файлы проекта с расш "С" указать(вариант, созданный утилитой makefile): # List C source files here. (C dependencies are automatically generated.) SRC = $(TARGET).c C1820Timer.c WireDriver.c Удачи.
|
|
|
|
|
Aug 18 2008, 13:44
|
Частый гость
 
Группа: Свой
Сообщений: 77
Регистрация: 4-08-06
Пользователь №: 19 324

|
Доброе время суток, уважаемые. Возникла проблема при переходе с WinAVR-20070525 на WinAVR-20080512. При компиляции появляется предупреждение, что атрибут PROGMEM проигнорирован. Цитата ../menu.h:17: warning: ignoring attributes applied to 'struct <anonymous>' after definition на код Код typedef struct { //const char* ptr_item;// pointer to item name const char item_name[20];// string ptr_function select_function; // function pointer at enter/escape uint8_t ent_f; // ID menu item to enter uint8_t esc_f; // ID menu item to escape }Menu PROGMEM; Из-за этого память данных раздувается с 50 байт то 850. В чем может быть проблема? Заранее спасибо
|
|
|
|
|
Aug 18 2008, 14:27
|
Местный
  
Группа: Свой
Сообщений: 466
Регистрация: 21-06-05
Пользователь №: 6 205

|
Попробуйте так Код typedef struct { //const char* ptr_item;// pointer to item name const char item_name[20];// string ptr_function select_function; // function pointer at enter/escape uint8_t ent_f; // ID menu item to enter uint8_t esc_f; // ID menu item to escape }Menu;
Menu Menu_Item PROGMEM;
|
|
|
|
|
Sep 11 2008, 19:04
|
Участник

Группа: Новичок
Сообщений: 17
Регистрация: 31-10-05
Пользователь №: 10 350

|
Вот нарвался на странность Прописываю свой тип данных - структуру. Об'являюуказатели на этот тип. Код typedef struct { uint8_t status; //Status uint8_t R_index; //Read index uint8_t W_index; //Write index uint8_t buffer[MAXBUFFER]; }RINGBUFFER;
volatile RINGBUFFER *Rx,*Tx; Компилирую (без оптимизации)- все ОК, НО!!!!!!!! В Студии вижу полную "лажу" Мало того, что компилятор разместил экземпляры типа структуры в регистрах Так еще и они (эти два экземпляра) - одно и тоже - т.е при записи в Rx->buffer пишется также и в Tx->buffer - извечный вопрос. ЧТО ДЕЛАТЬ? :о) PS Может тупо "дать по рукам" компилятору и поставить Код volatile RINGBUFFER *Rx,*Tx __attribute__ ((section (".data"))); ?
Сообщение отредактировал Tracer - Sep 11 2008, 19:22
|
|
|
|
|
Sep 11 2008, 19:35
|
Знающий
   
Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484

|
Цитата(Tracer @ Sep 11 2008, 23:04)  Вот нарвался на странность Приведите больше кода, как вы работаете с указателемя, как выделяете память под структуры. Анатолий.
|
|
|
|
|
Sep 11 2008, 19:58
|
Участник

Группа: Новичок
Сообщений: 17
Регистрация: 31-10-05
Пользователь №: 10 350

|
Цитата(aesok @ Sep 11 2008, 22:35)  Приведите больше кода, как вы работаете с указателемя, как выделяете память под структуры.
Анатолий. Спасибо, ЭТО Я ТУПЛЮ. Действительно объявил указатели и БОЛЬШЕ НИЧЕГО. Пошел учить матчасть :о) Все поправил Объявляю теперь так Код volatile RINGBUFFER Rx,Tx; Все встало на места и находится там где надо Еще один вопрос Есть функция Код void rb_flush(RINGBUFFER *rb) { cli(); rb->R_index=0; rb->W_index=0; rb->status=EMPTYBUFFER; sei(); } Вызываю ее так Код void main(void) { ... rb_flush(&Rx); ... } Компилятор ругается - но не сильно А всетаки, что ему не нравится? Код ../rb.c:63: warning: passing argument 1 of 'rb_flush' discards qualifiers from pointer target type ../rb.c:64: warning: passing argument 1 of 'rb_flush' discards qualifiers from pointer target type
|
|
|
|
|
Sep 11 2008, 20:50
|

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

|
Цитата(Tracer @ Sep 11 2008, 22:58)  Компилятор ругается - но не сильно А всетаки, что ему не нравится? void rb_flush( volatile RINGBUFFER *rb) Но вы хорошенько подумайте, нужен ли вам volatile для всего буфера? Возможно, достаточно объявить с volatile только индексы и статус?
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Sep 11 2008, 21:12
|
Участник

Группа: Новичок
Сообщений: 17
Регистрация: 31-10-05
Пользователь №: 10 350

|
Цитата(Сергей Борщ @ Sep 11 2008, 23:50)  void rb_flush(volatile RINGBUFFER *rb) Но вы хорошенько подумайте, нужен ли вам volatile для всего буфера? Возможно, достаточно объявить с volatile только индексы и статус? 1. БОЛЬШОЕ спасибо. 2. Подумаю, Но без volatile в дизасемблере просто "окровения от GCC". Я такой код хрен бы писал какой он генерит. Но может я еще не достиг нужных высот для понимания Великой идеи :0)
Сообщение отредактировал Tracer - Sep 11 2008, 21:13
|
|
|
|
|
Sep 12 2008, 19:01
|
Участник

Группа: Новичок
Сообщений: 17
Регистрация: 31-10-05
Пользователь №: 10 350

|
Цитата(Непомнящий Евгений @ Sep 12 2008, 07:13)  Вы хотите сказать, что корректный С-код компилируется в неверную программу? Можете привести полный пример? Проверил В этой версии все ОК. В версии WinAVR 20071221 переменная ms_delay хранилась в регистре при прервании пушалась - изменялась-попалась - т.е ничего не менялось. Вот в этом примере. Код #include <stdint.h> #include <avr/interrupt.h>
uint16_t ms_delay=0;
ISR(TIMER0_OVF_vect) { if(ms_delay)ms_delay--;
}
void my_delay(uint16_t msd) { ms_delay=msd; while(ms_delay){} }
void main(void) { cli(); TCCR0=0x03; TCNT0=0x83; TIMSK=0x01; sei(); DDRB =0xff; while(1) { PORTB=0xff; my_delay(1000); PORTB=0x00; my_delay(1000); } При объявлении ее volatile все заработало. Я с тех пор глобальные переменные - объявляю типа volatile.
Сообщение отредактировал Tracer - Sep 12 2008, 19:04
|
|
|
|
|
Sep 12 2008, 19:08
|
Знающий
   
Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484

|
Цитата(Tracer @ Sep 12 2008, 23:01)  Я с тех пор глобальные переменные - объявляю типа volatile. avr-libc-user-manual FAQ#1 Анатолий.
|
|
|
|
|
Sep 12 2008, 19:27
|
Участник

Группа: Новичок
Сообщений: 17
Регистрация: 31-10-05
Пользователь №: 10 350

|
Цитата(aesok @ Sep 12 2008, 22:08)  avr-libc-user-manual FAQ#1
Анатолий. Да да именно мой случай. Ну кто же читет Факи в доках, пока не поморочит себе изрядно голову :о)) Теперь то я уже ЭТО знаю.
|
|
|
|
|
Sep 25 2008, 10:44
|

Участник

Группа: Участник
Сообщений: 16
Регистрация: 27-04-05
Из: Воронеж
Пользователь №: 4 541

|
Добрый день! У меня WinAVR 20080512 + AVR Studio 4.14 выдаёт предупреждение Код ../main.c:890: warning: passing argument 2 of 'eeprom_write_block' makes pointer from integer without a cast на последнюю строку в этом примере: Код #define EEPROM_SENSOR2_ADR 0x078 // адрес хранения номера датчика unsigned char current_sensor_code[8]; //текущий код датчика
...
eeprom_busy_wait(); eeprom_write_block (current_sensor_code, EEPROM_SENSOR2_ADR, 8); (функции - из eeprom.h того же WinAVR'a) т.е. ему не нравится то, что указатель на адрес записан в явном виде (конктетный адрес в EEPROM), хотя всё работает. как мне можно записать указатель на адрес ЕЕПРОМ чтобы компилятор не выдавал предупреждение? Можно ли при этом не расходовать RAM для хранения указателя? Или может существует какой-нибудь ключ для отмены выдачи предупреждения такой записи указателя?
|
|
|
|
|
Sep 25 2008, 11:25
|

Участник

Группа: Участник
Сообщений: 16
Регистрация: 27-04-05
Из: Воронеж
Пользователь №: 4 541

|
Цитата(Непомнящий Евгений @ Sep 25 2008, 14:56)  ну напишите руками приведение к тому типу, который ожидает eeprom_write_block - примерно так: eeprom_write_block (current_sensor_code, EEPROM_SENSOR2_ADR, (char*)8); Не, дык он же на 2-й аргумент функции ругается! Т.е. на EEPROM_SENSOR2_ADR, который выше обозначен как число 0x078. вот описание этой функции из доки: Цитата void eeprom_write_block (const void * pointer_ram, void * pointer_eeprom, size_t n)
Write a block of n bytes to EEPROM address pointer_eeprom from pointer_ram.
Сообщение отредактировал timex - Sep 25 2008, 11:30
|
|
|
|
|
Sep 25 2008, 11:45
|

Начинающий профессионал
    
Группа: Свой
Сообщений: 1 215
Регистрация: 25-10-06
Из: СПб
Пользователь №: 21 648

|
Достаточно распространенная ситуация, когда константы подставляются в вызов функции в том числе из макро. Лучше явно делать преобразование типа (как советует Непомнящий Евгений) для спокойной жизни. У Вас Цитата #define EEPROM_SENSOR2_ADR 0x078 // адрес хранения номера датчика Наверно, прошло бы без предупреждения, если не было бы ведущего нуля (0x78). Нет, не прошло бы. У Вас тип Код void , а это требует явного преобразования к типу используемой памяти. Посмотрел, как сам использовал Код uint8_t eeprom_buf[RECORD_SIZE]; /* Буфер блока данных */
int8_t eeprom_data_write(const int16_t address) /* Запись блока данных в EEPROM */ { int16_t tmp; if( (address > EEPMIN_ADDR) && (address < (EEPMAX_ADDR-RECORD_SIZE))) { tmp = address; eeprom_busy_wait(); eeprom_write_block(eeprom_buf, (uint16_t*)tmp, RECORD_SIZE); return EXIT_SUCCESS; } return EXIT_FAILUREN; /* Bad address */ } Явное преобразование типа, а заодно и контроль допустимых адресов записи
--------------------
Наука изощряет ум; ученье вострит память. Козьма Прутков
|
|
|
|
|
Sep 25 2008, 12:16
|

Участник

Группа: Участник
Сообщений: 16
Регистрация: 27-04-05
Из: Воронеж
Пользователь №: 4 541

|
mdmitry, да, спасиб. при такой записи строки Код eeprom_write_block (current_sensor_code, (unsigned int*) EEPROM_SENSOR2_ADR, 8); варнинг не выдаётся. Вдогонку! Обратил внимание, что в окне сообщений компилятора при Rebuld All выдаётся следующее (помечено "!!!!!!!!>"): Код Build started 25.9.2008 at 17:14:51 avr-gcc.exe -I"C:\AVRlib" -mmcu=atmega16 -Wall -gdwarf-2 -std=gnu99 -fgnu89-inline -O2 -fsigned-char -MD -MP -MT main.o -MF dep/main.o.d -c ../main.c !!!!!!!!> C:\WINDOWS\Temp/ccFQajf5.s: Assembler messages: !!!!!!!!> C:\WINDOWS\Temp/ccFQajf5.s:2433: Warning: expression dangerous with linker stubs !!!!!!!!> C:\WINDOWS\Temp/ccFQajf5.s:2434: Warning: expression dangerous with linker stubs avr-gcc.exe -mmcu=atmega16 main.o -o sensor_ibutton.elf avr-objcopy -O ihex -R .eeprom sensor_ibutton.elf sensor_ibutton.hex avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" --change-section-lma .eeprom=0 --no-change-warnings -O ihex sensor_ibutton.elf sensor_ibutton.eep || exit 0
AVR Memory Usage ---------------- Device: atmega16
Program: 4506 bytes (27.5% Full) (.text + .data + .bootloader) Data: 158 bytes (15.4% Full) (.data + .bss + .noinit)
Build succeeded with 0 Warnings... файлов таких в c:\windows\temp нету... где копать?
Сообщение отредактировал timex - Sep 25 2008, 13:14
|
|
|
|
|
Sep 25 2008, 13:23
|
;
     
Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509

|
Цитата(timex @ Sep 25 2008, 16:16)  1. по поводу Linker Stubs - это глюки. Здесь уже была тема. Можно (по крайней мере, в предыдущей winavr 2007) не обращать внимания. 2. Вернемся к Код eeprom_write_block (current_sensor_code, (unsigned int*) EEPROM_SENSOR2_ADR, 8); Вроде как правильно, но Вы уверены, что Вам нужен именно (unsigned int*) ?  Имхо, бардака в голове только прибавилось.
|
|
|
|
|
Sep 25 2008, 13:31
|

Начинающий профессионал
    
Группа: Свой
Сообщений: 1 215
Регистрация: 25-10-06
Из: СПб
Пользователь №: 21 648

|
Цитата(_Pasha @ Sep 25 2008, 17:23)  1. по поводу Linker Stubs - это глюки. Здесь уже была тема. Можно (по крайней мере, в предыдущей winavr 2007) не обращать внимания. 2. Вернемся к Код eeprom_write_block (current_sensor_code, (unsigned int*) EEPROM_SENSOR2_ADR, 8); Вроде как правильно, но Вы уверены, что Вам нужен именно (unsigned int*) ?  Имхо, бардака в голове только прибавилось. 1. Это временные файлы, они удаляются после выполнения необходимых действий. 2. Полная аналогия относительно доступа к областям памяти по отношению к функциям типа Код memmove, memcpy и другим (IMHO). Нужен ведь адрес ячейки памяти, а их больше чем 256.
--------------------
Наука изощряет ум; ученье вострит память. Козьма Прутков
|
|
|
|
|
Sep 25 2008, 13:44
|

Участник

Группа: Участник
Сообщений: 16
Регистрация: 27-04-05
Из: Воронеж
Пользователь №: 4 541

|
Цитата(_Pasha @ Sep 25 2008, 17:23)  1. по поводу Linker Stubs - это глюки. Здесь уже была тема. Можно (по крайней мере, в предыдущей winavr 2007) не обращать внимания. Сейчас проверил - появляется только при оптимизации -O1, -O2, -O3. При -Оs и -O0 такого нету... (WinAVR-20071221). Обновил до 20080512 - глюк перестал проявлятся! Цитата(_Pasha @ Sep 25 2008, 17:23)  2. Вернемся к Код eeprom_write_block (current_sensor_code, (unsigned int*) EEPROM_SENSOR2_ADR, 8); Вроде как правильно, но Вы уверены, что Вам нужен именно (unsigned int*) ?  Имхо, бардака в голове только прибавилось. Упс, от созерцания прекращения выдачи варнингов незаметил  . Переправил на "(unsigned char*)". Но в данном случае, думается, между int и char нет разницы, т.к. в описании функции стоит "void"...?
Сообщение отредактировал timex - Sep 25 2008, 13:57
|
|
|
|
|
Sep 25 2008, 14:19
|

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

|
Цитата(timex @ Sep 25 2008, 16:44)  Переправил на "(unsigned char*)". Но в данном случае, думается, между int и char нет разницы, т.к. в описании функции стоит "void"...? Если вы хотите писать понятно, то приведите к указателю на тот тип, данные которого записываете, т.е. к тому типу, на который у вас указывает current_sensor_code. Если хотите чтобы было "просто правильно", то приведите к тому типу, который ожидает функция, т.е. к void *. Если хотите через полгода-год, смотря в этот кусок кода, мучительно думать "а какого черта здесь приводится именно к unsigned char *, а не к unsigned int *?" - оставьте так, как есть. P.S. параметр функции объявлен как void *, потому что к void * неявно приводится любой указатель.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Sep 25 2008, 15:02
|

Начинающий профессионал
    
Группа: Свой
Сообщений: 1 215
Регистрация: 25-10-06
Из: СПб
Пользователь №: 21 648

|
Цитата(Сергей Борщ @ Sep 25 2008, 18:19)  Если вы хотите писать понятно, то приведите к указателю на тот тип, данные которого записываете, т.е. к тому типу, на который у вас указывает current_sensor_code. Если хотите чтобы было "просто правильно", то приведите к тому типу, который ожидает функция, т.е. к void *. Если хотите через полгода-год, смотря в этот кусок кода, мучительно думать "а какого черта здесь приводится именно к unsigned char *, а не к unsigned int *?" - оставьте так, как есть.
P.S. параметр функции объявлен как void *, потому что к void * неявно приводится любой указатель. Сергей Борщ, в функциях типа Код memmove и др. все же делается приведение к тому типу данных, который используется. Согласен, мой пример требует корректировки с точки зрения соблюдения всех стандартов.
--------------------
Наука изощряет ум; ученье вострит память. Козьма Прутков
|
|
|
|
|
Sep 25 2008, 18:17
|

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

|
Цитата(mdmitry @ Sep 25 2008, 18:02)  в функциях типа Код memmove и др. все же делается приведение к тому типу данных, который используется. Здесь какое-то недопонимание. Внутри функции memmove, memset и т.п. переданный указатель типа void * действительно приводится к тому типу, единицами которого осуществляется копирование, стирание (чаще всего к байту). Но сам параметр функции имеет тип void * чтобы при вызове этой функции можно было использовать любой указатель, не делая явного приведения: Код int var1; unsigned char var2; struct struct_t { unsigned int a; unsigned long b; } var3;
void Test() { memset(&var1, 0, sizeof(var1)); memset(&var2, 0, sizeof(var2)); memset(&var3, 0, sizeof(var3)); }
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Sep 25 2008, 19:46
|

Начинающий профессионал
    
Группа: Свой
Сообщений: 1 215
Регистрация: 25-10-06
Из: СПб
Пользователь №: 21 648

|
Цитата(Сергей Борщ @ Sep 25 2008, 22:17)  Здесь какое-то недопонимание. Внутри функции memmove, memset и т.п. переданный указатель типа void * действительно приводится к тому типу, единицами которого осуществляется копирование, стирание (чаще всего к байту). Но сам параметр функции имеет тип void * чтобы при вызове этой функции можно было использовать любой указатель, не делая явного приведения Насколько я понимаю, в прототипе указатели на источник и приемник имеют тип void* с целью дать программисту возможность явного приведения типа указателей как для удобства (работа с конкретными типами данных), так и для контроля типов самим компилятором. Предполагаю, что приведение типа может улучшить как скорость работы функции, так и эффективность использования памяти (дырки и выравнивание). Исходный код этих функций я не смотрел (неверно, неплохо и ознакомиться  ).
--------------------
Наука изощряет ум; ученье вострит память. Козьма Прутков
|
|
|
|
|
Sep 25 2008, 20:13
|
Местный
  
Группа: Свой
Сообщений: 381
Регистрация: 27-07-08
Из: теплые края
Пользователь №: 39 233

|
Цитата(mdmitry @ Sep 25 2008, 22:46)  Насколько я понимаю, в прототипе указатели на источник и приемник имеют тип void* с целью дать программисту возможность явного приведения типа указателей как для удобства (работа с конкретными типами данных), так и для контроля типов самим компилятором. Нет. С точки зрения контроля типов void* - худшее что можно придумать. Цитата Предполагаю, что приведение типа может улучшить как скорость работы функции, так и эффективность использования памяти (дырки и выравнивание). Исходный код этих функций я не смотрел (неверно, неплохо и ознакомиться  ). Нет. С точки зрения компилятора (точнее ассемблера) не имеет никакой разницы, указатель на какой тип используется.
|
|
|
|
|
Sep 30 2008, 18:24
|
Знающий
   
Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484

|
Цитата(_Pasha @ Sep 30 2008, 11:06)  Хочу спросить: почему в хедерах контроллеров не прижилось описание SFR через структуры с битовыми полями? aesok - Вы ближе всего к идеологии...  Наверное по той-же самой причине по которой выкинули sbi и cbi, с помощью таких структур можно красиво изменять один бит, но если вам нужно сразу установить несколько бит в регистре, то код получается избыточным (нужно последовательно устанавливать каждый бит). Анатолий.
|
|
|
|
|
Oct 3 2008, 20:13
|
Участник

Группа: Новичок
Сообщений: 17
Регистрация: 31-10-05
Пользователь №: 10 350

|
Цитата(demiurg_spb @ Oct 1 2008, 10:40)  К слову, из рассылки ImageCraft от 26 сентября 2008г:
With XMega, Atmel introduce new syntax to access the io registers, using structs and unions. See AppNote AVR1000 for details.
ImageCraft io header files support new syntax fully, only usage of multi-byte struct members is different, because compiler does not support C++ anonymous unions. Та в ИКС Мегах, АТМЕЛы сделали виртуальные регистры - специально для битовых операций. Мне вообще импонирует,что АВР делаются под синтаксис С.
Сообщение отредактировал Tracer - Oct 3 2008, 20:14
|
|
|
|
|
  |
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|