|
|
  |
Iar и внешняя память, любая память с любым интерфейсом |
|
|
|
Mar 21 2008, 11:10
|
Участник

Группа: Участник
Сообщений: 52
Регистрация: 9-02-06
Из: Челябинск
Пользователь №: 14 160

|
Хочу легко и просто работать с внешней памятью : - определять переменные, массивы, структуры int a, char abc[10]; - читать из этой памяти примерно так temp=a; temp=abc[4]; - писать в память a=8; abc[2]=10;
При этом тип внешней памяти может быть любой (SRAM, EEPROM, Dataflash...) и интерфейс доступа тоже (spi, i2c, ногодрыжество)
Посмотрел в сторону встроенного eeprom для avr (способ общения с ней) - то что надо, но похоже все жестко описано на уровне компилятора.
Попробовал определить свой сегмент в xcl файле //************************************************************************* // Read/write segments mapped to 128K External RAM. //************************************************************************* -DextRAMSTART=000000 -DextRAMEND=01FFFF //************************************************ // Data segments. //************************************************ -Z(XDATA)extDATA=extRAMSTART-extRAMEND
Определил переменную __no_init int alpha @ "extDATA";
Обратился к ней alpha=10;
А вот как теперь объяснить компилятору что нужно сделать чтоб записать во внешнюю память число 10?
|
|
|
|
|
Mar 21 2008, 11:18
|

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

|
Цитата(Alfa @ Mar 21 2008, 14:10)  Хочу легко и просто работать с внешней памятью ... При этом тип внешней памяти может быть любой (SRAM, EEPROM, Dataflash...) и интерфейс доступа тоже (spi, i2c, ногодрыжество) Обломитесь. В некоторых простейших случаях можно на C++ c перегрузкой немножко порезвиться, а вообще "естественное" обращение к "неестественной" памяти противоестественно  .
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Mar 21 2008, 11:33
|
Участник

Группа: Участник
Сообщений: 52
Регистрация: 9-02-06
Из: Челябинск
Пользователь №: 14 160

|
Цитата(zltigo @ Mar 21 2008, 16:18)  Обломитесь. В некоторых простейших случаях можно на C++ c перегрузкой немножко порезвиться, а вообще "естественное" обращение к "неестественной" памяти противоестественно  . примерчик "перегрузки" можно? Еще мнения есть? Не может быть чтоб в такой мощной среде не было заложено возможности поизвращаться...
|
|
|
|
|
Mar 21 2008, 11:44
|

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

|
Цитата(Alfa @ Mar 21 2008, 14:33)  примерчик "перегрузки" можно? А как у Вас с С++? http://ru.wikipedia.org/wiki/Перегрузка_операций Берете книжку, читаете и делаете. Цитата Не может быть чтоб в такой мощной среде не было заложено возможности поизвращаться... А причем тут "среда", IDE и прочеее? Ну сделали IARовцы (полагаю исключительно ради попрочнее подсадить на свой компилятор определенный круг пользователе) еще некий встроенный тип для абсолютно конкретной железки, ну и что? Есть компилятор - его и изучайте.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Mar 21 2008, 11:59
|
Участник

Группа: Участник
Сообщений: 52
Регистрация: 9-02-06
Из: Челябинск
Пользователь №: 14 160

|
Цитата(zltigo @ Mar 21 2008, 16:44)  А как у Вас с С++? http://ru.wikipedia.org/wiki/Перегрузка_операций Берете книжку, читаете и делаете. у-у-у-у.... это надо подумать... Цитата(zltigo @ Mar 21 2008, 16:44)  А причем тут "среда", IDE и прочеее? Ну сделали IARовцы (полагаю исключительно ради попрочнее подсадить на свой компилятор определенный круг пользователе) еще некий встроенный тип для абсолютно конкретной железки, ну и что? Есть компилятор - его и изучайте. Изучаю. Решение сам не нашел - потому и написал сюда... Спасибо за ответ
|
|
|
|
|
Mar 21 2008, 17:59
|

Местный
  
Группа: Участник
Сообщений: 219
Регистрация: 20-11-07
Пользователь №: 32 484

|
Код struct fram_via_ssp { static void prepare() {} static void unprepare() {} static void read(unsigned addr, void * to, unsigned length) {} static void write(unsigned addr, void const * from, unsigned length) {}
typedef unsigned address_t; };
template <class T, class P> class extmemory { public: extmemory(typename P::address_t a = 0): address(a) {}
operator T(void) const { T tmp; P::read(this->address, &tmp, sizeof(tmp)); return tmp; }
extmemory & operator=(T const & rhs) { P::write(this->address, &rhs, sizeof(rhs)); return *this; }
typename P::address_t address; };
int main() { extmemory<double, fram_via_ssp> variable_in_the_fram(124);
variable_in_the_fram = 3.141592654; double q = variable_in_the_fram; return 0; } Только не ясно как отказы памяти обрабатывать. Я поэтому забросил эту идею.
|
|
|
|
|
Mar 22 2008, 18:37
|
Участник

Группа: Участник
Сообщений: 19
Регистрация: 13-09-05
Пользователь №: 8 518

|
Статья от DASMa, в догонку.
Flash_Cpp.rar ( 15.72 килобайт )
Кол-во скачиваний: 314
Сообщение отредактировал IgorKossak - Mar 23 2008, 10:04
|
|
|
|
|
Mar 24 2008, 04:20
|
Участник

Группа: Участник
Сообщений: 52
Регистрация: 9-02-06
Из: Челябинск
Пользователь №: 14 160

|
всем спасибо. особенно статья понравилась - хорошо разжевано. буду пробовать
|
|
|
|
|
May 12 2008, 14:32
|
Частый гость
 
Группа: Участник
Сообщений: 91
Регистрация: 24-08-06
Из: Москва
Пользователь №: 19 809

|
У меня вот такой вопрос новичка по Си++, почитав статью, понял что можно перегрузить операторы присваивания для получения и записи во флеш данных определенного типа, если в качестве данных выстпуает структура большого объема, и смысла нет в копировании такого объема из флеш в оперативку, которая по рамеру кот наплакал.. Используется встроенный Флеш в микроконтроллере MSP430. Приведу в качсетве примера код взятый из статьи DASM.
extern void FlashWrite (void * what, unsigned addr, unsigned objSize); extern void FlashRead (void * where, unsigned addr, unsigned objSize);
template <class T> class CFlash { public: // перегрузка оператор присваивания void operator = (T val) { int addr = (unsigned) this; // получаем адрес переменной int objSize = sizeof (T); //получаем размер переменной FlashWrite (&val, addr, objSize); // пишем переменную во флеш };
// перегрузка оператора приведения типа operator T() { T t; // создаем временный объект парметризованного класса int addr = (unsigned) this; return *((T *)addr); // возвращаем прочтенный объект }
private:
T _dummy; };
теперь во флеш мне надо записать структуру размером в сегмент флеша 512 байт
struct F{ unsigned char h; unsigned int g; ..... };
для записи во флеш использую готовый оператор
CFlash <F> F_0;
для записи одного байта мне приходится с помошью оператора извлекать всю структуру и изменять один байт где-то в другом месте, а потом присваиванием записывать новую структуру. например,
tmp = F_0; tmp.h = 9; F_0 = tmp;
А если структура размера сегмента 512 Мб, то можно ли с помошью операторов получить доступ к одтельным членам структуры? Например хочется чтобы такая запись позволила записать только один байт F_0.h = 9, как это сделать с помошью операторов C++?
Спасибо!
|
|
|
|
|
May 12 2008, 15:43
|

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

|
Цитата(asket @ May 12 2008, 17:32)  А если структура размера сегмента 512 Мб, то можно ли с помошью операторов получить доступ к одтельным членам структуры? Например хочется чтобы такая запись позволила записать только один байт F_0.h = 9, как это сделать с помошью операторов C++? Если оставить за скобками, что FlashWrite() при работе с флешем оперирует сегментами, то можно: Код struct myStruct_t { CFlash<uint8_t> h; CFlash<uint32_T> g; };
myStruct_t F0;
void Test() { F0.h = 12; F0.g = 0x1234; }
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
May 12 2008, 16:14
|
Частый гость
 
Группа: Участник
Сообщений: 91
Регистрация: 24-08-06
Из: Москва
Пользователь №: 19 809

|
Цитата(Сергей Борщ @ May 12 2008, 19:43)  Если оставить за скобками, что FlashWrite() при работе с флешем оперирует сегментами, то можно: Код struct myStruct_t { CFlash<uint8_t> h; CFlash<uint32_T> g; };
myStruct_t F0;
void Test() { F0.h = 12; F0.g = 0x1234; } Спасибо, попробывал, получилось!)) Еще вопрос, мне надо организовать во флеше хранение массива структуры вида Код #pragma dataseg = "FLASH_NODES_SEG"
struct Node_t{ CFlash <char> f[512]; };
__no_init CFlash <Node_t> Cash; __no_init CFlash <Node_t> Node[3];
#pragma dataseg = default Cash я хотел бы использовать для промежуточного хранения сегмента для записи одного или нескольких байтов, как лучше организовать запись с кэшированием? Перед записями, я так понимаю что надо старый сегмент сохранить в сегмент Cash (поскольку оперативки кот наплакал), затем стираем новый сегмент, а затем из Cash вместе с новыми байтами записываем в записываемый сегмент, как это корректно организовать на C++?
|
|
|
|
|
May 12 2008, 18:38
|

Местный
  
Группа: Участник
Сообщений: 219
Регистрация: 20-11-07
Пользователь №: 32 484

|
Цитата(asket @ May 12 2008, 20:14)  Cash я хотел бы использовать для промежуточного хранения сегмента для записи одного или нескольких байтов, как лучше организовать запись с кэшированием? Перед записями, я так понимаю что надо старый сегмент сохранить в сегмент Cash (поскольку оперативки кот наплакал), затем стираем новый сегмент, а затем из Cash вместе с новыми байтами записываем в записываемый сегмент, как это корректно организовать на C++? Может, лучше взять FRAM? Там, правда, будут такие вещи как разделяемый SPI или I2C (если туда подсоединена не только FRAM) и все прелести борьбы за ресурсы, зато никаких проблем с перезаписью одного байта
|
|
|
|
|
May 13 2008, 06:56
|
Частый гость
 
Группа: Участник
Сообщений: 91
Регистрация: 24-08-06
Из: Москва
Пользователь №: 19 809

|
Цитата(meister @ May 12 2008, 22:38)  Может, лучше взять FRAM? Там, правда, будут такие вещи как разделяемый SPI или I2C (если туда подсоединена не только FRAM) и все прелести борьбы за ресурсы, зато никаких проблем с перезаписью одного байта  Согласен, я тоже так думал, и интерфейс не помеха, и даже для этих целей подойдет EEPROM, но и там особо мест немного, а потом во флеш пустует половина адресного пространства, код у меня не такой большой как размер данных.. :-)
|
|
|
|
|
May 14 2008, 07:18
|
Частый гость
 
Группа: Участник
Сообщений: 91
Регистрация: 24-08-06
Из: Москва
Пользователь №: 19 809

|
Ладно, хорошо, допустим понадобится запись во внешную память например в тот же FRAM такой вот структуры
class CDeviceID{ public: CExtMem<unsigned int, 1> ID; // адрес - массив из 1 элемента CExtMem<unsigned char, 1> Num; // номер на шине массив из 1 элемента CExtMem<unsigned char, 20> Name; // имя устройства (20 символов) ... };
template <class T, unsigned char size> class CExtMem { public: void operator = (T val) { int addr = (unsigned) this; int objSize = sizeof (T); CSpi::Write (addr, (unsigned char *)&val, objSize); };
operator T() {
T t; unsigned addr = (unsigned) this; unsigned objSize = sizeof (T); CSpi::Read (addr, (unsigned char *)&t, objSize); return t; } T & operator [](int n) { T t; unsigned addr = (unsigned) (this + n); unsigned objSize = sizeof (T); CSpi::Read (addr, (unsigned char *)&t, objSize); return t; } private: T _dummy; };
где CExtMem - шаблон реализованный на базе DASM-кода, написанный в его статье, но включил возможность читать элементы массива, например Name[20], но побайтово писать как-то некорректно с точки зрения производительности, поэтому думаю над вопросом универсальности применения шаблонов, чтобы иметь возможность и блоком, и побайтово записывать.
Напрмер вот так deviceID.Name = "Устройство №3" или deviceID.Name[6] = '!', как это грамотно сделать на C++? Спасибо за любую помошь!
|
|
|
|
|
May 14 2008, 07:27
|

Местный
  
Группа: Участник
Сообщений: 219
Регистрация: 20-11-07
Пользователь №: 32 484

|
Цитата(asket @ May 14 2008, 11:18)  Напрмер вот так deviceID.Name = "Устройство №3" или deviceID.Name[6] = '!', как это грамотно сделать на C++? Спасибо за любую помошь! Конкретно по deviceID.Name = "Устройство №3": Код void operator=(T const *) { } deviceID.Name[6] = '!' должен возвращать l-value, operator= которого будет записывать в "специфическую" память. Я в каком-то посте писал, что эту затею бросил, ибо мозг можно сломать, тем более, что у меня там слишком много if (например, другой тред уже работает с FRAM), что делать с которыми не очень ясно в случае операторов C++ (нету эксцепшенов в IAR).
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|