|
Запись структуры во флеш. |
|
|
|
Nov 14 2016, 14:01
|
Профессионал
    
Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075

|
Есть структура. Код typedef struct TEST_S { unsigned char start; unsigned int length; char *text; }TEST;
extern TEST tests[MAX_TESTS]; я инициализирую структуру и пытаюсь записать. Код unsigned int TESTER_SaveTest(unsigned int user_page) { unsigned int ret; unsigned int addr; tests[0].start = 0xDA; tests[0].length = 5; tests[0].text = "HELLO"; tests[1].start = 0xDA; tests[1].length = 6; tests[1].text = "WORLD!"; ret = FLASH_PageErase(user_page); if (ret) return ret; addr = 0; ret = FLASH_PageProgram(user_page, addr, (uint8_t *) &tests[0], BUFFER_SIZE_BYTE); if (ret) return ret; addr += (sizeof(tests[0])) + 1; ret = FLASH_PageProgram(user_page, addr, (uint8_t *) &tests[1], BUFFER_SIZE_BYTE); //тут я получаю ошибку - 32. if (ret) return ret; return ret; } Первая запись проходит нормально. Вторая со смещением 13 выдает ошибку 32 - Access error is set in the FSTAT register. Я что то упускаю в логике?
|
|
|
|
|
Nov 14 2016, 14:43
|
Профессионал
    
Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075

|
Цитата(aaarrr @ Nov 14 2016, 20:26)  Для сферической флеш в вакууме? Вангую, требования по выравниванию по строкам. Они в Kinetis так намутили с флеш драйвером! Запись такая. Код FlashProgram(&flashSSDConfig, dest, size, buffer, FlashCommandSequence); Логично предположить что size это размер записываемого массива buffer. Смотрим реализацию CODE uint32_t SIZE_OPTIMIZATION FlashProgram(PFLASH_SSD_CONFIG pSSDConfig, \ uint32_t dest, \ uint32_t size, \ uint8_t* pData, \ pFLASHCOMMANDSEQUENCE pFlashCommandSequence) { uint32_t ret = FTFx_OK; /* return code variable */ uint8_t i; uint32_t temp;
if (size & (PGM_SIZE_BYTE - 0x01U)) { ret = FTFx_ERR_SIZE; } else { /* convert to byte address */ dest = WORD2BYTE(dest); #if (DEBLOCK_SIZE) temp = WORD2BYTE(pSSDConfig->DFlashBlockBase); if((dest >= temp) && (dest < (temp + pSSDConfig->DFlashBlockSize))) { dest = dest - temp + 0x800000U; } else #endif { temp = WORD2BYTE(pSSDConfig->PFlashBlockBase); if((dest >= temp) && (dest < (temp + pSSDConfig->PFlashBlockSize))) { dest -= temp; } else { ret = FTFx_ERR_ACCERR; } } while((size > 0x0U) && (FTFx_OK == ret)) { /* clear RDCOLERR & ACCERR & FPVIOL flag in flash status register. Write 1 to clear*/ temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FSTAT_OFFSET; REG_WRITE(temp, FTFx_SSD_FSTAT_ERROR_BITS); /* passing parameter to the command */ #if (PGM_SIZE_BYTE == FTFx_PHRASE_SIZE) temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB0_OFFSET; REG_WRITE(temp, FTFx_PROGRAM_PHRASE); #else temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB0_OFFSET; REG_WRITE(temp, FTFx_PROGRAM_LONGWORD); #endif temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB1_OFFSET; REG_WRITE(temp, GET_BIT_16_23(dest)); temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB2_OFFSET; REG_WRITE(temp, GET_BIT_8_15(dest)); temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB3_OFFSET; REG_WRITE(temp, GET_BIT_0_7(dest));
for (i = 0x0U; i < PGM_SIZE_BYTE; i++) { temp = pSSDConfig->ftfxRegBase + i + 0x08U; REG_WRITE(temp, *(pData + i)); }
/* calling flash command sequence function to execute the command */ ret = pFlashCommandSequence(pSSDConfig);
/* update destination address for next iteration */ dest += PGM_SIZE_BYTE; /* update size for next iteration */ size -= PGM_SIZE_BYTE; /* increment the source address by 1 */ pData += PGM_SIZE_BYTE; } } #if C90TFS_ENABLE_DEBUG /* Enter Debug state if enabled */ if (TRUE == (pSSDConfig->DebugEnable)) { ENTER_DEBUG_MODE; } #endif
return(ret); }
Код /* update size for next iteration */ size -= PGM_SIZE_BYTE; это как? учитывая что Код #define PGM_SIZE_BYTE 0x0008U /* 8 bytes */ то есть размер моей структуры должен быть кратный 8?
Сообщение отредактировал Jenya7 - Nov 14 2016, 14:55
|
|
|
|
|
Nov 14 2016, 15:29
|
Профессионал
    
Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075

|
Цитата(aaarrr @ Nov 14 2016, 21:27)  Что-то вроде. а где вставить прагму? так вроде не ругается Код #pragma pack(8) typedef struct TEST_S { unsigned char start; unsigned int length; char *text; }TEST; я вообще не понимаю что за клоунада такая. в STM32 и EFM32 я писал любой размер и все были довольны и я и флеш.
|
|
|
|
|
Nov 14 2016, 15:35
|
Профессионал
    
Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075

|
Цитата(aaarrr @ Nov 14 2016, 21:33)  О, сколько нам открытий чудных... Надо было начинать с LPC. так не я это решаю. как по мне остался бы на STM32 там все уже написано. пробовал так Код #pragma pack(8) typedef struct TEST_S { unsigned char start; unsigned int length; char *text; }TEST; и так Код typedef #pragma pack(8) struct TEST_S { unsigned char start; unsigned int length; char *text; }TEST; uint32_t n = sizeof(tests[0]); возвращает 12. почему 12 непонятно. по моему я понял. три члена структуры компайлер выравнивает до 4 байт. получаем 12. чтобы получить реальную длину я должен прибавить длину строки? "HELLO" - еще 5 байт?
Сообщение отредактировал Jenya7 - Nov 14 2016, 16:26
|
|
|
|
|
Nov 15 2016, 07:22
|
Профессионал
    
Группа: Свой
Сообщений: 1 123
Регистрация: 8-03-09
Из: Днепр
Пользователь №: 45 848

|
Цитата(Jenya7 @ Nov 14 2016, 18:29)  . . . . я вообще не понимаю что за клоунада такая. в STM32 и EFM32 я писал любой размер и все были довольны и я и флеш. Не Вы первый ходите по этим граблям. Такой метод записи сильно "компиляторо-прагма"-зависим. Чтоб с этим не заморачиваться (раз и навсегда), почитайте за сериализацию.
|
|
|
|
|
Nov 15 2016, 11:21
|
Профессионал
    
Группа: Свой
Сообщений: 1 123
Регистрация: 8-03-09
Из: Днепр
Пользователь №: 45 848

|
Цитата(Jenya7 @ Nov 15 2016, 13:11)  сериализация очень широкое понятие. буду признателен если ткнете носом. ссылки, где это внятно расписано, под рукой нет. Если в двух словах - преобразование различных данных (в том числе структур, классов и чегоугодно) в последовательность байт (в нашем случае) для сохранения или передачи где-куда-либо. С целю последующего однозначного восстановления, напр. при приеме из канала связи. Одна из основных особенностей-достоинств - платформо и компиляторо-независимость. Вы сохраняете структуру "оптом", по сути в виде образа из памяти. При сериализации придется - брать каждое поле структуры, - определять его размер, - преобразовывать его в последовательность байт (исходя из размера поля/типа данных), - и затем их (поля) "цепочкой" записывать в флеш. При этом на выравнивание можно не обращать внимание. Единственный ньюанс - надо учитывать платформенный Big-Little Endian формат для чисел конкретного процессора.
|
|
|
|
|
Nov 15 2016, 11:58
|
Профессионал
    
Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075

|
Цитата(k155la3 @ Nov 15 2016, 17:21)  ссылки, где это внятно расписано, под рукой нет. Если в двух словах - преобразование различных данных (в том числе структур, классов и чегоугодно) в последовательность байт (в нашем случае) для сохранения или передачи где-куда-либо. С целю последующего однозначного восстановления, напр. при приеме из канала связи. Одна из основных особенностей-достоинств - платформо и компиляторо-независимость. Вы сохраняете структуру "оптом", по сути в виде образа из памяти. При сериализации придется - брать каждое поле структуры, - определять его размер, - преобразовывать его в последовательность байт (исходя из размера поля/типа данных), - и затем их (поля) "цепочкой" записывать в флеш.
При этом на выравнивание можно не обращать внимание. Единственный ньюанс - надо учитывать платформенный Big-Little Endian формат для чисел конкретного процессора. (uint8_t *) &MyStruct - прекрасная сериализация только речь тут о другом . ребята из NXP говорят надо делать падинг буферу до размера кратного 8.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|