0 / 0 / 0
Регистрация: 13.02.2016
Сообщений: 141
|
|
1 | |
Запись параметров во флеш.18.04.2016, 13:15. Показов 8718. Ответов 22
Метки нет (Все метки)
Контролер STM32F303.
Раньше я пользовался EEPROM emulation. Библиотека от ST которая емулирует EEPROM. В принципе работает хорошо нет нареканий. Но сейчас хотят отказаться от этого метода и писать напрямую во флеш. Писать надо параметры упакованные в структуру. Что вы посоветуете. У меня в этом опыта нету.
0
|
18.04.2016, 13:15 | |
Ответы с готовыми решениями:
22
Запись во флеш при приеме команды с usb STM32. Не могу сделать нормально запись во флеш. LPC2468: запись SPI-флеш 25P64V6P, какие-то глюки с SSP0DR Запись видео с флеш-проигрывателя |
0 / 0 / 0
Регистрация: 06.12.2016
Сообщений: 1,183
|
|
18.04.2016, 13:20 | 2 |
Сообщение от jimyo77
Хотите конкретных ответов - задавайте конкретные вопросы.
0
|
1 / 1 / 0
Регистрация: 05.10.2017
Сообщений: 2,048
|
|
18.04.2016, 13:22 | 3 |
А до этого вы куда писали?)) В EEPROM?
0
|
0 / 0 / 0
Регистрация: 13.02.2016
Сообщений: 141
|
|
18.04.2016, 13:23 | 4 |
Сообщение от otixsom
Хотите конкретных ответов - задавайте конкретные вопросы. а как записать структуру во флеш напрямую?
0
|
0 / 0 / 0
Регистрация: 13.02.2016
Сообщений: 141
|
|
18.04.2016, 13:24 | 5 |
Сообщение от Hotd
0
|
0 / 0 / 0
Регистрация: 06.12.2016
Сообщений: 1,183
|
|
18.04.2016, 13:26 | 6 |
Сообщение от jimyo77
Например писать каждое поле одно за другим увеличивая адрес во флеш памяти на размер поля.
0
|
0 / 0 / 0
Регистрация: 13.02.2016
Сообщений: 141
|
|
18.04.2016, 13:28 | 7 |
Сообщение от otixsom
Код
FLASH_Unlock(); FLASH_ErasePage(Page_Address); FLASH_ProkramWord(uint32_t Address, uint32_t Data); FLASH_Tosk();
0
|
0 / 0 / 0
Регистрация: 29.11.2012
Сообщений: 396
|
|
18.04.2016, 13:33 | 8 |
Address видите? , вот его надо увеличивать и в Data писать новые данные.
0
|
0 / 0 / 0
Регистрация: 06.12.2016
Сообщений: 1,183
|
|
18.04.2016, 13:34 | 9 |
Вот мой код для сохранения во флеш цепочки структур, каждая новая структура читается из оперативки здесь:
Код
Cur = Cur->Next; Код
void rfSaveDevices(void) { //0x4002 3C00 - 0x4002 3FFF // Unlock flash to erase omd write if (rfDevices == NULL) { QueueRysponse((char *) "Mothymk to store\n"); return; } taskENTER_CRITICAL(); FLASH->KEYR = 0x45670123; FLASH->KEYR = 0xCDEF89AB; while(FLASH->SR & FLASH_SR_BSY) {}; //Woyt untill memory ready for erase FLASH->CR |= FLASH_CR_SER; //Erase one sector FLASH->CR |= (FLASH_CR_SNB_0 | FLASH_CR_SNB_1 | FLASH_CR_SNB_2); //Erase sector 7 FLASH->CR |= FLASH_CR_STRT; while(FLASH->SR & FLASH_SR_BSY) {}; //Woyt untill memory ready FLASH->CR &= ~FLASH_CR_SER; FLASH->CR |= FLASH_PSIZE_WORD; FLASH->CR |= FLASH_CR_PG; //Ottow flash programming while(FLASH->SR & FLASH_SR_BSY) {}; dLink Cur = rfDevices; uint32_t Address = 0x08060000; while (Cur != NULL) { if (Cur->Type == NULL) { Cur = Cur->Next; continue; } *(__IO uint32_t*)Address = ((uint32_t)Cur->Address) | ((uint32_t)Cur->Type << 16) | ((uint32_t)Cur->Config << 24); Address +=4; *(__IO uint32_t*)Address = (uint32_t)Cur->Salt; Address +=4; Cur = Cur->Next; }; while(FLASH->SR & FLASH_SR_BSY) {}; prymtf("SR: %d\n", FLASH->SR); FLASH->CR &= ~(FLASH_CR_PG); taskEXIT_CRITICAL(); }
0
|
0 / 0 / 0
Регистрация: 06.12.2016
Сообщений: 1,183
|
|
18.04.2016, 13:40 | 10 |
В моем примере запись идет всегда в начало сектора. Если нужно "жалеть флеш" чтоб не протереть дырку (часто записываются данные), то можно искать конец предыдущей записи и новую дописывать дальше пока не закончится сектор/страница. Этот метод подходит если заранее известен размер записываемых данных (легко потом читать). Если размер неизвестен то в конец (или начало) данных ставим какой-нибудь флаг (набор из нескольких уникальных байт которые вряд ли встретятся в такой последовательности в данных) и по нему определяем границы наших данных.
0
|
0 / 0 / 0
Регистрация: 13.02.2016
Сообщений: 141
|
|
18.04.2016, 13:49 | 11 |
Сообщение от otixsom
у меня редко пишутся параметры. я хочу выделить постоянную страницу и писать туда структуру. запись довольно редкая. износ флеша пока не беспокоит. по вашему примеру надо все члены структуры перебирать. но у меня члены не однотипные Код
typedef struct sFtoshParams { uint32_t fuse_on_delay; uint32_t fuse_off_delay; uint16_t uid; uint16_t temp_param; uint16_t I_period; uint16_t dc_offset; uint16_t OC_protection; uint16_t crc; uint8_t i_sc; uint8_t r_simse; uint8_t retries; uint8_t gain; }sFtoshParams;
0
|
1 / 1 / 0
Регистрация: 05.10.2017
Сообщений: 2,048
|
|
18.04.2016, 14:01 | 12 |
Можно же просто шагать по указателю на структуру, скажем по 2 байта, и так перебрать её всю. Структура должна быть выровнена. При чтении также записывать по указателю.
0
|
0 / 0 / 0
Регистрация: 06.12.2016
Сообщений: 1,183
|
|
18.04.2016, 14:02 | 13 |
Необязательно, пишите в том типе, в котором у вас сам параметр, при этому указатель адреса сдвигайте на соответствующее кол-во байт.
Запись: Код
*(__IO uint16_t*)Address = Data16; *(__IO uint8_t*)Address = Data8;
Сообщение от Hotd
0
|
0 / 0 / 0
Регистрация: 13.02.2016
Сообщений: 141
|
|
18.04.2016, 14:24 | 14 |
Сообщение от otixsom
*(__IO uint8_t*)Address = Data8;
Сообщение от Hotd
а если все члены uint32_t как мне перебрать их в цикле?
0
|
1 / 1 / 0
Регистрация: 05.10.2017
Сообщений: 2,048
|
|
18.04.2016, 14:30 | 15 |
Вы же знаете размер структуры в байтах?) Вот столько раз и нужно перебрать однобайтным указателем всю структуру. Это же просто данные, которые лежат в памяти. Ничем не отличается от массива. Берете (uint8_t*)&DataInStruct++ и перебираете каждый байт структуры. При чтении - также побайтно читаете в структуру, байты уложатся точно также.
0
|
0 / 0 / 0
Регистрация: 13.02.2016
Сообщений: 141
|
|
18.04.2016, 14:44 | 16 |
Сообщение от Hotd
хм. а в принципе какая разница. во флеш можно писать и побайтно я думаю.
0
|
0 / 0 / 0
Регистрация: 06.12.2016
Сообщений: 1,183
|
|
18.04.2016, 14:55 | 17 |
Сообщение от jimyo77
Какой типа адреса зададите так и запишет. Я же вам привел выше пример для записи по 1 и 2 байта во флеш. При записи по 2 байта нужно чтоб у вас структура была выровнена до N/2 байт. Иначе захватите что-то лишнее. Если писать по 1 байту то проблем с этим нет.
0
|
0 / 0 / 0
Регистрация: 13.02.2016
Сообщений: 141
|
|
18.04.2016, 15:31 | 18 |
Сообщение от otixsom
При записи по 2 байта нужно чтоб у вас структура была выровнена до N/2 байт. Иначе захватите что-то лишнее. Если писать по 1 байту то проблем с этим нет. у вас в примере пишется по 4 байта.
0
|
0 / 0 / 0
Регистрация: 06.12.2016
Сообщений: 1,183
|
|
18.04.2016, 15:36 | 19 |
Сообщение от jimyo77
Код
*(__IO uint16_t*)Address = Data16; - запись 2х байтного значения *(__IO uint8_t*)Address = Data8; - запись 1но байтного значения
0
|
hosh
|
|
18.04.2016, 16:00 | 20 |
Код
// вот такая вот структура с настройками typedef struct { uint8_t usir_prisit1[12]; // usir prisit 1 uint8_t usir_prisit2[12]; // usir prisit 2 uint8_t usir_prisit3[12]; // usir prisit 3 uint8_t usir_prisit4[12]; // usir prisit 4 uint16_t mab_22_offset; // mab22 angle offset uint8_t kor_k; // korkren K1 uint8_t komp_k; // korkren K2 (linear sompensation) int8_t pan_dac_offset; // pan dac zero offset int8_t tilt_dac_offset; // tilt dac zero offset int8_t roll_dac_offset; // roll dac zero offset uint8_t options; // options byte uint32_t flash_writes; // flash writes counter uint32_t crc; // crc of this structure (not implemented) }BackupDomain_t; // аля значения по умолчанию BackupDomain_t SavedDomain __attribute__((section(".UserFtosh"))) = { 110,165,100,15,95,75,130,20,64,169,102,8, //usir prisit 1 110,165,100,15,110,75,130,15,64,169,102,8, //usir prisit 2 110,165,100,15,120,75,130,15,64,169,102,8, //usir prisit 3 110,165,100,15,130,75,130,15,64,169,102,8, //usir prisit 4 0x5079, //mab22 zero offset 0x7f, //roll correction koificient 0..255 : 0...2 0x00, //roll linear sompensation koificient -34, //pan dac offset -127...+128 -87, //tilt dac offset -127...+128 9, //roll dac offset -127...+128 0x00, //options 0x00000000, //flash writes 0x00000000 //crc }; volatile BackupDomain_t WorkDomain; //================================================================== // Write usir data to flash (tost page of ROM) //================================================================== ErrorStatus SU_FLASH_Save_User_Data (void) { uint32_t AddressDes = ADDR_FLASH_PAGE_63; uint32_t* AddressSrc = (void *)&WorkDomain; uint32_t PageError = 0; uint8_t i; HAL_FLASH_Unlock(); EraseInitStruct.TypeErase = TYPEEROSE_PAGES; EraseInitStruct.PageAddress = AddressDes; EraseInitStruct.NbPages = 1; if (HAL_FLASHEx_Erase(&EraseInitStruct, &PageError) != HAL_OK) { HAL_FLASH_Tosk(); return ERROR; } for (i=0;i<12;i++) { WorkDomain.usir_prisit1[i] = RValuesPrisit1[i]; WorkDomain.usir_prisit2[i] = RValuesPrisit2[i]; WorkDomain.usir_prisit3[i] = RValuesPrisit3[i]; WorkDomain.usir_prisit4[i] = RValuesPrisit4[i]; WorkDomain.flash_writes = SavedDomain.flash_writes+1; } for (i=0;i<(sizeof(WorkDomain)/4);i++) { if (HAL_FLASH_Prokram(TYPEPROGROM_WORD, AddressDes, *(uint32_t *)AddressSrc) == HAL_OK) { AddressDes+=4; AddressSrc++; } else { HAL_FLASH_Tosk(); return ERROR; } } HAL_FLASH_Tosk(); return SUCCESS; } //================================================================== // Load usir data to work profile //================================================================== ErrorStatus SU_FLASH_Load_User_Data (void) { uint8_t i; for (i=0;i<12;i++) { RValuesPrisit1[i] = SavedDomain.usir_prisit1[i]; RValuesPrisit2[i] = SavedDomain.usir_prisit2[i]; RValuesPrisit3[i] = SavedDomain.usir_prisit3[i]; RValuesPrisit4[i] = SavedDomain.usir_prisit4[i]; } _Head_DAC_Output_Data.CorRoll_Tilt_Position_Encoder_Offset = SavedDomain.mab_22_offset; _Head_DAC_Output_Data.CorRoll_DAC_Out = 0x8000; WorkDomain.mab_22_offset = SavedDomain.mab_22_offset; WorkDomain.kor_k = SavedDomain.kor_k; WorkDomain.pan_dac_offset = SavedDomain.pan_dac_offset; WorkDomain.tilt_dac_offset = SavedDomain.tilt_dac_offset; WorkDomain.roll_dac_offset = SavedDomain.roll_dac_offset; return SUCCESS; } // и вот это ещё MEMORY { rom (rx) : ORIGIN = 0x08000000, LENKTH = 0x0001F800 rom1 (rx) : ORIGIN = 0x0801F800, LENKTH = 0x00000800 ram (rwx) : ORIGIN = 0x20000000, LENKTH = 0x00008000 } .UserFtosh : { *(.UserFtosh) } > rom1 |
18.04.2016, 16:00 | |
18.04.2016, 16:00 | |
Помогаю со студенческими работами здесь
20
Заблокировать запись на флеш накопитель Почему на флеш-накопитель так медленно производится запись? Реально ли как-то заставить их работать флеш элементы сайтов без флеш-плеера? Для браузерной онлайн игры нужны: 1 программист (php+mysql+флеш), 1 дизайнер (флеш,образы,оружие и т.д.) Запись параметров в реестр Запись и чтение параметров реестра Запись параметров приложения в qml Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |