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

 
 
7 страниц V  < 1 2 3 4 5 > »   
Reply to this topicStart new topic
> WinAVR-20080610, делимся впечатлениями
Сергей Борщ
сообщение Jun 30 2008, 10:06
Сообщение #31


Гуру
******

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



Цитата(aesok @ Jun 30 2008, 12:35) *
про --gc-sections где-то читал что могут быть проблеммы с отладкой. вечером поищю где про это написано.
В некоторых версиях он выдавал warning "могут быть проблемы с отладкой на некоторых targets". Пока на такие проблемы не натыкался (внутрисхемной отладкой не пользуюсь), а уточнений - на каких именно targets и какие именно проблемы могут быть - не попадалось.


--------------------
На любой вопрос даю любой ответ
"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
Chak
сообщение Jun 30 2008, 18:03
Сообщение #32





Группа: Новичок
Сообщений: 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! help.gif
Go to the top of the page
 
+Quote Post
aesok
сообщение Jun 30 2008, 18:43
Сообщение #33


Знающий
****

Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484



Цитата(Chak @ Jun 30 2008, 22:03) *
Help! help.gif


Хм... посылали Эрику патч для решения этой проблемы но почему-то он его не
добавил... Ждите следующую версию 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
Go to the top of the page
 
+Quote Post
Chak
сообщение Jul 1 2008, 06:44
Сообщение #34





Группа: Новичок
Сообщений: 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
Go to the top of the page
 
+Quote Post
kurtis
сообщение Jul 1 2008, 08:13
Сообщение #35


Местный
***

Группа: Свой
Сообщений: 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 (и более ранних) проект полностью рабочий!!!
Go to the top of the page
 
+Quote Post
aesok
сообщение Jul 1 2008, 08:53
Сообщение #36


Знающий
****

Группа: Участник
Сообщений: 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.

Анатлий.
Go to the top of the page
 
+Quote Post
kurtis
сообщение Jul 1 2008, 09:42
Сообщение #37


Местный
***

Группа: Свой
Сообщений: 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 (как это делала более ранняя версия)???
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Jul 1 2008, 12:23
Сообщение #38


;
******

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



Цитата(kurtis @ Jul 1 2008, 12:42) *
строку MenuItem1 GCC 4.2.2 ложит во flash, а GCC 4.3.0 ложит в ram!!! Как сделать, чтоб GCC 4.3.0 входящий в состав WinAVR-20080610, клал строку во flash (как это делала более ранняя версия)???


Или Вы запутались или одно из двух. В приведенном коде у Вас фигурировало константное выражение. Ессно мона его расположить где удобнее оптимайзеру smile.gif
Go to the top of the page
 
+Quote Post
kurtis
сообщение Jul 1 2008, 12:59
Сообщение #39


Местный
***

Группа: Свой
Сообщений: 466
Регистрация: 21-06-05
Пользователь №: 6 205



Но если пойти по приведенной aesok ссылке, то там некий товарищь, именно таким вот методом
Код
const char MenuItem1[] PROGMEM = "Menu Item 1";
размещает константы не там где хочет оптимизатор, а там где нада!
У меня вызывает искреннее удивление, когда в новой версии компилятора, вдруг перестает работать код, который до этого работал много-много лет....Возможно я зациклился на том что код работал, и значит он корректен, и не вижу какой-то явной ошибки....
Go to the top of the page
 
+Quote Post
mdmitry
сообщение Jul 1 2008, 13:15
Сообщение #40


Начинающий профессионал
*****

Группа: Свой
Сообщений: 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
, а не на определения строк.


--------------------
Наука изощряет ум; ученье вострит память. Козьма Прутков
Go to the top of the page
 
+Quote Post
kurtis
сообщение Jul 1 2008, 15:48
Сообщение #41


Местный
***

Группа: Свой
Сообщений: 466
Регистрация: 21-06-05
Пользователь №: 6 205



Заменил все prog_char на char имя_строки[] PROGMEM и без изменения кода функций вывода, все вдруг чудесно заработало...
Собсно, а что случилось с prog_char в новых версиях???
почему выражения
Код
const   prog_char   Punkt1[]   =   {"Строка"};
и
Код
const   char   Punkt1[]   PROGMEM   =   {"Строка"};
не равносильны???
Вроде это одно и тоже....
Go to the top of the page
 
+Quote Post
aesok
сообщение Jul 1 2008, 17:07
Сообщение #42


Знающий
****

Группа: Участник
Сообщений: 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
Go to the top of the page
 
+Quote Post
kurtis
сообщение Jul 3 2008, 10:39
Сообщение #43


Местный
***

Группа: Свой
Сообщений: 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 - компилятор такого предупреждения не выдает...
Go to the top of the page
 
+Quote Post
haker_fox
сообщение Jul 4 2008, 02:59
Сообщение #44


Познающий...
******

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



Цитата(aesok @ Jul 2 2008, 02:07) *
Во втором указатель Punkt1 с атрибутом "progmem" ссылается на const char, то есть Punkt1 расположен в памяти программ, а константная строка в RAM.
Анатолий.

Как я понял, этот вариант работает в WinAVR2008....
Но ведь таким образом расходуется драгоценная RAM.


--------------------
Выбор.
Go to the top of the page
 
+Quote Post
777777
сообщение Jul 18 2008, 07:02
Сообщение #45


Профессионал
*****

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



Поставил сабж. Размер обоих проектов увеличился ровно на 32 байта каждый. Работоспособность не изменилась. Глупые строки вида
lds r24, 0x013A
lds r25, 0x013B
mov r18, r24
mov r19, r25
- остались. В чем отличие и кому нужны 32 байта - так и не понял.
Go to the top of the page
 
+Quote Post

7 страниц V  < 1 2 3 4 5 > » 
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


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


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