sonycman 1 7 июня, 2010 Опубликовано 7 июня, 2010 · Жалоба Доброго времени суток! Вот думаю использовать регистры бэкап домена. Как бы прозрачнее это сделать, в идеале так, чтобы работа с ними не отличалась от работы с ячейками обычного ОЗУ? Можно ли это? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
baralgin 0 7 июня, 2010 Опубликовано 7 июня, 2010 · Жалоба Из RM0008: Backup data register x (BKP_DRx) (x = 1 ..42) Address offset: 0x04 to 0x28, 0x40 to 0xBC Первые 10 слов лежат подряд, остальные через интервал. Можно рассматривать как два массива с адресами (BKP_BASE + 0x0004) и (BKP_BASE + 0x0040) соответственно. Думаю около того: volatile uint32_t* BKPPartOne = (volatile uint32_t*)(BKP_BASE + 0x0004); BKPPartOne[0] = 0x1234; BKPPartOne[1] = 0x2345; ... BKPPartOne[9] = 0xXXXX; Не проверял, но по идее должно работать :) . Если нужно одним массивом, то можно завернуть это дело в класс с оператором []. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rezident 0 7 июня, 2010 Опубликовано 7 июня, 2010 · Жалоба Стесняюсь спросить, а компиляторы про эту фичу не знают? А то вдруг они в курсе дела и используют ее по своему собственному разумению :laughing: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sonycman 1 9 июня, 2010 Опубликовано 9 июня, 2010 · Жалоба Спасибо за советы. Реализация в виде дефайнов слишком простая и неудобная - всё надо делать ручками. А вот обёртка в виде класса способна дать некое удобство и автоматизацию, но накладные расходы памяти будут совсем не кстати. Да и если с переопределением dword, word и byte проблем не вижу, то как реализовать в классе работу со структурами я не знаю :( Наверное создам пока обычную структуру в памяти, и буду её время от времени записывать/считывать из энергонезависимого озу. Насчёт компиляторов не в курсе. Работаю в RealView, а он совсем не отличается широкой поддержкой всяких хитрых фич, в отличие от IAR :( Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
baralgin 0 9 июня, 2010 Опубликовано 9 июня, 2010 (изменено) · Жалоба А вот обёртка в виде класса способна дать некое удобство и автоматизацию, но накладные расходы памяти будут совсем не кстати. Накладных расходов памяти не будет, только кода(и времени доступа). Сделать класс со статическими Set и Get для каждого члена "структуры", всё описать в хидере и после оптимизатора там будет очень компакный код. Собственно объект класса даже создавать не нужно, т.к. все методы будут статическими. Хотя никто не мешает так же завернуть это дело в static inline си-функции. Вопрос чисто эстетический :) . Наверное создам пока обычную структуру в памяти, и буду её время от времени записывать/считывать из энергонезависимого озу. По моему нормальный подход. Всё равно там этой backup-памяти кот наплакал(в мелких девайсах и вовсе 10 слов). Можно сделать универсальные: Save(const void* inptr, size_t bytes) и Load(void* outptr, size_t bytes) и грузить туда любые конструкции. Изменено 9 июня, 2010 пользователем baralgin Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
adnega 11 9 июня, 2010 Опубликовано 9 июня, 2010 · Жалоба помним, что слова BKP_DRx 16-битные и между ними есть 16-битные пустоты. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
baralgin 0 9 июня, 2010 Опубликовано 9 июня, 2010 · Жалоба adnega так именно из-за этого то и весь сыр-бор разгорелся (ну и также из-за пробела между двумя "банками", который было бы желательно убрать). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
adnega 11 10 июня, 2010 Опубликовано 10 июня, 2010 · Жалоба Мне кажется, что "прозрачность" будет зависеть от того каким объемом данных оперируешь и как часто. - Если до 16 бит, то определяем структуру и обращаемся к элементам структуры. - Если больше, то завести удобную память - писать-читать из этой памяти. Перед чтением использовать load(byte *data), после записи save(byte *data). load и save цена за "прозрачность". Для хранения параметров устройства использовал load/save. И прозрачно, и логично. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sonycman 1 10 июня, 2010 Опубликовано 10 июня, 2010 · Жалоба Ну, необходимость вызова функций Load\Save и "прозрачность" как то не совсем вяжутся. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
adnega 11 10 июня, 2010 Опубликовано 10 июня, 2010 · Жалоба Если под "прозрачностью" понимать непрерывность области данных, то это одно из решений решение. Если нужен пословный доступ (по 16 бит), то можно написать необходимое число дефайнов. Сам не пользовался, но кажется можно написать обработчик исключительной ситуации... Например, обращаемся к несуществующему региону памяти (виртуальной батареечной памяти) как батареечной памяти. Обрабатываем исключение - если адреса из виртуальной батареечной памяти, то осуществляем доступ к реальной. Накладненько, но вроде "прозрачно". Так надо? Будет работать? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sonycman 1 10 июня, 2010 Опубликовано 10 июня, 2010 · Жалоба Нет, в моём понимании "прозрачность" - это когда работа со специфическими данными осуществляется точно так же, как и с обычными. Пример: dword a = 100; NON_VOLATILE b = 50; if (b < a) b = a; и т.д. А ещё лучше было бы: NON_VOLATILE dword b; NON_VOLATILE struct { dword a; word b; byte c[5]; } timer; Тут мы одновременно задаём тип данных и его размер. Но это уже даже не Си, наверное... Я не знаю, как этого добиться на Си или Си++ :( Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
adnega 11 11 июня, 2010 Опубликовано 11 июня, 2010 · Жалоба Добился-таки "прозрачности", но на lpc1768. Проверял так: BYTE *bat; bat = (BYTE *)0x30000000; // несуществующая память bat[0]=0x5A; С позиций ядра bat[0]=num есть STR rc, [ro] rc - хранит число num, ro - хранит адрес назначения bat+0 Запись по несуществующему адресу вызывает исключение. В обработчике исключения подменяю ro на нужную ячейку памяти и выхожу (регистры R0-R3, R12 "проблемного участка" доступны через стек, остальные - напрямую). Команда STR выполняется еще раз, но уже с новым адресом. У данного подхода есть ряд минусов: - нужен контроллер с MPU. на STM32 не смог получить исключение в месте, где произвожу запись. - поскольку rc и ro заранее не известны (впрочем команда тоже может быть не STR), то нужно анализировать инструкцию, которая привела к сбою. - после выполнения инструкции параметры портятся, поэтому инструкцию лучше эмулировать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Serj78 0 14 декабря, 2010 Опубликовано 14 декабря, 2010 · Жалоба А у кого- нибудь получилось записать в эти регистры- хоть что- нибудь? Я попробовал- нифига не выходит. В лоб, по крайней мере: BKP->DR2=2222; a=BKP->DR2; В отладчике сморю а=0... и BKP_DR2=0.... и переправить его руками из отладчика не получается?? Управляющие регистры BKP_CR и BKP_CSR обнулены.. Нифига не понимаю.. Может, что-то не так делаю? Компилятор Keil 4.12 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
adnega 11 14 декабря, 2010 Опубликовано 14 декабря, 2010 · Жалоба А у кого- нибудь получилось записать в эти регистры- хоть что- нибудь? Я попробовал- нифига не выходит. В лоб, по крайней мере: BKP->DR2=2222; a=BKP->DR2; В отладчике сморю а=0... и BKP_DR2=0.... и переправить его руками из отладчика не получается?? Управляющие регистры BKP_CR и BKP_CSR обнулены.. Нифига не понимаю.. Может, что-то не так делаю? Компилятор Keil 4.12 Необходимые питание и клоки включены? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zoddy 0 14 декабря, 2010 Опубликовано 14 декабря, 2010 · Жалоба А у кого- нибудь получилось записать в эти регистры- хоть что- нибудь? Я так и делаю BKP->DRx = data; data = BKP->DRx; Все работает! Скорее всего вы не разрешили запись в BKP. Что-то типа этого... RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP | RCC_APB1Periph_PWR,ENABLE); // вкл тактирование нужной периферии PWR_BackupAccessCmd(ENABLE);// разрешаем доступ к BKP Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться