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

 
 
> AVR Toolchain - как работать с __flash?
ARV
сообщение Mar 1 2015, 20:12
Сообщение #1


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

Группа: Свой
Сообщений: 1 143
Регистрация: 30-09-08
Из: Новочеркасск
Пользователь №: 40 581



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

есть такая структура
Код
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[i].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 исчезает из кода?! я же делаю к нему обращения!


--------------------
Я бы взял частями... но мне надо сразу.
Go to the top of the page
 
+Quote Post
2 страниц V   1 2 >  
Start new topic
Ответов (1 - 24)
smalcom
сообщение Mar 1 2015, 20:54
Сообщение #2


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

Группа: Свой
Сообщений: 1 292
Регистрация: 26-06-07
Пользователь №: 28 718



AVR имеет девственную гарвардскую архитектуру. Для чтения данных из памяти программ используется набор ф-й pgm_read_xxx.
Посмотрите примерчики avrlib и макрос PGM_P.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Mar 1 2015, 22:30
Сообщение #3


Гуру
******

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



Цитата(smalcom @ Mar 1 2015, 22:54) *
Для чтения данных из памяти программ используется набор ф-й pgm_read_xxx.
Вы отстали от жизни. Уже довольно давно в avr-gcc в режиме C зявлена поддержка различных адресных пространств и квалификатор __flash.


--------------------
На любой вопрос даю любой ответ
"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
smalcom
сообщение Mar 1 2015, 23:32
Сообщение #4


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

Группа: Свой
Сообщений: 1 292
Регистрация: 26-06-07
Пользователь №: 28 718



https://gcc.gnu.org/onlinedocs/gcc/Named-Address-Spaces.html

действительно отстал))
Go to the top of the page
 
+Quote Post
ARV
сообщение Mar 2 2015, 04:49
Сообщение #5


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

Группа: Свой
Сообщений: 1 143
Регистрация: 30-09-08
Из: Новочеркасск
Пользователь №: 40 581



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

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


--------------------
Я бы взял частями... но мне надо сразу.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Mar 2 2015, 07:34
Сообщение #6


Гуру
******

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



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


--------------------
На любой вопрос даю любой ответ
"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
ARV
сообщение Mar 2 2015, 08:18
Сообщение #7


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

Группа: Свой
Сообщений: 1 143
Регистрация: 30-09-08
Из: Новочеркасск
Пользователь №: 40 581



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

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


--------------------
Я бы взял частями... но мне надо сразу.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Mar 2 2015, 08:53
Сообщение #8


Гуру
******

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



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


--------------------
На любой вопрос даю любой ответ
"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
ARV
сообщение Mar 2 2015, 08:58
Сообщение #9


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

Группа: Свой
Сообщений: 1 143
Регистрация: 30-09-08
Из: Новочеркасск
Пользователь №: 40 581



Код
#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 - символ должен быть цифрой. все остальное - прямое равенство. номер структуры, для которой первой все условия совпадут и есть номер правила.


--------------------
Я бы взял частями... но мне надо сразу.
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Mar 2 2015, 09:08
Сообщение #10


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

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



Цитата(ARV @ Mar 2 2015, 11:58) *
Какую версию компилятора используете?

http://sourceforge.net/projects/mobileches...hots%20(Win32)/
- c этим (avr-gcc-4.9.2 (prerelease)) тулчейном у меня всё отлично работает.
Во всю использую __flash...


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Mar 2 2015, 09:20
Сообщение #11


Гуру
******

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



Цитата(ARV @ Mar 2 2015, 10:58) *
Код
#define NO_CHAR        -1
#define ANY_VAR        -2
#define ANY_DIG        -3
#define ANY_CHAR    -4
Тогда компилятор сделал все правильно. Согласно integer promotion rules ваш rules[i].prev_ch перед сравнением приводится к int и он никак не может быть равным отрицательному числу. Надо или в #define или в условиях явно привести эти константы к uint8_t.


--------------------
На любой вопрос даю любой ответ
"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
ARV
сообщение Mar 2 2015, 09:24
Сообщение #12


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

Группа: Свой
Сообщений: 1 143
Регистрация: 30-09-08
Из: Новочеркасск
Пользователь №: 40 581



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

Цитата(Сергей Борщ @ Mar 2 2015, 13:20) *
Тогда компилятор сделал все правильно. Согласно integer promotion rules ваш rules[i].prev_ch перед сравнением приводится к int и он никак не может быть равным отрицательному числу. Надо или в #define или в условиях явно привести эти константы к uint8_t.
еще раз и помедленнее, пожалуйста. в моем понимании беззнаковый байт -1 это всего-навсего 0xFF, и потому должен сравниваться...


--------------------
Я бы взял частями... но мне надо сразу.
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Mar 2 2015, 09:27
Сообщение #13


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

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



hint:
Код
#define NO_CHAR        -1U
#define ANY_VAR        -2U
#define ANY_DIG        -3U
#define ANY_CHAR    -4U


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
ARV
сообщение Mar 2 2015, 09:29
Сообщение #14


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

Группа: Свой
Сообщений: 1 143
Регистрация: 30-09-08
Из: Новочеркасск
Пользователь №: 40 581



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

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


--------------------
Я бы взял частями... но мне надо сразу.
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Mar 2 2015, 09:30
Сообщение #15


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

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



Цитата(ARV @ Mar 2 2015, 12:24) *
скачал с сайта Атмела текущую версию тулчейна для AVR8...
А какая версия последняя?
Наберите в консоли:
Код
avr-gcc --v



--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
ARV
сообщение Mar 2 2015, 09:34
Сообщение #16


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

Группа: Свой
Сообщений: 1 143
Регистрация: 30-09-08
Из: Новочеркасск
Пользователь №: 40 581



все, тему можно закрывать blush.gif

Цитата(demiurg_spb @ Mar 2 2015, 13:30) *
А какая версия последняя?
Наберите в консоли:
Код
avr-gcc --v

4.8.1

хотя еще рано закрывать тему: просветите еще, пожалуйста, как правильно определять массив в flash:
1. __flash const bla_bla_bla array[];
2. const bla_bla_bla __flash array[];

Eclipsе не распарсивает второй вариант, хотя вроде как он правильный...


--------------------
Я бы взял частями... но мне надо сразу.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Mar 2 2015, 09:37
Сообщение #17


Гуру
******

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



Цитата(ARV @ Mar 2 2015, 11:34) *
хотя вроде как он правильный...
По моему тоже. Эклипс несовершенен. Можно попытаться направить им сообщение об ошибке.


--------------------
На любой вопрос даю любой ответ
"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
ARV
сообщение Mar 2 2015, 09:49
Сообщение #18


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

Группа: Свой
Сообщений: 1 143
Регистрация: 30-09-08
Из: Новочеркасск
Пользователь №: 40 581



у меня с английским не очень хорошо, а автопереводчикам не очень доверяю...

Eclipse Luna мало того, что второй вариант объявления не понимает, но если такое объявление находится в числе параметров функции - вся функция не подсвечивется, и ниже по коду могут быть сбои парсера синтаксиса...


--------------------
Я бы взял частями... но мне надо сразу.
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Mar 2 2015, 15:56
Сообщение #19


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(ARV @ Mar 2 2015, 14:49) *
Eclipse Luna мало того, что второй вариант объявления не понимает, но если такое объявление находится в числе параметров функции - вся функция не подсвечивется, и ниже по коду могут быть сбои парсера синтаксиса...

Эклипса понятия не имеет, что такое "__flash". Помогите ей, задайте в Project - Properties - C/C++ General - Paths and Symbols - Symbols пустой дефайн "__flash".


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Mar 3 2015, 08:19
Сообщение #20


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

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



Цитата(AHTOXA @ Mar 2 2015, 18:56) *
Эклипса понятия не имеет, что такое "__flash". Помогите ей, задайте в Project - Properties - C/C++ General - Paths and Symbols - Symbols пустой дефайн "__flash".

Думаю, что цель DISCOVERY тоже решает эту задачу, но более правильным способом.
Код
#discovery target for Eclipse parser
#usage: make specs_file=${INPUTS}
.PHONY: discovery
discovery:
        $(CC) $(SOURCE_DIRS) $(ALL_CFLAGS) -E -P -v -dD '$(specs_file)'
        $(REMOVE) spec.d


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Mar 3 2015, 23:02
Сообщение #21


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Думаете, там будет дефайн для __flash? Я в этом сильно сомневаюсь. Ведь __flash - это не дефайн, а квалификатор типа памяти.


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Mar 4 2015, 07:33
Сообщение #22


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

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



Цитата(AHTOXA @ Mar 4 2015, 02:02) *
Да, Вы правы, есть лишь дефайн __FLASH, но это не то...
Жаль что нет стандартного способа раскрытия расширений языка для редактора...


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Mar 4 2015, 07:45
Сообщение #23


Гуру
******

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



Цитата(AHTOXA @ Mar 2 2015, 17:56) *
задайте в Project - Properties - C/C++ General - Paths and Symbols - Symbols пустой дефайн "__flash".
Это если используется самопальный самописный makefile. А если используется какой-то плагин, генерящий makefile исходя из этих установок, то такой define замаскирует ключевое слово при компиляции. А вот если он будет подставляться только при выполении discovery - все будут довольны:
Код
discovery:
        $(CC) $(SOURCE_DIRS) $(ALL_CFLAGS) -D__flash -E -P -v -dD '$(specs_file)'



И по теме основного вопроса - я полагаю, что проблема возникла из-за использования неподходящего типа. В полях prev_ch, curr_ch хранятся символы и поэтому это тот редкий случай, когда надо использовать тип char. Не unsigned, не signed, не тип из stdint.h, а именно классический char. И поскольку NO_CHAR, ANY_VAR, ANY_DIG, ANY_CHAR представляют из себя переопределенные коды символов, их надо обявлять именно как "символ с указанным кодом", т.е. '\xFF', '\xFE', '\xFD', '\xFC'. Тогда не было бы проблемы с неявным расширением до int и не пришлось бы бороться с ней явными приведениями типов.


--------------------
На любой вопрос даю любой ответ
"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
AHTOXA
сообщение Mar 4 2015, 10:13
Сообщение #24


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(Сергей Борщ @ Mar 4 2015, 12:45) *
Это если используется самопальный самописный makefile. А если используется какой-то плагин, генерящий makefile исходя из этих установок, то такой define замаскирует ключевое слово при компиляции. А вот если он будет подставляться только при выполении discovery - все будут довольны:
Код
discovery:
        $(CC) $(SOURCE_DIRS) $(ALL_CFLAGS) -D__flash -E -P -v -dD '$(specs_file)'

Если makefile генерится плагином, то откуда там появится цель discovery? sm.gif
А вот для самописного makefile это решение правильнее, чем то, что я написал выше - так мы получим все настройки проекта в одном месте (в makefile).


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
ARV
сообщение Mar 5 2015, 12:21
Сообщение #25


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

Группа: Свой
Сообщений: 1 143
Регистрация: 30-09-08
Из: Новочеркасск
Пользователь №: 40 581



не знаю, что такое discovery, но проблема с подсветкой синтаксиса, обозначенная мной, решается тупым typedef __flash const char fchar; - после этого Eclipse прекрасно понимает, что fchar это тип и все подсвечивает правильно.


--------------------
Я бы взял частями... но мне надо сразу.
Go to the top of the page
 
+Quote Post

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

 


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


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