|
|
  |
Поменять порядок следования переменных EEPROM |
|
|
|
Dec 5 2006, 22:18
|
Гуру
     
Группа: Свой
Сообщений: 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, тоже ошибка, но уже линковщика.
Подскажите как это сделать правильно.
|
|
|
|
|
Dec 6 2006, 01:27
|
Гуру
     
Группа: Свой
Сообщений: 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 размещены в порядке их объявления.
|
|
|
|
|
Dec 6 2006, 03:55
|

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

|
Цитата(zltigo @ Dec 6 2006, 03:55)  Вариант 4 будет правильным. Указываете насколько простирается максимальный размер и первоначальный размер ручками а не sizeof() :-( неявно инициализированного массива. Массив явно инициализирован, но ниже по тексту. Конечно ручками не хотелось бы. Не то чтобы я белоручка .... Цитата Если "хочется" решить задачу не думая о правильности ее постановки, то заводите две переменные - одну где-то "после", вторую (обнуленную) гарантированно "до". При первом запуске инициализируете "до" первой и все - можете накрывать неиспользуемую неконтролируемо растущим массивом. Несколько более прилично - в отдельный сегмент массив выделить и попросить линкер гарантированно его конце его размещать. Что значит "Если "хочется" решить задачу не думая о правильности ее постановки". В чём неправильность постановки??? С удовольствием выслушаю. Возможно я не совсем внятно объяснил задачу. Разжую. 1) Выпускается законченный блок имеющий интерфейс rs485. 2) Блок имеет ряд характеристик (в том числе мастер/слэйв) значительно меняющими его работу. 3) С пом. спец программы блок работает в любом месте с любыми характеристиками. (Признак первого включения пока мне не требовался) 4) В блоке имеется память EEPROM и некоторые другие переферийные узлы. Всё это определяется на этапе инициализации оборудования динамически. В том числе объём внешней памяти. Перепрошивать прогу не надо. 5) Часть EEPROM занято данными на момент компиляции. Причём эти данные могут менятся в процессе производства (не регулярно. например раз в пол года). 6) Существует переменная указывающая объём занятый данными. В момент компиляции/производства она соответствует длине масива находящегося во внутреннем EEPROM. 7) Поскольку компилятор видит массив, то хотелось бы указать ему автоматически расчитывать значение занятого места. Что в данной постановке задачи неправильно? Вижу много (естественно) обходных путей её решения. В то же время я думал существует прямой ответ на мой вопрос. Существуют ведь прототипы функций, может есть и предварительное объявление массива типа "forward". Или каким образом попросить линкер разместить сегмент в конце? Как привязать к адресам я знаю. xcl файл использую.
|
|
|
|
|
Dec 7 2006, 22:33
|

Гуру
     
Группа: Модераторы
Сообщений: 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)
|
|
|
|
|
Dec 8 2006, 00:12
|

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

|
Цитата(SasaVitebsk @ Dec 7 2006, 20:28)  Массив явно инициализирован, но ниже по тексту. Конечно ручками не хотелось бы. Не то чтобы я белоручка ....  Нет! Размер массива явно НЕ указан. Если размер массива явно указать, то придется явно указывать и количество инициализированных байтов. Неудобно, но проблемы отпадут :-( Цитата 1) Выпускается законченный блок имеющий интерфейс rs485. Ничего не имею против. Цитата 2) Блок имеет ряд характеристик (в том числе мастер/слэйв) значительно меняющими его работу. 3) С пом. спец программы блок работает в любом месте с любыми характеристиками. (Признак первого включения пока мне не требовался) 4) В блоке имеется память EEPROM и некоторые другие переферийные узлы. Всё это определяется на этапе инициализации оборудования динамически. В том числе объём внешней памяти. Перепрошивать прогу не надо. Просто святое дело! Цитата 5) Часть EEPROM занято данными на момент компиляции. Причём эти данные могут менятся в процессе производства (не регулярно. например раз в пол года). 6) Существует переменная указывающая объём занятый данными. В момент компиляции/производства она соответствует длине масива находящегося во внутреннем EEPROM. 7) Поскольку компилятор видит массив, то хотелось бы указать ему автоматически расчитывать значение занятого места. А вот тут уже становится все просто очень хреново. Вместо нормально описанной структуры данных блока используется неструктурированный безразмерный массив абстрактных байтов - верный путь к проблемам. Цитата Что в данной постановке задачи неправильно? См.выше. Цитата Вижу много (естественно) обходных путей её решения. Как выяснилось, задача таки сама поставлена "в обход" нормального подхода к делу. Цитата может есть и предварительное объявление массива типа "forward". Существует, естественно, только массив нужно явно объявить :-)
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Dec 11 2006, 00:16
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
Цитата(zltigo @ Dec 8 2006, 00:12)  А вот тут уже становится все просто очень хреново. Вместо нормально описанной структуры данных блока используется неструктурированный безразмерный массив абстрактных байтов - верный путь к проблемам. Аааа.. вот в чём дело. А я то думаю что за наезд. Массив описать нельзя. Блок, который обрабатывает поток данных, не видит откуда они поступают. Это может быть любой интерфейс или внутренние данные(в данном случае). Данные представляют собой команды последовательно поступающие. С точки зрения программы каждая команда является структурой. Структура(команда) имеет много полей и разную длину, но первые поля совпадают. Одно из них - имя команды. Поэтому, в момент поступления команды, она сразу же определена (известны все поля). Работа идёт ч/з динамическую память и указатели. Эта часть полностью реализована и нареканий на неё у меня нет. Хотя, как это бывает обычно, есть части изделия(и программы) которые мне не нравятся. Естественно, по причине нехватки фантазии/предусмотрительности на этапе проектирования. А путь к сожалению обычен, - сначала выпускаем так и паралельно дорабатываем до нормального варианта. Спасибо всем ответившим. В данном случае придётся описать размерность вручную. Это будет проще. Изделие будет рабочим даже если оно будет поставлятся с пустым массивом. Массив заполнен для саморекламы изделия (я иногда такое практикую) Для "Сергей Борщ", - спасибо за ответ. Я никогда не игнорирую ответы знающих людей, даже если они мне по каким-то соображениям не подошли. В Вашем случае я его скопировал себе (делаю для себя маленький фак чего я не знаю) Думаю, что когда-нибудь я его использую (идею) но уже в другом проекте. Ещё раз спасибо всем что уделили мне своё время.
|
|
|
|
|
Dec 11 2006, 02:17
|

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

|
Цитата(SasaVitebsk @ Dec 10 2006, 23:16)  Массив описать нельзя. Как выяснилось ниже - можно  : Цитата В данном случае придётся описать размерность вручную. Это будет проще. Изделие будет рабочим даже если оно будет поставлятся с пустым массивом. и мир не рухнул  . Цитата С точки зрения программы каждая команда является структурой. Структура(команда) имеет много полей и разную длину, но первые поля совпадают. Одно из них - имя команды. Для выхода из таких "положений" принято использовать вложенные структуры, union-ы и преобразование указателей. В Вашем случае вместо безликого массива можете сделать структуру описывающую Вашу начальную "команду" и инициализировать будет проще (туднее ошибиться) и размер всегда известен, как sizeof() описанной структуры. Ну а преобразовывать указатель на эту структуру в указатель на другую структуру или на абстрактный байтовый массив при необходимости. Вот и все  .
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|