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

 
 
 
Closed TopicStart new topic
> Причуды компилятора AVR, Проблема при работе с памятью
Yoruk91
сообщение Sep 20 2013, 11:47
Сообщение #1





Группа: Участник
Сообщений: 11
Регистрация: 2-04-13
Пользователь №: 76 323



Здравствуйте уважаемые радиолюбители.
Хотел бы узнать ваше мнение по поводу маленькой проблемы, а то скоро разобью себе голову об стол. maniac.gif
Я делаю устройство, которое по замыслу должно активно взаимодействовать с пользователем через интерфейс RS-485, т.е оно будет находиться на удалений и будет трудно досягаемым для пользователей. Устройство активно взаимодействует с пользователем посредством текстовых сообщений на каждый чих. Т.е в Flash памяти МК должен храниться полный набор текстовых сообщений на все случаи жизни.
Проблема :
Не могу стандартными средствами заставить поместить массив с указателями на строки в Flash память.
В кусочке кода демонстрируется фрагмент работы с часами DS3231

//Дни недели
Код
const char DS3231_Day1 [] PROGMEM ="Sun ";
const char DS3231_Day2 [] PROGMEM ="Mon ";
const char DS3231_Day3 [] PROGMEM ="Tue ";
const char DS3231_Day4 [] PROGMEM ="Wed ";
const char DS3231_Day5 [] PROGMEM ="Thu ";
const char DS3231_Day6 [] PROGMEM ="Fri ";
const char DS3231_Day7 [] PROGMEM ="Sat ";


Вот тут по замыслу из часов пришла циферка 2 из регистра «День недели» и мы плавно передаем данные в обрабатывающий центр "Mon ";
Собственно, вычисление нужной строки происходит тут :

Код
char* Day_Pointer [] PROGMEM = { DS3231_Day1,DS3231_Day2,
                      DS3231_Day3,DS3231_Day4,
                      DS3231_Day5,DS3231_Day6,
                      DS3231_Day7};


И почему то стала появляться ошибка, которой раньше не было.

Error 1 variable 'Day_Pointer' must be const in order to be put into read-only section by means of '__attribute__((progmem))' C:\Work\Protos\Task_2\Task_2.c 38 7 Rob

Он просит сделать константой, но это не помогает

Без директивы Progmem программа не ругается, но из массива «Day_Pointer» попадается не то что надо. Использовались стандартные директивы чтения а-ля:

(pgm_read_word(&Day_Pointer [val]));

И тому подобные…

Так же использовалось следующее руководство
Руководство

Замена массив на :

Код
PGM_P Day_Pointer [] PROGMEM = { DS3231_Day1,DS3231_Day2,
                                  DS3231_Day3,DS3231_Day4,
                                  DS3231_Day5,DS3231_Day6,
                                  DS3231_Day7};


Завенчалась успехом с ошибкой

Error 1 variable 'Day_Pointer' must be const in order to be put into read-only section by means of '__attribute__((progmem))' C:\Work\Protos\Task_2\Task_2.c 38 7 Rob

Хотя сама директива PGM_P подразумевает const char*
Прошу вашей помощи.

Целевой МК : Xmega32a4u
IDE: AVR Studio 6.1.2730 SP-2

Перейти на IAR не предлагать !!!

P.S Левой пяткой последнее время подумываю перейти на какие ни будь-мелкие АРМы (LPC800/LPC11xx), а то сюрпризы вроде работающего драгона по PDI только с последними ревизиями микросхем (особенно серия A1), ремонта кабеля для 50 mil для jtag ice 3 начинают утомлять...
Go to the top of the page
 
+Quote Post
Santy
сообщение Sep 20 2013, 12:12
Сообщение #2


Участник
*

Группа: Участник
Сообщений: 49
Регистрация: 30-10-07
Пользователь №: 31 879



А со стеком всё нормально?
Go to the top of the page
 
+Quote Post
MrYuran
сообщение Sep 20 2013, 12:33
Сообщение #3


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



Где-то звездочек не хватает.
Например, const*
Искать некогда, думать лень.


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
Navovvol
сообщение Sep 20 2013, 12:41
Сообщение #4


Частый гость
**

Группа: Участник
Сообщений: 105
Регистрация: 9-09-11
Пользователь №: 67 080



Мда.. я в со Флешем ваще не дружу. может так надо ?
Код
PROGMEM const char *Day_Pointer []
{  
  DS3231_Day1,DS3231_Day2,
  DS3231_Day3,DS3231_Day4,
  DS3231_Day5,DS3231_Day6,
  DS3231_Day7;
} //



Сообщение отредактировал Navovvol - Sep 20 2013, 12:42
Go to the top of the page
 
+Quote Post
mdmitry
сообщение Sep 20 2013, 15:07
Сообщение #5


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

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



Это смотрели? Стоит посмотреть и здесь. Поиск помогает rolleyes.gif (Data in Program Space).


--------------------
Наука изощряет ум; ученье вострит память. Козьма Прутков
Go to the top of the page
 
+Quote Post
Yoruk91
сообщение Sep 20 2013, 16:09
Сообщение #6





Группа: Участник
Сообщений: 11
Регистрация: 2-04-13
Пользователь №: 76 323



Цитата(mdmitry @ Sep 20 2013, 18:07) *
Это смотрели? Стоит посмотреть и здесь. Поиск помогает rolleyes.gif (Data in Program Space).


Я по этому мануалу делал. До обновления студий все было норм. А сейчас появляется точно такая же ошибка. Студия ругается именно на директиву PROGMEM. И как раз чуть выше я описывал кусочек проги сделанный по мануалу.
На текущий момент у вас самый качественный ответ

Цитата(Santy @ Sep 20 2013, 15:12) *
А со стеком всё нормально?


Сударь, программа даже компиляцию не проходит, а вы уже лезете со срывом стека

Цитата(mdmitry @ Sep 20 2013, 18:07) *
Это смотрели? Стоит посмотреть и здесь. Поиск помогает rolleyes.gif (Data in Program Space).


Да я смотрел эти мануалы. Но они уже устарели. Где то в апреле компилятор обновили. Как раз с этого момента перед данными во флеше нкжно дописывать CONST
Go to the top of the page
 
+Quote Post
Santy
сообщение Sep 20 2013, 16:27
Сообщение #7


Участник
*

Группа: Участник
Сообщений: 49
Регистрация: 30-10-07
Пользователь №: 31 879



Без директивы Progmem программа не ругается, но из массива «Day_Pointer» попадается не то что надо.
Если программа компиляцию не проходит откуда извесно, что попадает из массива «Day_Pointer».
Go to the top of the page
 
+Quote Post
Yoruk91
сообщение Sep 20 2013, 16:43
Сообщение #8





Группа: Участник
Сообщений: 11
Регистрация: 2-04-13
Пользователь №: 76 323



Цитата(Santy @ Sep 20 2013, 19:27) *
Без директивы Progmem программа не ругается, но из массива «Day_Pointer» попадается не то что надо.
Если программа компиляцию не проходит откуда извесно, что попадает из массива «Day_Pointer».


Окончательно запутался .... Приказал компилятору

volatile const PROGMEM int Day_Pointer [] = { DS3231_Day1,DS3231_Day2,
DS3231_Day3,DS3231_Day4,
DS3231_Day5,DS3231_Day6,
DS3231_Day7};

Он вроде проглотил ... А если грузить .map файл , то студия ругнеться, при clean ->rebuild отпускает.
Директива проекта - корень ЦЭ ....
Go to the top of the page
 
+Quote Post
mdmitry
сообщение Sep 20 2013, 20:11
Сообщение #9


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

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



Цитата(Yoruk91 @ Sep 20 2013, 20:43) *
volatile const PROGMEM int Day_Pointer [] = { DS3231_Day1,DS3231_Day2,
DS3231_Day3,DS3231_Day4,
DS3231_Day5,DS3231_Day6,
DS3231_Day7};

Поясните, что хотели сделать этими определениями (volatile const)?


--------------------
Наука изощряет ум; ученье вострит память. Козьма Прутков
Go to the top of the page
 
+Quote Post
Tarbal
сообщение Sep 20 2013, 20:47
Сообщение #10


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

Группа: Свой
Сообщений: 1 351
Регистрация: 21-05-10
Пользователь №: 57 439



Надо эту переменную тоже сделать константой.

const char* Day_Pointer [] PROGMEM = { DS3231_Day1,DS3231_Day2,
DS3231_Day3,DS3231_Day4,
DS3231_Day5,DS3231_Day6,
DS3231_Day7};

А почему не сделать так?
const char Day_Pointer [] [5]PROGMEM = {
"Sun ",
"Mon ",
"Tue ",
"Wed ",
"Thu ",
"Fri ",
"Sat "};



После компиляции в файле *.map обязательно проверьте в какой сегмент попали данные.

Цитата(mdmitry @ Sep 21 2013, 00:11) *
Поясните, что хотели сделать этими определениями (volatile const)?


Методом тыка пытались отгадать ответ. volatile сюда никаким боком не относится.

volatile предназначено для декларации переменных, которые не меняются в программе, но могут измениться из-за воздействия извне. Например регистры устройств, регистр таймера и т.д..
Она предназначена для предотвращения удаления этой переменной оптимизатором как неизменяющейся. Ведь оптимизатор не видит, что переменной что-либо присваивается.

Сообщение отредактировал Tarbal - Sep 20 2013, 23:50
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Sep 20 2013, 21:31
Сообщение #11


Гуру
******

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



А вы случайно не в режиме C++ компилируете? В этом режиме PROGMEM не работает, только __attribute__((section(".progmem"))) перед объявлением переменной. А если вы используете режим "голого" С, то в новых версиях компилятор поддерживает ключевое слово __flash со всеми вытекающими вкусностями, включая доступ к таким переменным без __pgm_read_xxxx()


--------------------
На любой вопрос даю любой ответ
"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
Yoruk91
сообщение Sep 21 2013, 03:13
Сообщение #12





Группа: Участник
Сообщений: 11
Регистрация: 2-04-13
Пользователь №: 76 323



Уважаемые дамы и господа !
Благодарю вас за помощь.
Все оказалось намного проще, чем ожидалось !

//Дни недели
Код
const char DS3231_Day1 [] PROGMEM ="Sun ";
const char DS3231_Day2 [] PROGMEM ="Mon ";
const char DS3231_Day3 [] PROGMEM ="Tue ";
const char DS3231_Day4 [] PROGMEM ="Wed ";
const char DS3231_Day5 [] PROGMEM ="Thu ";
const char DS3231_Day6 [] PROGMEM ="Fri ";
const char DS3231_Day7 [] PROGMEM ="Sat ";


Код
const char * const Day_Pointer [] PROGMEM =  {
    DS3231_Day1,DS3231_Day2,
    DS3231_Day3,DS3231_Day4,
    DS3231_Day5,DS3231_Day6,
    DS3231_Day7};


Нужно было поставить еще один const
Go to the top of the page
 
+Quote Post

Closed TopicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


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


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