Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Ответить

Программирование flash памяти в MSP430G2553

Пн мар 11, 2019 12:47:27

Добрый день!
Хочу сохранить в постоянной Flash памяти число int от 0 до 255. Программу написал используя пример библиотеки mspflash.h но после нажатия Reset переменная "counter" не сохраняется. Не совсем понимаю как в Energia работают функции Flash.read и Flash.write.

Вот фрагмент моей программы:

#include "MspFlash.h"
#define flash SEGMENT_D

int pos=0;
int counter=0;
int p=0;

void loop() {

Flash.read(flash+(pos * sizeof(int)), (unsigned char*)&p, sizeof(int));
counter=p;

if (.............) {
counter=++counter;
} else {
counter=--counter;

}

Flash.erase(flash);

Flash.write(flash+(pos * sizeof(int)), (unsigned char*)&counter, sizeof(int));

}


Что я делаю не правильно?
С уважением, Superpanky

Re: Программирование flash памяти в MSP430G2553

Ср мар 24, 2021 12:16:04

Вот пример кода для чтения и записи во флеш память.
Код:
// Чтение из флеш памяти от adr_start, до adr_end в массив ID_RKU_R
// Значения adr_start и adr_end должны быть кратны 2, и adr_start должно быть меньше adr_end
void Read_FLASH_MEMORY(unsigned int adr_start, unsigned int adr_end)
{
    unsigned short *Flash_ptr = (unsigned short *)adr_start;// Начальный адрес флэш-памяти
    unsigned int d0;
    if ((adr_start < adr_end) && ((adr_end-adr_start) != 1)) // Защита от дурака
    {
        for (d0=0; d0<=(adr_end-adr_start)/2; d0++)
        {
            unsigned int a = adr_start+(d0*2);  // Адрес ячейки памяти = "a"
            *Flash_ptr = a;                     // Указываем на адрес ячейки памяти Flash_ptr откуда нужно читать
            ID_RKU_R[d0] = *Flash_ptr;          // Читаем в "ID_RKU[d0]" данные хранящиеся в ячейке памяти "Flash_ptr"
        }
    }
}

// Запись во флеш память от adr_start, до adr_end массив данных flash_data
// Значения adr_start и adr_end должны быть кратны 2, и adr_start должно быть меньше adr_end
void Write_FLASH_MEMORY(unsigned int adr_start, unsigned int adr_end)
{
    unsigned short *Flash_ptr = (unsigned short *)adr_start;// Начальный адрес флэш-памяти
    unsigned int d0;
    __disable_interrupt();          // Глобальное запрещение прерываний
    if ((adr_start < adr_end) && ((adr_end-adr_start) != 1)) // Защита от дурака
    {
        for (d0=0; d0<=(adr_end-adr_start)/2; d0++)
        {
            FCTL3 = FWKEY;              // Снимаем блокирующий бит
            FCTL1 = FWKEY + ERASE;      // Разрешаем стирание
            *Flash_ptr = 0;             // Фиктивная запись для стирания флеш-сегмента
            FCTL1 = FWKEY + WRT;        // Установить бит WRT для операции записи
            *Flash_ptr = flash_data[d0];// Записываем значение flash_data во флеш память с адресом Flash_ptr
            FCTL1 = FWKEY;              // Сбросить бит записи
            FCTL3 = FWKEY + LOCK;       // Устанавливаем бит блокировки
            ID_RKU_W[d0] = *Flash_ptr;  // Читаем в "ID_RKU[d0]" значение "flash_data" хранящееся в "Flash_ptr" (проверка)
            *Flash_ptr++;
        }
    }
    __enable_interrupt();           // Глобальное разрешение прерываний
}


Добавлено after 2 minutes 16 seconds:
Пример вызова подпрограммы.
Код:
    Read_FLASH_MEMORY(0x8000, 0x8400);
    Write_FLASH_MEMORY(0xA000, 0xA400);

Re: Программирование flash памяти в MSP430G2553

Ср мар 24, 2021 23:35:44

Прикольно.
В MSP430FR достаточно переменной присвоить квалификатор __persistent и всё. Хоть всю FRAM память запомни)) Но есть нюансы с защитой...

Re: Программирование flash памяти в MSP430G2553

Чт мар 25, 2021 13:14:26

Честно говоря не проверял запись в занятые адреса (например 00001c18, отвечающий за ACP_results в .map файле моего проекта), да и не советую. Лучше пользоваться теми адресами, которые прописаны в .cmd файле, а именно в распределении карты памяти, где прописано сколько и с какого адреса начинается какой либо раздел. (работать лучше в разделе FLASH)

Re: Программирование flash памяти в MSP430G2553

Пн мар 29, 2021 11:17:43

Доброго времени суток, написал небольшую прогу, но работает както не правильно. может кто подскажет в чём ошибка.
Код:
unsigned short *Flash_ptr = (unsigned short *)0x8000;// Начальный адрес флэш-памяти
/**
 * main.c
 */
int main(void)
{
   WDTCTL = WDTPW | WDTHOLD;   // stop watchdog timer
    FCTL3 = FWKEY;              // Снимаем блокирующий бит
    FCTL1 = FWKEY + ERASE;      // Разрешаем стирание
    *Flash_ptr = 0;             // Фиктивная запись для стирания флеш-сегмента
    FCTL1 = FWKEY + WRT;        // Установить бит WRT для операции записи
    *Flash_ptr = 0x4303;// Записываем значение flash_data во флеш память с адресом Flash_ptr (nop)
    *Flash_ptr++;
    *Flash_ptr = 0x1300;// Записываем значение flash_data во флеш память с адресом Flash_ptr (reti)
    FCTL1 = FWKEY;              // Сбросить бит записи
    FCTL3 = FWKEY + LOCK;       // Устанавливаем бит блокировки
//__asm (" MOV.W #0x8000,R15 ");
//__asm (" CALL &R15");
$0x8000:
    ((void(*)() )0x8000)();  // Переход по адресу 0х8000
    __no_operation();
    __no_operation();
    __no_operation();
    __no_operation();
    __no_operation();
    goto $0x8000;


Во флеш записывает всё правильно (в 8000 адрес пишет команду nop, в адрес 8002 - reti), но после ((void(*)() )0x8000)() переходит на адрес 0х0000, и благополучно там висит... Что не так?

Добавлено after 46 minutes 25 seconds:
Нашёл в чём дело. Выполняя команду выхода из адреса 0х8002, происходит переход на адрес 0х0000. Вобщем в адрес 0х8003 нужно записать куда переходить.

Добавлено after 33 minutes 36 seconds:
Нужно было вместо команды RETI (0x1300), ввести команду RETA (0x0110). Тогда выход происходит сразу после выполнения ((void(*)() )0x8000)();
Ответить