|
IAR для MSP430, удобная работа с флешью |
|
|
|
Nov 20 2011, 11:00
|
Знающий
   
Группа: Участник
Сообщений: 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
|
|
|
|
|
Nov 20 2011, 19:46
|
Участник

Группа: Участник
Сообщений: 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
|
|
|
|
|
Nov 21 2011, 10:48
|
Участник

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

|
Цитата(Zelepuk @ Nov 21 2011, 10:18)  може тогда перед перезаписью байта во флеши копировать ....... Так обычно и делают. Альтернатива (если настроек мало и меняются они часто) - писать их блоками друг за другом в чистую страницу, для работы использовать последний блок, а когда страница заполнится, стирать и начинать сначала. Чуть сложнее, но помогает сэкономить ресуры флеши (она ограничена по числу перезаписей).
|
|
|
|
|
Nov 21 2011, 11:32
|
Знающий
   
Группа: Участник
Сообщений: 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
|
|
|
|
|
Nov 21 2011, 12:22
|
Участник

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

|
А что тут комментировать? Стандартная процедура, о которой говорили выше - сохранить где-то содержимое страницы, стереть ее и записать повторно, за исключением модифицируемой переменной. Просто тут для временного хранения используется другая страница флеши. Имеет ли это смысл? Трудно сказать, разве что катастрофически припрет со свободной RАМ. Все остальное в минусе - временные затраты, энергия, ресурс флеши. Чтобы выбрать оптимальный для Вас вариант, надо знать гораздо больше о количестве сохраняемых переменных, частоте их изменения, и куче других параметров.
|
|
|
|
|
Nov 21 2011, 12:31
|
Знающий
   
Группа: Участник
Сообщений: 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()
Сообщение отредактировал Zelepuk - Nov 21 2011, 12:33
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|