|
|
  |
Алгоритм вычесления page overflow |
|
|
|
Feb 18 2018, 07:40
|
Профессионал
    
Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075

|
Есть несколько структу которые я записываю на флеш в камне Код if (status == FLASH_COMPLETE) { size = sizeof(GLOB_MOTOR_DATA); addr = (uint32_t *)(flash_page + offset); status = WriteFlash(&glob_mot_data, addr, size); offset += (size + SEPARATOR); size = sizeof(IR_DATA); addr = (uint32_t *)(flash_page + offset); status = WriteFlash(&ir_data, addr, size); offset += (size + SEPARATOR); size = sizeof(MOTOR_TASK) * MAX_TASKS; addr = (uint32_t *)(flash_page + offset); status = WriteFlash(&mot_task, addr, size); offset += size + SEPARATOR; } размер данных постоянно растет, добавляются новые структуры и я задумался - нужно же как то мониторить переполнение страницы, она же не резиновая. и чо то у меня какие то громоздкие вычисления получаются, что мне очень не нравиться. как бы это сделать покрасивше? если последняя структура не влезает на страницу - дописать то что влезает и перескочить на следующую страницу или не париться и всю структуру записать на следующей странице? а где хранить информацию что у меня данные раскинуты на нескольких страницах? я тут нашел старый код для внешней памяти Код if(((address & (AT25_PAGE_SIZE - 1)) + lenght) >= AT25_PAGE_SIZE) { bytes_to_write = AT25_PAGE_SIZE - (address & (AT25_PAGE_SIZE - 1)); //page_overflow = 1; } else { bytes_to_write = lenght; //page_overflow = 0; } с какого перепугу я эндил, нифига не помню. сижу мучаю калькулятор, ничего не выходит. можно воспользоваться этим алгоритмом? упс. только сейчас заметил. я offset вычисляю в байтах а надо size/4.
Сообщение отредактировал Jenya7 - Feb 18 2018, 11:11
|
|
|
|
|
Feb 18 2018, 11:43
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(Jenya7 @ Feb 18 2018, 09:40)  если последняя структура не влезает на страницу - дописать то что влезает и перескочить на следующую страницу или не париться и всю структуру записать на следующей странице? Учтите, что во многих МК невозможна запись данных произвольного размера с произвольного места внутри страницы внутренней флешь программ. Например в LPC17xx можно писать только по адресам кратным 16 и, соответственно, размер кратный 16. Нет, можно конечно записать и не кратно 16, но потом, при чтении, получишь не то, что записал. Цитата(Jenya7 @ Feb 18 2018, 09:40)  а где хранить информацию что у меня данные раскинуты на нескольких страницах? Ну если придерживаться некоего общего правила записи (правила, на основании которого надо перейти к след. странице), то и процедура чтения должна придерживаться этого же правила. Тогда всё будет ок.
|
|
|
|
|
Feb 18 2018, 11:59
|
Профессионал
    
Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075

|
Цитата(jcxz @ Feb 18 2018, 16:43)  Учтите, что во многих МК невозможна запись данных произвольного размера с произвольного места внутри страницы внутренней флешь программ. Например в LPC17xx можно писать только по адресам кратным 16 и, соответственно, размер кратный 16. Нет, можно конечно записать и не кратно 16, но потом, при чтении, получишь не то, что записал.
Ну если придерживаться некоего общего правила записи (правила, на основании которого надо перейти к след. странице), то и процедура чтения должна придерживаться этого же правила. Тогда всё будет ок. у меня все пишет/читает. вопрос был о другом.
|
|
|
|
|
Feb 18 2018, 13:08
|

Просто Che
    
Группа: Свой
Сообщений: 1 567
Регистрация: 22-05-07
Из: ExUSSR
Пользователь №: 27 881

|
Цитата(Jenya7 @ Feb 18 2018, 09:40)  если последняя структура не влезает на страницу - дописать то что влезает и перескочить на следующую страницу или не париться и всю структуру записать на следующей странице? а где хранить информацию что у меня данные раскинуты на нескольких страницах? Поскольку вы ничего не написали об окружении вашего вопроса, а только задали сам узкий вопрос, ничего конкретного посоветовать нельзя, только общие рассуждения. А знать тут нужно: как часто вы пишите данные в страницу флеш за время жизни прибора; сколько раз пишите на страницу, пока она не заполнится; какая вообще структура записей: как непрерывный лог чего-то или это отдельные записи, которые нужно читать выборочно, т.д. При этом советы могут быть разные. Все упирается в ресурс флеш. Если это лог-файл, то логичней делить данные по длине страницы и последнюю запись делать за два приема. Если общее число записей за время жизни прибора мало, то вам вообще никто не мешает при каждой записи данных писать в ту же страницу служебную информацию по расположению данных на странице. Вариантов много...
|
|
|
|
|
Feb 18 2018, 15:24
|
Профессионал
    
Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075

|
Цитата(HardEgor @ Feb 18 2018, 21:15)  Кгхм... скажу банальщину, но возможно её вы и ждете: целочисленно разделить размер флэш(или страницы) на размер сохраняемой структуры, если ноль - места не хватит. это уже ближе к телу, как говорил Моппасан. Но у меня разные структуры на одной странице. я тут посмотрел со стороны на свои художества и переделал. правда еще не проверял Код FLASH_Status FLASH_WriteParams(uint32_t flash_page) { uint8_t i; uint32_t page_adr; uint32_t *source_adr; FLASH_Status status; //flash unlock if((FLASH->CR & FLASH_CR_LOCK) != RESET) { /* Authorize the FLASH Registers access */ FLASH->KEYR = FLASH_KEY1; FLASH->KEYR = FLASH_KEY2; }
status = FLASH_ErasePage(flash_page); if (status == FLASH_COMPLETE) { //---------------GLOB_MOTOR_DATA--------------------------------- source_adr = (void *)&glob_mot_data; page_adr = flash_page; for (i = 0; i < GLOB_MOTOR_DATA_SIZE; ++i) // //size in words { status = FLASH_ProgramWord((uint32_t)(page_adr + i*4), *(source_adr + i)); } //---------------IR_DATA-------------------------------------- source_adr = (void *)&ir_data; page_adr = flash_page + GLOB_MOTOR_DATA_SIZE; for (i = 0; i < IR_DATA_SIZE; ++i) //size in words { status = FLASH_ProgramWord((uint32_t)(page_adr + i*4), *(source_adr + i)); } //---------------MOTOR_TASK---------------------------------- source_adr = (void *)&mot_task; page_adr = flash_page + GLOB_MOTOR_DATA_SIZE + IR_DATA_SIZE; for (i = 0; i < TASK_DATA_SIZE; ++i) //size in words { status = FLASH_ProgramWord((uint32_t)(page_adr + i*4), *(source_adr + i)); } } return status; }
void FLASH_ReadParams(uint32_t flash_page) {
//---------------GLOB_MOTOR_DATA--------------------------------- uint32_t *source_adr = (uint32_t *)(flash_page); uint32_t *dest_adr = (void *)&glob_mot_data;
uint32_t i; for (i=0; i < GLOB_MOTOR_DATA_SIZE; ++i) { *dest_adr = *(__IO uint32_t*)source_adr; } //---------------IR_DATA-------------------------------------- source_adr = (uint32_t *)(flash_page+GLOB_MOTOR_DATA_SIZE); dest_adr = (void *)&ir_data;
for (i=0; i < IR_DATA_SIZE; ++i) { *dest_adr = *(__IO uint32_t*)source_adr; } //---------------MOTOR_TASK---------------------------------- source_adr = (uint32_t *)(flash_page+GLOB_MOTOR_DATA_SIZE+IR_DATA_SIZE); dest_adr = (void *)&mot_task;
for (i=0; i < IR_DATA_SIZE; ++i) { *dest_adr = *(__IO uint32_t*)source_adr; } } с переполнением страницы еще ничего не решил. хоцца шоб было красиво, элегантно.
Сообщение отредактировал Jenya7 - Feb 18 2018, 15:32
|
|
|
|
|
Feb 18 2018, 16:57
|

Просто Che
    
Группа: Свой
Сообщений: 1 567
Регистрация: 22-05-07
Из: ExUSSR
Пользователь №: 27 881

|
Цитата(Jenya7 @ Feb 18 2018, 16:31)  ребята вы шутите или как? при чем здесь какая флеш и сколько раз я на нее пишу? изначальный вопрос - Алгоритм вычисления page overflow. неужели нельзя внимательно прочитать и проанализировать пару строчек? я пишу конфигурационные структуры, один раз при настройке системы, ну может пару раз для точной подстройки. какой лог файл? во флеш камня лог файл? да и вообще это не имеет никакого отношения к вопросу. давайте отделять зерна от плевел. А по моему мнению, это вы всех троллите Если это пару раз для конфигурации прибора, то: 1) Вы не знаете размер страницы флеш и размер записываемых данных? 2) Вы не можете поделить одно на другое и принять решение влазит/не влазит? 3) Вы не можете придумать "шапку" конфигурации с параметрами, описывающими её длину и расположение? з.ы. а разбираться с вашими "портянками" из-за вопроса на одно деление вряд-ли кто будет, они тут совершенно излишни... з.з.ы. звиняйте за резкий тон, но это уже перебор, имхо
|
|
|
|
|
Feb 19 2018, 06:31
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(Jenya7 @ Feb 19 2018, 08:27)  а если завтра добавиться новая структура? Добавите её к остальным. Цитата(Jenya7 @ Feb 19 2018, 08:27)  по моему скромному мнению переполнение нужно вычислять по текущему адресу и размеру страницы, без дополнительных аргументов. А для этого сделайте универсальную процедуру записи, без привязки к каким-либо структурам. И при чтении замените порнографию на memcpy, если уж хочется, чтобы было "красиво, элегантно".
|
|
|
|
|
Feb 21 2018, 16:37
|
Профессионал
    
Группа: Свой
Сообщений: 1 123
Регистрация: 8-03-09
Из: Днепр
Пользователь №: 45 848

|
Цитата(Jenya7 @ Feb 18 2018, 10:40)  Есть несколько структу которые я записываю на флеш в камне . . . . а где хранить информацию что у меня данные раскинуты на нескольких страницах? . . . Размер страницы флеш известен. Размер Вашей структуры известен. Кол-во структур, умещеющихся в страницу известно на этапе компиляции. (понятно, что скорее всего останется "нечетное" пустое место, жертва во благо логичности и простоте работы с массивом). Инексы массива во флеш и внутри страницы создавать динамически в RAM.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|