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

 
 
> IAR для MSP430, удобная работа с флешью
Zelepuk
сообщение Nov 19 2011, 10:11
Сообщение #1


Знающий
****

Группа: Участник
Сообщений: 634
Регистрация: 27-10-10
Пользователь №: 60 464



если какие-то особенности компилятора, может pragma какие-ниубдь, позволяющие работать с переменными во flash так же лекго как с обычными переменными?

например могу ли я объявить как-то по хитрому переменную "x", чтобы потом легко её инкрементировать в коде

x++; //например
Go to the top of the page
 
+Quote Post
2 страниц V   1 2 >  
Start new topic
Ответов (1 - 22)
SSerge
сообщение Nov 19 2011, 12:15
Сообщение #2


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

Группа: Свой
Сообщений: 1 719
Регистрация: 13-09-05
Из: Novosibirsk
Пользователь №: 8 528



Чтобы изменить содержимое флэши нужно скопировать страницу её в ОЗУ, там изменить, страницу стереть (стирается только страница целиком) и снова записать во флэш изменённые данные.
Ну и какая прагма тут может помочь?


--------------------
Russia est omnis divisa in partes octo.
Go to the top of the page
 
+Quote Post
Zelepuk
сообщение Nov 19 2011, 12:55
Сообщение #3


Знающий
****

Группа: Участник
Сообщений: 634
Регистрация: 27-10-10
Пользователь №: 60 464



Спасибо.
Дело в том, что мне требуется хранить только одну переменную в ПЗУ.
просто читаю вот такое:

...есть атрибуты, назначение которых описано в документации. То, что там написано, примерно выглядит так: Атрибут section(".infomem") функции или глобальной переменной указывает на то, что функция или ПЕРЕМЕННАЯ должна располагаться в сегменте информационной памяти.


это немного путает.

Как же тогда расположить одну переменную в ПЗУ и обращатсья к ней?
Go to the top of the page
 
+Quote Post
KARLSON
сообщение Nov 19 2011, 15:51
Сообщение #4


Знающий
****

Группа: Свой
Сообщений: 604
Регистрация: 5-05-06
Из: Нижегородская обл.
Пользователь №: 16 819



Вы можете сделать переменную во флеш по любому адресу какому захотите. Но изменить эту переменную просто проинициализировав не получиться. Нужны пароли к изменению флешь памяти. Почитайте раздел флеш память в Руководство пользователя MSP430x2xx Глава 7 стр 265.


--------------------
Кризис - это не отсутствие денег, а отсутствие идей! Учитесь и никаких кризисов не будет.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Nov 19 2011, 20:45
Сообщение #5


Гуру
******

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



QUOTE (Zelepuk @ Nov 19 2011, 15:55) *
ПЕРЕМЕННАЯ должна располагаться в сегменте информационной памяти.
Переменая может быть и константной. Для переменных во флеше это подразумевается.


--------------------
На любой вопрос даю любой ответ
"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
Zelepuk
сообщение Nov 19 2011, 22:00
Сообщение #6


Знающий
****

Группа: Участник
Сообщений: 634
Регистрация: 27-10-10
Пользователь №: 60 464



Цитата(Сергей Борщ @ Nov 19 2011, 23:45) *
Переменая может быть и константной. Для переменных во флеше это подразумевается.


плохо((( надо чтобы она могла менятся в программе) rolleyes.gif
smile3046.gif
Go to the top of the page
 
+Quote Post
dxp
сообщение Nov 20 2011, 09:33
Сообщение #7


Adept
******

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



Цитата(Zelepuk @ Nov 20 2011, 05:00) *
плохо((( надо чтобы она могла менятся в программе) rolleyes.gif
smile3046.gif

Что это за константа такая, что может меняться в программе. Тогда это не константа.


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
Zelepuk
сообщение Nov 20 2011, 11:00
Сообщение #8


Знающий
****

Группа: Участник
Сообщений: 634
Регистрация: 27-10-10
Пользователь №: 60 464



Цитата(dxp @ Nov 20 2011, 12:33) *
Что это за константа такая, что может меняться в программе. Тогда это не константа.

неправильно выразился... переменная конечно)

нашёл заветный код:

CODE

struct info_mem_s
{
union
{
struct nv_parms_s s;
int8_t x[128];
} seg_a;

struct nv_parms_s
{
int16_t variable;
}

void flash_write_int16(int16_t *ptr, int16_t value)
{
_DINT();
FCTL3 = FWKEY; /* Lock = 0 */
FCTL1 = FWKEY | WRT;
*((int16_t *) ptr) = value; /* Program the flash */
}


затем пишу во флешь так в функции main():

CODE

flash_write_int16((int *) &(nv_parms.seg_a.s.variable), (int16_t)1000);


я думаю вопрос с записью решён.

Как теперь можно прочитать эту переменную из флеши?

Сообщение отредактировал Zelepuk - Nov 20 2011, 18:13
Go to the top of the page
 
+Quote Post
=DS=
сообщение Nov 20 2011, 19:46
Сообщение #9


Участник
*

Группа: Участник
Сообщений: 54
Регистрация: 25-09-07
Пользователь №: 30 836



Цитата(Zelepuk @ Nov 20 2011, 15:00) *
flash_write_int16((int *) &(nv_parms.seg_a.s.variable), (int16_t)1000);

я думаю вопрос с записью решён.

Как теперь можно прочитать эту переменную из флеши?

Прочитать-то просто: int x = nv_parms.seg_a.s.variable;
Но Вы, кажется, не понимаете, как работает флеш. Записать значение по любому адресу в ней можно без проблем, но только один раз и в чистую (все биты равны единице). При попытке повторной записи туда же другого значения старое не затрется - те биты, что были ранее сброшены в ноль, так и останутся. Нужно снова проинициализировать (стереть) память перед записью нового значения, а сделать это можно только со всей страницей целиком, а не с отдельным байтом.

Сообщение отредактировал =DS= - Nov 20 2011, 19:59
Go to the top of the page
 
+Quote Post
Zelepuk
сообщение Nov 21 2011, 06:18
Сообщение #10


Знающий
****

Группа: Участник
Сообщений: 634
Регистрация: 27-10-10
Пользователь №: 60 464



спасибо, но как же быть тогда?
може тогда перед перезаписью байта во флеши копировать содержимое страницы в RAM, затем переписывать содержимое байта и затем снова переписывать всю страницу во флеши?

Подскажите решение...
Go to the top of the page
 
+Quote Post
=DS=
сообщение Nov 21 2011, 10:48
Сообщение #11


Участник
*

Группа: Участник
Сообщений: 54
Регистрация: 25-09-07
Пользователь №: 30 836



Цитата(Zelepuk @ Nov 21 2011, 10:18) *
може тогда перед перезаписью байта во флеши копировать .......

Так обычно и делают. Альтернатива (если настроек мало и меняются они часто) - писать их блоками друг за другом в чистую страницу, для работы использовать последний блок, а когда страница заполнится, стирать и начинать сначала. Чуть сложнее, но помогает сэкономить ресуры флеши (она ограничена по числу перезаписей).
Go to the top of the page
 
+Quote Post
Zelepuk
сообщение Nov 21 2011, 11:32
Сообщение #12


Знающий
****

Группа: Участник
Сообщений: 634
Регистрация: 27-10-10
Пользователь №: 60 464



нашёл интересный код по теме поста:

CODE
// ***********************************************************************
// This routine makes the flash looks like EEPROM. It will erase and
// replace just one word
// This routine copies will erase SEGA and then image SEGB to SEGA
// It will then erase SEGB and copy from SEGA back to SEGB all 128 bytes
// except the one to be replaced.
// ***********************************************************************
void flash_replace16(int16_t *ptr, int16_t word)
{
int *read_ptr;
int *write_ptr;
int w;

//Optimise the case where the new and old values are the same
if (*ptr == word)
return;
flash_clr((int *) FSEG_A);

_DINT();
//Set to write mode to prepare for copy
FCTL3 = FWKEY; /* Lock = 0 */
FCTL1 = FWKEY | WRT;

//Copy block B to A
read_ptr = (int *) FSEG_B;
write_ptr = (int *) FSEG_A;
for (w = 0; w < 64; w++)
*write_ptr++ = *read_ptr++;
flash_clr((int *) FSEG_B);

//Set to write mode to prepare for copy
FCTL3 = FWKEY; /* Lock = 0 */
FCTL1 = FWKEY | WRT;

//Copy block A to B, slipping in the new value at the right location
read_ptr = (int *) FSEG_A;
write_ptr = (int *) FSEG_B;
for (w = 0; w < 64; w++, read_ptr++, write_ptr++)
{
if (write_ptr == ptr)
*write_ptr = word;
else
*write_ptr = *read_ptr;
}
flash_secure();
_EINT();
}


как я понял, эта функция то, что мне нужно
Прошу прокоментировать

Сообщение отредактировал Zelepuk - Nov 21 2011, 11:32
Go to the top of the page
 
+Quote Post
=DS=
сообщение Nov 21 2011, 12:22
Сообщение #13


Участник
*

Группа: Участник
Сообщений: 54
Регистрация: 25-09-07
Пользователь №: 30 836



А что тут комментировать? Стандартная процедура, о которой говорили выше - сохранить где-то содержимое страницы, стереть ее и записать повторно, за исключением модифицируемой переменной. Просто тут для временного хранения используется другая страница флеши. Имеет ли это смысл? Трудно сказать, разве что катастрофически припрет со свободной RАМ. Все остальное в минусе - временные затраты, энергия, ресурс флеши. Чтобы выбрать оптимальный для Вас вариант, надо знать гораздо больше о количестве сохраняемых переменных, частоте их изменения, и куче других параметров.
Go to the top of the page
 
+Quote Post
Zelepuk
сообщение Nov 21 2011, 12:31
Сообщение #14


Знающий
****

Группа: Участник
Сообщений: 634
Регистрация: 27-10-10
Пользователь №: 60 464



спасибо за ответы, я разбираю код для MSP430
так вот есть такая конструкция
CODE
#define __infomem___ Pragma("location=\"INFO\"")

__infomem__ const struct info_mem_s nv_parms


и затем

CODE
flash_write_int16((int *) &(nv_parms.seg_a.s.variable), nv_parms.seg_a.s.variable & ~(1 << 2));


получается: обявили константу во флеши и затем записали на её место что-то...
верно?
не совсем понятно как потом прочитать то что записали через flash_write_int16()

smile3046.gif

Сообщение отредактировал Zelepuk - Nov 21 2011, 12:33
Go to the top of the page
 
+Quote Post
MrYuran
сообщение Nov 21 2011, 13:01
Сообщение #15


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



Цитата(Zelepuk @ Nov 21 2011, 16:31) *
не совсем понятно как потом прочитать то что записали через flash_write_int16()

Берете адрес ваших данных и читаете без всяких чудес.


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
Zelepuk
сообщение Nov 21 2011, 13:11
Сообщение #16


Знающий
****

Группа: Участник
Сообщений: 634
Регистрация: 27-10-10
Пользователь №: 60 464



Цитата(=DS= @ Nov 20 2011, 22:46) *
Прочитать-то просто: int x = nv_parms.seg_a.s.variable;
Но Вы, кажется, не понимаете, как работает флеш. Записать значение по любому адресу в ней можно без проблем, но только один раз и в чистую (все биты равны единице). При попытке повторной записи туда же другого значения старое не затрется - те биты, что были ранее сброшены в ноль, так и останутся. Нужно снова проинициализировать (стереть) память перед записью нового значения, а сделать это можно только со всей страницей целиком, а не с отдельным байтом.


пытаюсь после манипуляций описаных выше (в частности flash_write_int16()) прочитать записанное значение

int x = nv_parms.seg_a.s.variable;
вывожу 'x' на дисплей: нули((

P.S. дисплей выводит правильно
Go to the top of the page
 
+Quote Post
=DS=
сообщение Nov 21 2011, 13:43
Сообщение #17


Участник
*

Группа: Участник
Сообщений: 54
Регистрация: 25-09-07
Пользователь №: 30 836



CODE
#define __infomem___ Pragma("location=\"INFO\"")

Подмена на __infomem___ прагмы "location="INFO"" . Просто для удобства чтения и модификации. Но тут могут быть зарыты грабли. В частности, этот текст может быть несовместим с вышеописанной процедурой. Надо смотреть распределение флеш памяти для конкретного кристалла. Секция INFO включает в себя сегменты A, B (C, D в зависимости от кристалла)

CODE
__infomem__ const struct info_mem_s nv_parms

Разместить стуктуру nv_parms типа info_mem_s в памяти в секции INFO. Здесь надо проверить, как расположены в памяти входящие в INFO сегменты INFOA, INFOB (C, D). Компилятор расположит структуру nv_parms в начале секции INFO, а в серии 2хх там расположена секция D, например, в то время как flash_replace16 подразумевает, что данные хранятся в секции В. Можно не париться и прямо указать Pragma("location=\"INFOB\"")

CODE
flash_write_int16((int *) &(nv_parms.seg_a.s.variable), nv_parms.seg_a.s.variable & ~(1 << 2));


>>получается: обявили константу во флеши и затем записали на её место что-то...верно?
Не совсем так. Скорее жестко привязали имя и местоположение структуры к определенному адресу памяти. Делают так, потому что TI специально выделяют зону флеш-памяти именно для этих целей. У нее уменьшен размер страницы и увеличено количество возможных перезаписей по сравнению с основной страницей


JTAG есть? Давайте ВЕСЬ код, относящися к теме, тип кристалла.
Go to the top of the page
 
+Quote Post
Zelepuk
сообщение Nov 21 2011, 16:48
Сообщение #18


Знающий
****

Группа: Участник
Сообщений: 634
Регистрация: 27-10-10
Пользователь №: 60 464



Спасибо за подсказки. Всё заработало. Кристалл F47187
непонятно только почему не работает конструкция

CODE
void flash_write_int16(int16_t *ptr, int16_t value)
{
_DINT();
FCTL3 = FWKEY; /* Lock = 0 */
FCTL1 = FWKEY | WRT;
*((int16_t *) ptr) = value; /* Program the flash */
}


когда применяю её вместо flash_replace16()

Сообщение отредактировал Zelepuk - Nov 21 2011, 16:53
Go to the top of the page
 
+Quote Post
=DS=
сообщение Nov 21 2011, 18:33
Сообщение #19


Участник
*

Группа: Участник
Сообщений: 54
Регистрация: 25-09-07
Пользователь №: 30 836



Цитата(Zelepuk @ Nov 21 2011, 20:48) *
Спасибо за подсказки. Всё заработало. Кристалл F47187
непонятно только почему не работает конструкция

CODE
void flash_write_int16(int16_t *ptr, int16_t value)
}


когда применяю её вместо flash_replace16()

Возможно, потому что вы оставили флеш в режиме записи?
По завершении записи надо дать команды
FCTL1 = FWKEY;
FCTL3 = FWKEY | LOCK;

Еще одна вещь, о которой не надо забывать - если собака работает, перед записью во флеш ее надо отключать, а то взбрыкнуть может капитально.

Go to the top of the page
 
+Quote Post
Zelepuk
сообщение Nov 22 2011, 20:35
Сообщение #20


Знающий
****

Группа: Участник
Сообщений: 634
Регистрация: 27-10-10
Пользователь №: 60 464



Цитата(=DS= @ Nov 21 2011, 15:22) *
А что тут комментировать? Стандартная процедура, о которой говорили выше - сохранить где-то содержимое страницы, стереть ее и записать повторно, за исключением модифицируемой переменной. Просто тут для временного хранения используется другая страница флеши. Имеет ли это смысл? Трудно сказать, разве что катастрофически припрет со свободной RАМ. Все остальное в минусе - временные затраты, энергия, ресурс флеши. Чтобы выбрать оптимальный для Вас вариант, надо знать гораздо больше о количестве сохраняемых переменных, частоте их изменения, и куче других параметров.


если предположить что таких переменных для хранения не более десяти. Частота изменения около 15 минут.

-наверное лучше написать функцию которая сразу меняет 10 переменных во флеши, чтобы как-то сбереч ресурс флеши?
-при перезаписи каждые 15 минут и количестве циклов флеши 100 000(как у MSP430) получается имеем всего 25000 часов такой работы, после чего флешь загнётся...

наверное лучше на какую-то внешнюю ПЗУ перейти.
Go to the top of the page
 
+Quote Post
=DS=
сообщение Nov 23 2011, 00:53
Сообщение #21


Участник
*

Группа: Участник
Сообщений: 54
Регистрация: 25-09-07
Пользователь №: 30 836



Цитата(Zelepuk @ Nov 23 2011, 00:35) *
-при перезаписи каждые 15 минут и количестве циклов флеши 100 000(как у MSP430) получается имеем всего 25000 часов такой работы, после
наверное лучше на какую-то внешнюю ПЗУ перейти.

Не так все плохо. Там 255 ячеек памяти в инфо области, прежде чем ее стирать можно заполнить 25 - 10 блоками настроек в завистимости от их типа, что уже дает 250000-500000 часов работы, а если вы еще заранее знаете, что часть из них будет меняться очень редко, то можно их сгруппироать и выиграть еще больше.
Или поставить кондер побольше по питанию и держать быстро меняющиеся настройки в ОЗУ, а во флеш их писать при пропадании питания.

Сообщение отредактировал =DS= - Nov 23 2011, 01:04
Go to the top of the page
 
+Quote Post
Zelepuk
сообщение Nov 23 2011, 05:58
Сообщение #22


Знающий
****

Группа: Участник
Сообщений: 634
Регистрация: 27-10-10
Пользователь №: 60 464



Цитата(=DS= @ Nov 23 2011, 03:53) *
Не так все плохо. Там 255 ячеек памяти в инфо области, прежде чем ее стирать можно заполнить 25 - 10 блоками настроек в завистимости от их типа, что уже дает 250000-500000 часов работы...


можно по подробнее об этом?
Go to the top of the page
 
+Quote Post
Дмитрий К.
сообщение Nov 23 2011, 07:11
Сообщение #23


Участник
*

Группа: Участник
Сообщений: 24
Регистрация: 6-05-06
Из: Москва
Пользователь №: 16 848



QUOTE (Zelepuk @ Nov 23 2011, 08:58) *
можно по подробнее об этом?

имеется ввиду такая последовательность:
- стереть страницу
- записать данные (10 байт) со смещением 0x00 (начало страницы),
- через 15 мин записать данные (10 байт) со смещением 0x0A,
- через 15 мин записать данные (10 байт) со смещением 0x14,
- ... так 50 раз
- страница заполнилась, стирание всей страницы

это для обычной страницы по 512 байт (не INFO),
для INFO размер 64 байта
Go to the top of the page
 
+Quote Post

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

 


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


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