Перейти к содержанию
    

AVR Toolchain - как работать с __flash?

Не едут лыжи, помогите понять, почему происходит следующее.

 

есть такая структура

typedef struct{
    uint8_t        prev_ch;            // предыдущий символ
    uint8_t        curr_ch;            // текущий символ
    uint8_t        auto_eq;            // автовставка TOC_EQUAL
    uint8_t        can_ok;                // разрешено нажатие ОК (конец редактирования)
    uint8_t        approved_begin;        // индекс первого разрешенного следующего символа
    uint8_t        approved_end;        // индекс последнего разрешенного следующего символа
} smart_rule;

делаю массив таких структур в адресном пространстве __flash, которое как бы поддерживается AVR Toolchain (и для обычных строк действительно поддерживается!)

const smart_rule __flash rules[RULES_CNT] = { тут инициализирую все структуры }

затем есть код, с которым дикие проблемы:

uint8_t find_rule(uint8_t pos, char *s){
    uint8_t i;

    for(i=0; i < RULES_CNT; i++){
        if((rules[i].prev_ch == NO_CHAR) && (pos == 0)){
            if((rules[i].curr_ch == NO_CHAR) && (s[pos] == ' ')) break;
            if((rules[i].curr_ch == ANY_VAR) && (s[pos] >= TOC_WDAY) && (s[pos] <= TOC_QUART)) break;
            if(rules[i].curr_ch == s[pos]) break;
        }
        if(rules[i].prev_ch == ANY_CHAR){
            if((rules[i].curr_ch == NO_CHAR) && (s[pos] == ' ')) break;
            if((rules[i].curr_ch == ANY_VAR) && (s[pos] >= TOC_WDAY) && (s[pos] <= TOC_QUART)) break;
            if(rules[i].curr_ch == s[pos]) break;
        }
        if((rules[i].prev_ch == ANY_DIG) && (s[pos-1] >= '0') && (s[pos-1] <= '9')){
            if((rules[i].curr_ch == NO_CHAR) && (s[pos] == ' ')) break;
            if((rules[i].curr_ch == ANY_DIG) && (s[pos-1] >= '0') && (s[pos-1] <= '9')) break;
            if((rules[i].curr_ch == ANY_VAR) && (s[pos] >= TOC_WDAY) && (s[pos] <= TOC_QUART)) break;
            if(rules[i].curr_ch == s[pos]) break;
        }
    }
    return i;
}

проблемы следующие:

1. в том виде, как описано, Eclipse категорически отказывается понимать обращение к массиву типа такого rules.prev_ch - пишет, что Field 'prev_ch' could not be resolved, аналогично и на все другие поля. при этом компиляция идет без ошибок.

2. Eclipse перестает ругаться, если меняю определение массива на такое: __flash const smart_rule rules[RULES_CNT]

3. ладно, пусть я не понимаю, как правильно определить массив во flash, НО!!!! в итоговом коде нет тела вышеприведенной функции find_rule - если отключаю оптимизацию, остается ПУСТОЙ ЦИКЛ, а при включенной оптимизации даже нет обращения к функции!

 

ПОЧЕМУ?

почему компилятор считает, что ни один if не сработает? что я делаю не так? почему если я задаю опции -fdata-sections и -Wl,-gc-sections, то мой массив rules исчезает из кода?! я же делаю к нему обращения!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

AVR имеет девственную гарвардскую архитектуру. Для чтения данных из памяти программ используется набор ф-й pgm_read_xxx.

Посмотрите примерчики avrlib и макрос PGM_P.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для чтения данных из памяти программ используется набор ф-й pgm_read_xxx.
Вы отстали от жизни. Уже довольно давно в avr-gcc в режиме C зявлена поддержка различных адресных пространств и квалификатор __flash.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

я перешел с WinAVR на AVR Toolchain практически только из-за этой самой поддержки __flash, ибо реализация вышеупомянутой функции при помощи pgm_read_xxxx - это не геморрой даже, это ужас нерожденного...

 

так что по существу моего вопроса скажете, уважаемые коллеги? неужели никто с массивами структур во flash не работает?!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Увы, не использую эти квалификаторы. Когда только появлялась поддержка этого квалификатора, ее автор писал что не будет добавлять ее в режиме С++, потому что он не использует плюсы и вообще адресные пространства добавлены только в стандарт С, но не в С++. А поскольку я пишу только на С++ - приходится по старинке, pgm_read_xxx(). Пользуюсь компилятором из репозитория убунты. Под виндовсом после смерти WinAVR использовал сборки отсюда.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

pgm_read_xxx - это кошмар :( проще будет перенести массив в ОЗУ.

 

перенес массив в ОЗУ... складывается впечатление, что что-то у меня не то записано в условиях внутри цикла, потому что компилятор упорно выбрасывает все if-ы - видно, считает, что условия никогда не выполняются. но я не вижу этой однозначности... может, со стороны виднее: ткните носом!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Так с наскока тоже не вижу. А чему равны константы ANY_CHAR, NO_CHAR, ANY_DIG, ANY_VAR?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

#define NO_CHAR        -1
#define ANY_VAR        -2
#define ANY_DIG        -3
#define ANY_CHAR    -4

в массиве - набор правил, т.е. условий проверки пары символов в строке. должны совпасть оба символа в строке с тем, что задано в одной из структур массива. если задано prev_ch = NO_CHAR - предыдущий символ не проверяется, потому что это ситуация начала строки и предыдущего символа просто нет. если curr_ch = NO_CHAR - в строке должен быть на текущей позиции пробел. ANY_VAR - символ в строке должен лежать в некоем диапазоне значений. ANY_DIG - символ должен быть цифрой. все остальное - прямое равенство. номер структуры, для которой первой все условия совпадут и есть номер правила.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Какую версию компилятора используете?

 

http://sourceforge.net/projects/mobileches...hots%20(Win32)/

- c этим (avr-gcc-4.9.2 (prerelease)) тулчейном у меня всё отлично работает.

Во всю использую __flash...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

#define NO_CHAR        -1
#define ANY_VAR        -2
#define ANY_DIG        -3
#define ANY_CHAR    -4

Тогда компилятор сделал все правильно. Согласно integer promotion rules ваш rules.prev_ch перед сравнением приводится к int и он никак не может быть равным отрицательному числу. Надо или в #define или в условиях явно привести эти константы к uint8_t.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

скачал с сайта Атмела текущую версию тулчейна для AVR8... ща попробую рекомендованную Вами скачать.

 

Тогда компилятор сделал все правильно. Согласно integer promotion rules ваш rules.prev_ch перед сравнением приводится к int и он никак не может быть равным отрицательному числу. Надо или в #define или в условиях явно привести эти константы к uint8_t.
еще раз и помедленнее, пожалуйста. в моем понимании беззнаковый байт -1 это всего-навсего 0xFF, и потому должен сравниваться...

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

hint:

#define NO_CHAR        -1U
#define ANY_VAR        -2U
#define ANY_DIG        -3U
#define ANY_CHAR    -4U

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

блин, Сергей, ну спасибо Вам! как я лоханулся-то! действительно, переделал константы на 0xFF, 0xFE и т.д. - появились проверки!!!

спасибо огромное!

 

этого самого integer promotions в данном месте и не увидел вообще, незаметно подкрался...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

скачал с сайта Атмела текущую версию тулчейна для AVR8...
А какая версия последняя?

Наберите в консоли:

avr-gcc --v

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...