реклама на сайте
подробности

 
 
3 страниц V  < 1 2 3  
Reply to this topicStart new topic
> Запись структуры во флеш.
Jenya7
сообщение Nov 16 2016, 13:23
Сообщение #31


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



Цитата(aaarrr @ Nov 16 2016, 18:06) *
Мне, например, тоже. И в чем смысл динамического выделения, если строка - str - уже есть?

у К-70 так устроен флеш что надо писать размер кратный 8. мне строку надо проверить и дополнить до кратной 8. поэтому я выделяю + padding_size.

Сообщение отредактировал Jenya7 - Nov 16 2016, 13:26
Go to the top of the page
 
+Quote Post
XVR
сообщение Nov 16 2016, 13:26
Сообщение #32


Гуру
******

Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847



Советую сделать так.

Строки в FLASH упаковывать в такую структуру:
Код
typedef struct PackedStr {
  unsigned int length;
  unsigned char tag;
  char string[1];
} PackedStr;
Реально ваша строка (string[1]) будет занимать столько места, сколько надо (после конца структуры).

В памяти строки складывать в буфер достаточной длинны (что бы принять целиком строку) и длинны, кратной 8

Там же (в памяти) у вас будет 2 индекса в этом буфере:
  1. Индекс последнего занятого байта
  2. Индекс (в пределах первых 8ми байтов) хвоста от предыдущей записи


При приеме новой строки записываете ее в память, увеличивая длинну. После приема смотрите, если индекс занятого места больше 8 - записываете целое количество страниц, а незаписанный хвост переносите в начало буфера (корректируя указатели).
После приема всех данных записываете последний неполный блок (если он есть)

Чтение из FLASH аналогично: читаете в память и перемещаетесь по ней

Код
#define BUF_SIZE 1024
char buffer[BUF_SIZE];

PackedStr* get_next(PackedStr* str)
{
  int len = sizeof(str)-1+str->length;
  if (len&-sizeof(int)) len=(len&-sizeof(int))+sizeof(int); // Align for 'int' field
  return (PackedStr*)(len+(char*)str);
}

PackedStr* start = (PackedStr*)buffer;

void write_string(char* your_string, char tag)
{
  start->tag = tag;
  start->length = strlen(your_string);
  memcpy(start->string,your_string,start->length);

  start = get_next(start);

  int len = (char*)start - buffer;
  if ( len >= PGM_SIZE_BYTE)
  {
     int page_aligned = len&-PGM_SIZE_BYTE;
     WriteToFlash(buffer,page_aligned);
     len &= PGM_SIZE_BYTE-1;
     if (len) memcpy(buffer,buffer+page_aligned,len);
     start = (PackedStr*)(buffer+len);
  }
}

void final_flush()
{
  if ((char*)start != buffer)
  {
    ... pad buffer with 0 ...
    WriteToFlash(buffer,PGM_SIZE_BYTE);
    start = (PackedStr*)buffer;
  }
}

Чтение напишите сами (по аналогии)
Go to the top of the page
 
+Quote Post
Jenya7
сообщение Nov 16 2016, 13:36
Сообщение #33


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



это интересно. надо попробовать. char buffer[BUF_SIZE] вместо heap. спасибо.
Go to the top of the page
 
+Quote Post
HardEgor
сообщение Nov 16 2016, 13:37
Сообщение #34


Гуру
******

Группа: Свой
Сообщений: 2 223
Регистрация: 3-03-06
Из: Tomsk
Пользователь №: 14 925



Цитата(XVR @ Nov 16 2016, 20:26) *
Код
PackedStr* get_next(PackedStr* str)
{
  int len = sizeof(str)-1+str->length;
  if (len&-sizeof(int)) len=(len&-sizeof(int))+sizeof(int); // Align for 'int' field
  return (PackedStr*)(len+(char*)str);
}

А почему-бы при выравнивании, длину не вычислить напрямую:
len = (str->length/8+1)*8
два сдвига на 8 и сложение.
Go to the top of the page
 
+Quote Post
k155la3
сообщение Nov 16 2016, 13:41
Сообщение #35


Профессионал
*****

Группа: Свой
Сообщений: 1 123
Регистрация: 8-03-09
Из: Днепр
Пользователь №: 45 848



Цитата(Jenya7 @ Nov 16 2016, 16:49) *
. . . .
ломаю голову как выделить место под строку.
. . . .

Сколько в процессоре RAM ?
И какой тип флеш ?
(ответ требуется в формате исповеди)
---
Смысл выделять динамически, если памяти достаточно.
Размер стоки (максимальный) имеет какие-то приближенные к жизни размеры,
илиже ОНО бескоечно, аки Вселенная ?
sm.gif


Go to the top of the page
 
+Quote Post
Jenya7
сообщение Nov 16 2016, 13:50
Сообщение #36


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



Цитата(k155la3 @ Nov 16 2016, 18:41) *
Сколько в процессоре RAM ?
И какой тип флеш ?
(ответ требуется в формате исповеди)
---
Смысл выделять динамически, если памяти достаточно.
Размер стоки (максимальный) имеет какие-то приближенные к жизни размеры,
илиже ОНО бескоечно, аки Вселенная ?
sm.gif

Посмотрел сейчас и был приятно удивлен - 64К RAM. Можно выделить кусок под строки и не париться. Какая максимальная длинна строки? да кто их знает. предположительно не более 1 К.

Сообщение отредактировал Jenya7 - Nov 16 2016, 13:51
Go to the top of the page
 
+Quote Post
XVR
сообщение Nov 16 2016, 19:47
Сообщение #37


Гуру
******

Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847



Цитата(HardEgor @ Nov 16 2016, 16:37) *
А почему-бы при выравнивании, длину не вычислить напрямую:
len = (str->length/8+1)*8
Эта формула увеличит длинну на 8 даже если она уже была выровнена на 8, а этого делать не стоит rolleyes.gif
Go to the top of the page
 
+Quote Post
ViKo
сообщение Nov 16 2016, 20:02
Сообщение #38


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(XVR @ Nov 16 2016, 22:47) *
Эта формула увеличит длинну на 8 даже если она уже была выровнена на 8, а этого делать не стоит rolleyes.gif

len = ((str->length - 1) / 8 + 1) * 8
Go to the top of the page
 
+Quote Post
Jenya7
сообщение Nov 17 2016, 08:14
Сообщение #39


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



Тестирую запись.
Создал структуру.
Код
typedef struct TEST_S
{
    unsigned int start;
    unsigned int length;
    unsigned int text_addr;
    unsigned int padding; //for padint to 8 bytes
}TEST;

TEST test;

Инициализирую
Код
uint32_t struct_size = sizeof(TEST);  //16 bytes
test.start = 0xDADA;
test.length = total_len;      
test.text_ptr = 0;
tests[test_idx].padding = 0;

Пишу.
Код
flash_addr = 0;  //from the start of the page -> 0x000FA000, USER_PAGE = 250
ret = FLASH_PageProgram(USER_PAGE, flash_addr, (uint8_t*) &test,  struct_size);
if (ret)
  return ret;

Получаю ошибку (ret = 1) - Protection violation is set in FSTAT register.
В дебагере вижу первые 8 байт записывает нормально. На второй восьмерке генерируется ошибка.

Я понял. Или стирать страницу или держать в памяти текущий адрес чтоб знать куда писать.

Сообщение отредактировал Jenya7 - Nov 17 2016, 08:23
Go to the top of the page
 
+Quote Post

3 страниц V  < 1 2 3
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 21st June 2025 - 21:46
Рейтинг@Mail.ru


Страница сгенерированна за 0.01446 секунд с 7
ELECTRONIX ©2004-2016