|
AVR Toolchain - как работать с __flash? |
|
|
|
Mar 1 2015, 20:12
|

Профессионал
    
Группа: Свой
Сообщений: 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 исчезает из кода?! я же делаю к нему обращения!
--------------------
Я бы взял частями... но мне надо сразу.
|
|
|
|
2 страниц
1 2 >
|
 |
Ответов
(1 - 24)
|
Mar 2 2015, 09:08
|

неотягощённый злом
     
Группа: Свой
Сообщений: 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...
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
|
Mar 2 2015, 09:20
|

Гуру
     
Группа: Модераторы
Сообщений: 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)
|
|
|
|
|
Mar 2 2015, 09:30
|

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

|
Цитата(ARV @ Mar 2 2015, 12:24)  скачал с сайта Атмела текущую версию тулчейна для AVR8... А какая версия последняя? Наберите в консоли: Код avr-gcc --v
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
|
Mar 2 2015, 09:34
|

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

|
все, тему можно закрывать  Цитата(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е не распарсивает второй вариант, хотя вроде как он правильный...
--------------------
Я бы взял частями... но мне надо сразу.
|
|
|
|
|
Mar 3 2015, 08:19
|

неотягощённый злом
     
Группа: Свой
Сообщений: 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
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
|
Mar 4 2015, 07:45
|

Гуру
     
Группа: Модераторы
Сообщений: 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)
|
|
|
|
|
Mar 4 2015, 10:13
|

фанат дивана
     
Группа: Свой
Сообщений: 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?  А вот для самописного makefile это решение правильнее, чем то, что я написал выше - так мы получим все настройки проекта в одном месте (в makefile).
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|