Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Алгоритм вычесления page overflow
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > Программирование
Jenya7
Есть несколько структу которые я записываю на флеш в камне
Код
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.
jcxz
Цитата(Jenya7 @ Feb 18 2018, 09:40) *
если последняя структура не влезает на страницу - дописать то что влезает и перескочить на следующую страницу или не париться и всю структуру записать на следующей странице?

Учтите, что во многих МК невозможна запись данных произвольного размера с произвольного места внутри страницы внутренней флешь программ.
Например в LPC17xx можно писать только по адресам кратным 16 и, соответственно, размер кратный 16.
Нет, можно конечно записать и не кратно 16, но потом, при чтении, получишь не то, что записал.

Цитата(Jenya7 @ Feb 18 2018, 09:40) *
а где хранить информацию что у меня данные раскинуты на нескольких страницах?

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


Ну если придерживаться некоего общего правила записи (правила, на основании которого надо перейти к след. странице), то и процедура чтения должна придерживаться этого же правила. Тогда всё будет ок.

у меня все пишет/читает. вопрос был о другом.
Baser
Цитата(Jenya7 @ Feb 18 2018, 09:40) *
если последняя структура не влезает на страницу - дописать то что влезает и перескочить на следующую страницу или не париться и всю структуру записать на следующей странице?
а где хранить информацию что у меня данные раскинуты на нескольких страницах?

Поскольку вы ничего не написали об окружении вашего вопроса, а только задали сам узкий вопрос, ничего конкретного посоветовать нельзя, только общие рассуждения.
А знать тут нужно: как часто вы пишите данные в страницу флеш за время жизни прибора; сколько раз пишите на страницу, пока она не заполнится; какая вообще структура записей: как непрерывный лог чего-то или это отдельные записи, которые нужно читать выборочно, т.д.
При этом советы могут быть разные.

Все упирается в ресурс флеш.
Если это лог-файл, то логичней делить данные по длине страницы и последнюю запись делать за два приема.

Если общее число записей за время жизни прибора мало, то вам вообще никто не мешает при каждой записи данных писать в ту же страницу служебную информацию по расположению данных на странице.

Вариантов много...
Jenya7
ребята вы шутите или как? при чем здесь какая флеш и сколько раз я на нее пишу? изначальный вопрос - Алгоритм вычисления page overflow. неужели нельзя внимательно прочитать и проанализировать пару строчек? я пишу конфигурационные структуры, один раз при настройке системы, ну может пару раз для точной подстройки. какой лог файл? во флеш камня лог файл? да и вообще это не имеет никакого отношения к вопросу. давайте отделять зерна от плевел.
arhiv6
Напишите прослойку с виртуальной адресацией и работайте через неё. Все проверки, в том числе о переполнении страницы, делаются внутри этой прослойки, там же это обрабатывается. Примеров подобной работы с флешем много, можете взять любой из гугла по запросу "eeprom emulation in flash".
HardEgor
Цитата(Jenya7 @ Feb 18 2018, 21:31) *
изначальный вопрос - Алгоритм вычисления page overflow. неужели нельзя внимательно прочитать и проанализировать пару строчек?

Кгхм... скажу банальщину, но возможно её вы и ждете: целочисленно разделить размер флэш(или страницы) на размер сохраняемой структуры, если ноль - места не хватит.
Jenya7
Цитата(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;                
    }
    
}

с переполнением страницы еще ничего не решил. хоцца шоб было красиво, элегантно.
HardEgor
Цитата(Jenya7 @ Feb 18 2018, 22:24) *
это уже ближе к телу, как говорил Моппасан. Но у меня разные структуры на одной странице.

Какая разница сколько структур, вычисляете для каждой перед записью. Или если пишите все сразу - для суммы всех структур.
Baser
Цитата(Jenya7 @ Feb 18 2018, 16:31) *
ребята вы шутите или как? при чем здесь какая флеш и сколько раз я на нее пишу? изначальный вопрос - Алгоритм вычисления page overflow. неужели нельзя внимательно прочитать и проанализировать пару строчек? я пишу конфигурационные структуры, один раз при настройке системы, ну может пару раз для точной подстройки. какой лог файл? во флеш камня лог файл? да и вообще это не имеет никакого отношения к вопросу. давайте отделять зерна от плевел.

А по моему мнению, это вы всех троллите wacko.gif

Если это пару раз для конфигурации прибора, то:
1) Вы не знаете размер страницы флеш и размер записываемых данных?
2) Вы не можете поделить одно на другое и принять решение влазит/не влазит?
3) Вы не можете придумать "шапку" конфигурации с параметрами, описывающими её длину и расположение?

з.ы. а разбираться с вашими "портянками" из-за вопроса на одно деление вряд-ли кто будет, они тут совершенно излишни...
з.з.ы. звиняйте за резкий тон, но это уже перебор, имхо
HardEgor
Цитата(Baser @ Feb 18 2018, 23:57) *
з.ы. а разбираться с вашими "портянками" из-за вопроса на одно деление вряд-ли кто будет, они тут совершенно излишни...

Он наверное ждет что сейчас появится какой-нибудь энтузазист и напишет для него код. wink.gif Чего там писать - 5 минут....
aaarrr
Цитата(Jenya7 @ Feb 18 2018, 18:24) *
Но у меня разные структуры на одной странице.
...
с переполнением страницы еще ничего не решил. хоцца шоб было красиво, элегантно.

Сложите свои разные структуры в одну "структуру структур". С ней и работайте при записи - будут автоматом и общая длина и смещения.
Jenya7
Цитата(aaarrr @ Feb 19 2018, 00:15) *
Сложите свои разные структуры в одну "структуру структур". С ней и работайте при записи - будут автоматом и общая длина и смещения.

а если завтра добавиться новая структура? по моему скромному мнению переполнение нужно вычислять по текущему адресу и размеру страницы, без дополнительных аргументов.
aaarrr
Цитата(Jenya7 @ Feb 19 2018, 08:27) *
а если завтра добавиться новая структура?

Добавите её к остальным.

Цитата(Jenya7 @ Feb 19 2018, 08:27) *
по моему скромному мнению переполнение нужно вычислять по текущему адресу и размеру страницы, без дополнительных аргументов.

А для этого сделайте универсальную процедуру записи, без привязки к каким-либо структурам.

И при чтении замените порнографию на memcpy, если уж хочется, чтобы было "красиво, элегантно".
k155la3
Цитата(Jenya7 @ Feb 18 2018, 10:40) *
Есть несколько структу которые я записываю на флеш в камне
. . . .
а где хранить информацию что у меня данные раскинуты на нескольких страницах?
. . .

Размер страницы флеш известен.
Размер Вашей структуры известен.
Кол-во структур, умещеющихся в страницу известно на этапе компиляции.
(понятно, что скорее всего останется "нечетное" пустое место, жертва во благо логичности и простоте работы с массивом).
Инексы массива во флеш и внутри страницы создавать динамически в RAM.


Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2024 Invision Power Services, Inc.