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

 
 
 
Reply to this topicStart new topic
> Поменять порядок следования переменных EEPROM
SasaVitebsk
сообщение Dec 5 2006, 22:18
Сообщение #1


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Попробовал пару способов - не пошло. Хотелось бы поменять порядок следования переменных в EEPROM. Для этого требуется что-то типа прототипа переменной объявить. Как - не знаю. Размещать вручную все переменные - нехочу.

Описываю задачу.

Имеется несколько переменных в EEPROM, один большой массив и переменная указывающая длину этого масива. По типу:

.......

uint8_t __eeprom Rollint[] = {
0xDA, 0x54, 0x00, 0x00, 0x01, 0x08, 0x07, 0x01, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x23, 0x33, 0x20, //
0xCF, 0xF0, 0xE8, 0xE2, 0xE5, 0xF2, 0x20, 0xEC, 0xE8, 0xF0, 0x20, 0xEF, 0xE0, 0xED, 0xED, 0xEE, //
0x21, 0x21, 0x21, 0x00, 0xDA, 0x45, 0x07, 0x07 //
};

uint32_t __eeprom eAdrProgEnd = sizeof(Rollint);

Так как объявлено сейчас - работает, но дело в том что этот массив может переписываться в процессе работы. По этому его надо разместить в конце EEPROM, а переменную eAdrProgEnd разместить где-нибудь перед ним. Если я механически переношу её вверх - выскакивает ошибка (оно и понятно - необъявлен Rollint). Пытался адрес закрепить типа @1, тоже ошибка, но уже линковщика.

Подскажите как это сделать правильно.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Dec 6 2006, 00:07
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Что-то порочное в самой постановке задачи.

0) В общем случае никто не гарантирует линковки в порядке упоминания переменных
1) Если массив постоянного размера, то зачем сдалась переменая - используйте прямо sizeof()
2) Если массив переменного размера и будет на ходу меняться, то какая разница, где находится
переменная - она ведь тоже будет меняться.
3) Если массив хрен знает какого размера (типа сколько влезет), то так программы вообще писать не стоит :-( - указывайте явно максимальный размер и явно инициализируйте начальный - все равно текущий придется инициализировать, так зачем с начальным извращаться?
4) ?


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Dec 6 2006, 01:27
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Цитата(zltigo @ Dec 6 2006, 00:07) *
Что-то порочное в самой постановке задачи.

0) В общем случае никто не гарантирует линковки в порядке упоминания переменных
1) Если массив постоянного размера, то зачем сдалась переменая - используйте прямо sizeof()
2) Если массив переменного размера и будет на ходу меняться, то какая разница, где находится
переменная - она ведь тоже будет меняться.
3) Если массив хрен знает какого размера (типа сколько влезет), то так программы вообще писать не стоит :-( - указывайте явно максимальный размер и явно инициализируйте начальный - все равно текущий придется инициализировать, так зачем с начальным извращаться?
4) ?


Скажу честно, я как то не надеялся на обсуждение идеи. Идею я привык оценивать сам. Причём привык очень давно. Бывает, и даже часто что я её меняю. Иногда по ходу проекта. Некоторые проекты переделывал по 4 раза. Причём без внешнего вмешательства. Так сказать элеменная база меняется, мы меняемся, взгляды меняются и т.д.

Но если Вам интересно, то выглядит так. Массив этот простирается (может простиратся) за пределы EEPROM во внешние EEPROM. По-скольку у меня m2560, а во внутреннем EEPROMе занято очень немного места, то я не считаю правильным выкидывать свободное место во внутреннем. Переменная eAdrProgEnd показывает ТЕКУЩИЙ занятый объём. При трансляции он совпадает с объёмом занятом в EEPROM. В процессе работы это значение может быть больше свободного места. Тогда п/п берущая значение будет добирать его с внешних источников.

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

Кстати посмотрел MAP файл (несколько насторожил и озадачил Ваш топик) переменные в EEPROM размещены в порядке их объявления.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Dec 6 2006, 03:55
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(SasaVitebsk @ Dec 6 2006, 00:27) *
Я не против если будут предложены другие способы решения задачи, но предпочтительным, на данный момент, являлось бы решение моей задачи.

Вариант 4 будет правильным. Указываете насколько простирается максимальный размер и первоначальный размер ручками а не sizeof() :-( неявно инициализированного массива.
Если "хочется" решить задачу не думая о правильности ее постановки, то заводите две переменные - одну где-то "после", вторую (обнуленную) гарантированно "до". При первом запуске инициализируете "до" первой и все - можете накрывать неиспользуемую неконтролируемо растущим массивом.
Несколько более прилично - в отдельный сегмент массив выделить и попросить линкер гарантированно его конце его размещать.

Цитата
Кстати посмотрел MAP файл (несколько насторожил и озадачил Ваш топик) переменные в EEPROM размещены в порядке их объявления.

А Вы не в map смотрите "как получилось", а в документ, где написано, что "так будет всегда".
А "всегда будет", если структуру-массив-union сделаете - для других случаев гарантий не предусмотрено.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
arttab
сообщение Dec 6 2006, 05:52
Сообщение #5


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

Группа: Свой
Сообщений: 1 432
Регистрация: 7-12-04
Из: Новосибирск
Пользователь №: 1 371



Может сначало зарезервировать место, а потом проиницилизировать значения?
__no_init __eeprom unsigned char Conf_BR[24] @0x01;

или нужно что то другое?


--------------------
OrCAD, Altium,IAR, AVR....
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Dec 7 2006, 21:28
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Цитата(zltigo @ Dec 6 2006, 03:55) *
Вариант 4 будет правильным. Указываете насколько простирается максимальный размер и первоначальный размер ручками а не sizeof() :-( неявно инициализированного массива.

Массив явно инициализирован, но ниже по тексту. Конечно ручками не хотелось бы. Не то чтобы я белоручка .... smile.gif
Цитата
Если "хочется" решить задачу не думая о правильности ее постановки, то заводите две переменные - одну где-то "после", вторую (обнуленную) гарантированно "до". При первом запуске инициализируете "до" первой и все - можете накрывать неиспользуемую неконтролируемо растущим массивом.
Несколько более прилично - в отдельный сегмент массив выделить и попросить линкер гарантированно его конце его размещать.


Что значит "Если "хочется" решить задачу не думая о правильности ее постановки". В чём неправильность постановки??? С удовольствием выслушаю.

Возможно я не совсем внятно объяснил задачу. Разжую.

1) Выпускается законченный блок имеющий интерфейс rs485.
2) Блок имеет ряд характеристик (в том числе мастер/слэйв) значительно меняющими его работу.
3) С пом. спец программы блок работает в любом месте с любыми характеристиками. (Признак первого включения пока мне не требовался)
4) В блоке имеется память EEPROM и некоторые другие переферийные узлы. Всё это определяется на этапе инициализации оборудования динамически. В том числе объём внешней памяти. Перепрошивать прогу не надо.
5) Часть EEPROM занято данными на момент компиляции. Причём эти данные могут менятся в процессе производства (не регулярно. например раз в пол года).
6) Существует переменная указывающая объём занятый данными. В момент компиляции/производства она соответствует длине масива находящегося во внутреннем EEPROM.
7) Поскольку компилятор видит массив, то хотелось бы указать ему автоматически расчитывать значение занятого места.

Что в данной постановке задачи неправильно?

Вижу много (естественно) обходных путей её решения. В то же время я думал существует прямой ответ на мой вопрос. Существуют ведь прототипы функций, может есть и предварительное объявление массива типа "forward". Или каким образом попросить линкер разместить сегмент в конце? Как привязать к адресам я знаю. xcl файл использую.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Dec 7 2006, 22:33
Сообщение #7


Гуру
******

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



Цитата(SasaVitebsk @ Dec 7 2006, 20:28) *
Вижу много (естественно) обходных путей её решения. В то же время я думал существует прямой ответ на мой вопрос. Существуют ведь прототипы функций, может есть и предварительное объявление массива типа "forward". Или каким образом попросить линкер разместить сегмент в конце? Как привязать к адресам я знаю. xcl файл использую.
У ИАРа для ARM есть __intrinsic int __segment_size(segment). В стоящем у меня ИАРе для AVR такой функции нет. К тому же почти уверен, что компилятор не допустит вызова функции при инициализации глобальной переменной. Могу предложить заход "из-за угла".
Код
extern void ee_size();
uint32_t __eeprom eAdrProgEnd = (uint32_t)&ee_size;

trick.s90:
    PUBLIC  ee_size
    RSEG    EEPROM_I

ee_size     EQU SIZEOF(EEPROM_I)

    END
Т.е. передавать константу из ассемблера (где можно ей присвоить размер сегмента) как адрес фиктивной функции. Это конечно нечестно, но другого способа придумать не могу :-(


--------------------
На любой вопрос даю любой ответ
"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
zltigo
сообщение Dec 8 2006, 00:12
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(SasaVitebsk @ Dec 7 2006, 20:28) *
Массив явно инициализирован, но ниже по тексту. Конечно ручками не хотелось бы. Не то чтобы я белоручка .... smile.gif

Нет! Размер массива явно НЕ указан. Если размер массива явно указать, то придется явно указывать
и количество инициализированных байтов. Неудобно, но проблемы отпадут :-(

Цитата
1) Выпускается законченный блок имеющий интерфейс rs485.

Ничего не имею против.
Цитата
2) Блок имеет ряд характеристик (в том числе мастер/слэйв) значительно меняющими его работу.
3) С пом. спец программы блок работает в любом месте с любыми характеристиками. (Признак первого включения пока мне не требовался)
4) В блоке имеется память EEPROM и некоторые другие переферийные узлы. Всё это определяется на этапе инициализации оборудования динамически. В том числе объём внешней памяти. Перепрошивать прогу не надо.

Просто святое дело!
Цитата
5) Часть EEPROM занято данными на момент компиляции. Причём эти данные могут менятся в процессе производства (не регулярно. например раз в пол года).
6) Существует переменная указывающая объём занятый данными. В момент компиляции/производства она соответствует длине масива находящегося во внутреннем EEPROM.
7) Поскольку компилятор видит массив, то хотелось бы указать ему автоматически расчитывать значение занятого места.

А вот тут уже становится все просто очень хреново. Вместо нормально описанной структуры данных блока используется неструктурированный безразмерный массив абстрактных байтов - верный путь к проблемам.
Цитата
Что в данной постановке задачи неправильно?

См.выше.
Цитата
Вижу много (естественно) обходных путей её решения.

Как выяснилось, задача таки сама поставлена "в обход" нормального подхода к делу.
Цитата
может есть и предварительное объявление массива типа
"forward".

Существует, естественно, только массив нужно явно объявить :-)


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Dec 11 2006, 00:16
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Цитата(zltigo @ Dec 8 2006, 00:12) *
А вот тут уже становится все просто очень хреново. Вместо нормально описанной структуры данных блока используется неструктурированный безразмерный массив абстрактных байтов - верный путь к проблемам.


smile.gif

Аааа.. вот в чём дело. А я то думаю что за наезд. smile.gif

Массив описать нельзя. Блок, который обрабатывает поток данных, не видит откуда они поступают. Это может быть любой интерфейс или внутренние данные(в данном случае). Данные представляют собой команды последовательно поступающие. С точки зрения программы каждая команда является структурой. Структура(команда) имеет много полей и разную длину, но первые поля совпадают. Одно из них - имя команды. Поэтому, в момент поступления команды, она сразу же определена (известны все поля). Работа идёт ч/з динамическую память и указатели. Эта часть полностью реализована и нареканий на неё у меня нет. Хотя, как это бывает обычно, есть части изделия(и программы) которые мне не нравятся. Естественно, по причине нехватки фантазии/предусмотрительности на этапе проектирования. А путь к сожалению обычен, - сначала выпускаем так и паралельно дорабатываем до нормального варианта. sad.gif

Спасибо всем ответившим. В данном случае придётся описать размерность вручную. Это будет проще. Изделие будет рабочим даже если оно будет поставлятся с пустым массивом. Массив заполнен для саморекламы изделия (я иногда такое практикую)

Для "Сергей Борщ", - спасибо за ответ. Я никогда не игнорирую ответы знающих людей, даже если они мне по каким-то соображениям не подошли. В Вашем случае я его скопировал себе (делаю для себя маленький фак чего я не знаю) Думаю, что когда-нибудь я его использую (идею) но уже в другом проекте.

Ещё раз спасибо всем что уделили мне своё время.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Dec 11 2006, 02:17
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(SasaVitebsk @ Dec 10 2006, 23:16) *
Массив описать нельзя.

Как выяснилось ниже - можно smile.gif :
Цитата
В данном случае придётся описать размерность вручную. Это будет проще. Изделие будет рабочим даже если оно будет поставлятся с пустым массивом.

и мир не рухнул smile.gif.

Цитата
С точки зрения программы каждая команда является структурой. Структура(команда) имеет много полей и разную длину, но первые поля совпадают. Одно из них - имя команды.

Для выхода из таких "положений" принято использовать вложенные структуры, union-ы и преобразование указателей.

В Вашем случае вместо безликого массива можете сделать структуру описывающую Вашу начальную "команду" и инициализировать будет проще (туднее ошибиться) и размер всегда известен,
как sizeof() описанной структуры. Ну а преобразовывать указатель на эту структуру в указатель на другую структуру или на абстрактный байтовый массив при необходимости.
Вот и все smile.gif.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post

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

 


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


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