|
IAR AVR 4.10A, как обеспечить доступ к EEPROM |
|
|
|
 |
Ответов
|
Mar 23 2005, 12:23
|
Участник

Группа: Свой
Сообщений: 32
Регистрация: 26-11-04
Из: Одесса, Украина
Пользователь №: 1 240

|
2 Тумблер:
А что в таком случае мешает использовать CRC или прочие алгоритмы контроля целостности данных? И для особо важных данных писать резервные копии?
А то, что Вы привели, относится к любым типам памяти, будь то RAM, eeprom или HDD. А не к способу их описания.
|
|
|
|
|
Mar 24 2005, 11:34
|

Частый гость
 
Группа: Свой
Сообщений: 146
Регистрация: 4-11-04
Из: Московская область
Пользователь №: 1 040

|
Цитата(Alex_St @ Mar 23 2005, 15:23) А что в таком случае мешает использовать CRC или прочие алгоритмы контроля целостности данных? И для особо важных данных писать резервные копии? Совершенно верно. Так делаю я - также как и Билли Гейтс. Делаем резервные копии в количестве N штук. Снабжаем каждую CRC16. Хочется CRC32, но для avr это все таки затруднительно. Фактически, алгоритм такой же (или очень похожий) как у FAT. А теперь попробуйте описать это переменной вида: int my_var; Конечно, можно попытаться. Но это черезвычайно не удобно. Эта переменная должна быть удвоена, утроена и.т.п. Как обратится к ее конкретному образу? Или придется описывать класс MY_INT_VAR и перегружать все операции. Или что-то вроде: int my_var_1; int my_var_2; /* где то далеко от _1 - но ГДЕ ? */ ... А потом массив указателей. Что-то это все не красиво. Гораздо легче и понятней: #define ADDR_MY_VAR 0x..... #define OFFSET1 0x... #define OFFSET2 0x... а потом write_eerpom (word addr, byte dat, word offset); byte read_eerpom (word addr, word offset); Все просто, понятно и точно известно - где каждая переменная и где каждая из таблиц данных (я решил сохранить это определение, поскольку воспользовался алгоритмом как у FAT) Цитата(Alex_St @ Mar 23 2005, 15:23) А то, что Вы привели, относится к любым типам памяти, будь то RAM, eeprom или HDD. А не к способу их описания. Мне кажется, вы сами себе противоречите. Уж конечно, описание переменной в RAM сильно отличается от того, что на HD. То, что на HD вообще как бы и не описывается - туда доступ "описанием" нельзя обеспечить. К HD можно обратиться, как к внешнему устройству. И к eeprom я предлагаю обращаться также. Кроме того, RAM с одной стороны и HD, eeprom с другой - существенно разные памяти по степени "опастности". Дело в том, что в случае сбоя и после перезапуска RAM обновляется и все OK. А HD и eeprom запоминают неверный результат и в этом все дело. Вот и получается, что для работы с ними я выбрал сходные алгоритмы. По моему, это естественно. На мой взгляд, странно предложить другое. Применив "FAT-алгоритм" мы вдруг с удивлением обнаружим что: 1. мы можем работать с частично разрушенным физически (навсегда) eeprom 2. мы можем восстанавливать разрушенные (по любым причинам)участки eeprom 3. мы можем не ставить больше системный монитор (экономия $0.5/шт) 4. мы не нуждаемся в средствах бесперебойного питания 5. мы можем наслаждаться красивым алгоритмом который изобрели сами (увы - мы были не первые, но все-таки) Кстати - "FAT-алгоритм" работает в IBM-PC, да еще как!!!!! Просто мы не знаем об этом. Но однажды, когда посыпался мой Fujitsu - 20гб, я вдруг получил сообщение: что то вроде: "Обе фат коррупт, не могу починить..." После этого диск я сдал назад в Техмаркет, а сам стал делать от 3 до 6 дублей в eeprom <_<
--------------------
- ЗАМЕНЯТЬ ДЕТАЛИ НА ХОДУ ВОСПРЕЩАЕТСЯ !!! -
|
|
|
|
|
Mar 24 2005, 13:57
|

Adept
     
Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343

|
Цитата(-Tумблер- @ Mar 24 2005, 17:34) Совершенно верно. Так делаю я - также как и Билли Гейтс. Делаем резервные копии в количестве N штук. Снабжаем каждую CRC16. Хочется CRC32, но для avr это все таки затруднительно.
[...]
Или придется описывать класс MY_INT_VAR и перегружать все операции. А чем не нравится класс? Цитата(-Tумблер- @ Mar 24 2005, 17:34) Гораздо легче и понятней: #define ADDR_MY_VAR 0x.....
#define OFFSET1 0x... #define OFFSET2 0x... а потом write_eerpom (word addr, byte dat, word offset);
byte read_eerpom (word addr, word offset);
Все просто, понятно и точно известно - где каждая переменная и где каждая из таблиц данных (я решил сохранить это определение, поскольку воспользовался алгоритмом как у FAT) И чем это лучше? Неслабое нагромождение кода в глобаном scope. В то время как, написав класс, где для вашей переменной объявить массив копий в EEPROM, который и обслуживать: Код class TMyEEPROM_Var { public: TMyEEPROM_Var(); TMyEEPROM_Var(typename x); ... // остальной интерфейс
private: __eeprom typename CopyArray[N]; }; Тут уж и проверки сделать при обращениях, и журналирование, и все необходимые операции определить. Т.ч. снаружи это будет просто как обычная переменная. А если уж хочется и отдельные копии смотреть, то и для них функцию определить - типа: Код typename TMyEEPROM_Var::get_copy(byte intex) { return CopyArray[intex]; } Но обращаться именно в EEPROM посредством __eeprom. Только это будет тоже скрыто внутри класса. А функции явные ee_read, ee_write - это явно излишне.
--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
|
|
|
|
|
Mar 25 2005, 12:14
|

Частый гость
 
Группа: Свой
Сообщений: 146
Регистрация: 4-11-04
Из: Московская область
Пользователь №: 1 040

|
Цитата(dxp @ Mar 24 2005, 16:57) А чем не нравится класс? Обьясню - чем не нравится класс. 1 Как быть с внешними eeprom-ами ? Концепцию менять каждый раз ? Вдобавок, в некоторых проектах использовались оба типа. 2. Использую то я C. Так вышло, мне часто приходится переходить с процессора на процессор. С с++ бывают проблемы - например для Fujitsu просто нет. С переносимостью программ на С проблем (у меня) не было до сих пор. С пол-оборота всегда и везде все работает. А вот теперь серьезно: 3. Если мы озабочены сохранностью данных eeprom, то делать приходится вот что: разные таблицы-копии располагаются на разном смещении, обязательно с "проплешинами" между собой. Чтобы не портились сразу две таблицы. Дело в том, что "исследования" показали - когда данные портятся, то они и расположены рядом. Т.е. портятся смежные байты. Поэтому совет расположить подряд N копий не кажется мне удачным. Кроме того, возникнут большие затруднения написания подсчета CRC в такой концепции. В предложенном мной варианте известен начальный адрес таблицы и ее размер. А это значит удобно обратиться к такой таблице как к массиву. Причем, к любому. Хотите - к байтовому, хотите - к вордовому. Подсчет CRC дело циклическое и "длительное". Удобство доступа всерьез повлияет на скорость процедуры. Любое прямое описание переменной в С приводит к ее автоматическому размещению компилятором. Собственно, это одно из больших достоинств этого языка. Как раз это, на мой взгляд, и мешает при работе с eeprom. В этом случае удобно распределить память самому. Это не сложно, поскольку таких данных сравнительно немного. И это приведет скорей к более компактной программе - это же к ассемблеру ближе, чем к c++ Цитата(dxp @ Mar 24 2005, 16:57) ... Неслабое нагромождение кода в глобаном scope. Извините - я этот вопрос просто не понял . Понятно, что я описал идею, а не приводил в конференции исходных текстов коммерческих программ. "..Идею дал? - Наморщи ум..". Я так понял - мы оба согласились сделать "ЭТО", но с разным описанием переменных. Но это значит, размеры исполнимых кодов у нас не сильно отличаются. Причем точно известно - дополнительная "оплата" размером за ооп обязательно будет. Полагаю от 5% - 10 %. Так что кодов больше будет у Вас. Вот исходных текстов может быть больше у меня. Но это мне не тяжко. Написал отдельный модуль один раз + .def файл макроопределений. Этот модуль кочует из проекта в проект. Как впрочем и многие другие. Удачи !
--------------------
- ЗАМЕНЯТЬ ДЕТАЛИ НА ХОДУ ВОСПРЕЩАЕТСЯ !!! -
|
|
|
|
|
Mar 25 2005, 14:37
|

Adept
     
Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343

|
Цитата(-Tумблер- @ Mar 25 2005, 18:14) Цитата(dxp @ Mar 24 2005, 16:57) А чем не нравится класс? Обьясню - чем не нравится класс. 1 Как быть с внешними eeprom-ами ? Концепцию менять каждый раз ? Вдобавок, в некоторых проектах использовались оба типа. Какая разница? С внешним все равно не так работаете. И тут можно другую реализацию сделать. Впрочем, это к делу не относится.  Цитата(-Tумблер- @ Mar 25 2005, 18:14) 2. Использую то я C. Так вышло, мне часто приходится переходить с процессора на процессор. С с++ бывают проблемы - например для Fujitsu просто нет. С переносимостью программ на С проблем (у меня) не было до сих пор. С пол-оборота всегда и везде все работает. Да, переносимость - это единственное серьезное возражение, тут спорить не буду. Если она рулит, то деваться некуда.  Но не удержусь от замечания, что С++ все больше и больше завоевывает позиции, и, как следствие, компиляторов тоже все больше и больше. Причем почти полноценных - с шаблонами, неймспейсами. Цитата(-Tумблер- @ Mar 25 2005, 18:14) А вот теперь серьезно: 3. Если мы озабочены сохранностью данных eeprom, то делать приходится вот что: разные таблицы-копии располагаются на разном смещении, [...] В предложенном мной варианте известен начальный адрес таблицы и ее размер. А это значит удобно обратиться к такой таблице как к массиву. Причем, к любому. Хотите - к байтовому, хотите - к вордовому. Подсчет CRC дело циклическое и "длительное". Удобство доступа всерьез повлияет на скорость процедуры. Да нет вопросов - хочется располагать со смещением - располагайте. Хочется работать с отдельными байтами - пожалуйста, никто не запрещает. Я не понимаю, как это конфликтует с объявлением переменной с квалификатором __eeprom? Класс-то ведь не в EEPROM живет, он - в обычной памяти. А внутри него забиты адреса данных в EEPROM'е. Просто всю работу он инкапсулирует внутри себя. А данные создаете в EEPROM с помощью слова __eeprom с последующей инициализацией представления класса, где в конструкторе прописываете адреса на EEPROM. При этом нет проблем с созданием многобайтных типов (предположим, Вам понадобилось плавучку в EEPROM хранить или вообще разномастные данные - структуры). И полный статический (т.е. на этапе компиляции) контроль типов. Цитата(-Tумблер- @ Mar 25 2005, 18:14) Любое прямое описание переменной в С приводит к ее автоматическому размещению компилятором. Собственно, это одно из больших достоинств этого языка. Как раз это, на мой взгляд, и мешает при работе с eeprom. В этом случае удобно распределить память самому. Это не сложно, поскольку таких данных сравнительно немного. Ну и распределяйте, никто не возражает. Только почему бы это не делать с помощью __eeprom. Речь о том, чтобы не лазить в EEPROM руками - для этого использовать интерфейсный объект. Но данные разместить (память выделить) отдельно руками, объявив все необходимое с помощью __eeprom, и проинициализировать интерфейсный объект адресами этих данных в EEPROM. Т.е. внутри класса должны быть указатели типа __eeprom typename *. Конструктор объекта должен требовать определенное количество и тип аргументов-адресов - если забудете что-то ему передать, компилятор ругнется. Безопасность использования выше. Цитата(dxp @ Mar 24 2005, 16:57) ... Неслабое нагромождение кода в глобаном scope. Цитата(-Tумблер- @ Mar 25 2005, 18:14) Извините - я этот вопрос просто не понял . Понятно, что я описал идею, а не приводил в конференции исходных текстов коммерческих программ. "..Идею дал? - Наморщи ум..". Дело не в том, что там было не полное определение реализации дано, а только идея. Дело в том, что согласно тому стилю, присущему С, в глобальной области видимости появится куча достаточно низкоуровневого кода (функции, переменные), работа с которыми, во-первых, неудобна (надо при работе постоянно держать в голове кучу левых сущностей), во-вторых, небезопасна (т.е. через некоторое время начинаешь забывать, что там к чему и легко что-то напутать). В случае класса вся работа сокрыта внутри - снаружи как раз простой и формализованный интерфейс - пользователь не видит всего этого внутреннего "ужаса"  , который не "грузит" ему мозги и не провоцирует на ошибки.  К тому же, можно класс слелать шаблоном и не переписывать все это для разных типов. Один раз написал, и используй для разных типов. __eeprom тут попадает, как говорится, "в струю".  В общем, не агитирую, по опыту знаю, это дело не нужное, т.к. каждый работает, опираясь на собственный опыт и знания. Но точку зрения изложил, может она послужит поводом где-то и пересмотреть позицию.
--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
|
|
|
|
|
Mar 28 2005, 10:21
|

Частый гость
 
Группа: Свой
Сообщений: 146
Регистрация: 4-11-04
Из: Московская область
Пользователь №: 1 040

|
Цитата(dxp @ Mar 25 2005, 17:37) Я не понимаю, как это конфликтует с объявлением переменной с квалификатором __eeprom? Если происходит обьявление __eeprom int value; то как раз размещением переменных занимается компилятор. Это как раз мне и не подходит - для данного случая. Но я и не предполагал, что некоторая дискуссия о сохранении данных в eeprom плавно перейдет в дискуссию о применении ооп... Эти два вопроса совершенно не связаны друг с другом - каждый сам по себе. Подумав как следует - пришел я к выводу: можно было бы конечно написать класс. Но не для переменной. Класс - таблица. С параметром конструктора "TABLEi_OFFSET". Это еще "куда ни шло". Полагаю в этом случае оплата за ООП будет минимальной. А как вы собираетесь считать CRC в вашей концепции ? Составлять массив указателей на классы-переменные или делать связной список из них ? Или разименовывать поочереди ? Цитата(dxp @ Mar 25 2005, 17:37) В случае класса вся работа сокрыта внутри - снаружи как раз простой и формализованный интерфейс - пользователь не видит всего этого внутреннего "ужаса"  , который не "грузит" ему мозги и не провоцирует на ошибки.  Да это я знаю.. (ворчливо). Пользуемся, как же - когда это всерьез выгодно (шас пойдет реклама): http://spiprog.narod.ruИзвинением мне служит только то, что обращаю ваше внимание на исходные тексты, а не на что либо иное. Действительно, ООП в этом конкретном случае дает огромный выигрыш в производительности труда. И это меня волнует больше всего. Теперь о триллере. Эпиграф: "..Тебе страшно? Мне-нет...". "Малыш и Карлсон", мультфильм. И где же тут ужас: my_important_var.save_me_please (); // это у вас save_my_important_var (); // это у меня. Мне кажется, что ваши "страхи" на программу в 8К (а на самом деле в 4- инструкции AVR 16-битные) слегка преувеличены.
--------------------
- ЗАМЕНЯТЬ ДЕТАЛИ НА ХОДУ ВОСПРЕЩАЕТСЯ !!! -
|
|
|
|
Сообщений в этой теме
Sergio66 IAR AVR 4.10A Mar 17 2005, 15:52 IgorKossak Не нужно никакой функции. Просто обьявите переменн... Mar 17 2005, 16:53 Sergio66 Цитата(Sergio66 @ Mar 17 2005, 18:52)Еще один... Mar 17 2005, 16:59 KRS Цитата(Sergio66 @ Mar 17 2005, 19:59)Цитата(S... Mar 17 2005, 17:01 IgorKossak !!!
Не следует также забывать, что кол... Mar 18 2005, 09:22 -Tумблер- Цитата(Sergio66 @ Mar 17 2005, 18:52)Еще один... Mar 18 2005, 12:20 IgorKossak Цитата(-Tумблер- @ Mar 18 2005, 15:... Mar 18 2005, 15:30  KRS Цитата(IgorKossak @ Mar 18 2005, 18:30)Цитата... Mar 18 2005, 15:38   IgorKossak Цитата(KRS @ Mar 18 2005, 18:38)Это не поможе... Mar 18 2005, 15:59    KRS Цитата(IgorKossak @ Mar 18 2005, 18:59)Цитата... Mar 18 2005, 16:16     vet Цитата(KRS @ Mar 18 2005, 19:16)Откуда взялис... Mar 18 2005, 20:03     IgorKossak Цитата(KRS @ Mar 18 2005, 19:16)...Откуда взя... Mar 21 2005, 07:25 IgorKossak Существует бесконечно малое количество причин в пр... Mar 21 2005, 08:08 -Tумблер- Цитата(IgorKossak @ Mar 21 2005, 11:08)Сущест... Mar 22 2005, 07:34 IgorKossak Интересное мнение, хотя и не бесспорное.
Из под мо... Mar 23 2005, 09:27 -Tумблер- Цитата(IgorKossak @ Mar 23 2005, 12:27)лет и ... Mar 23 2005, 11:33 IgorKossak -Tумблер-, Вы похоже очень спешите читать пост и в... Mar 23 2005, 12:21     IgorKossak Далеко не единственный случай, когда программист н... Mar 28 2005, 09:29
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|