Гость
Форумы / Программирование [игнор отключен] [закрыт для гостей] / Алгоритм записи на чип флэш памяти / 9 сообщений из 9, страница 1 из 1
16.02.2021, 10:19
    #40045653
jenya7
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Алгоритм записи на чип флэш памяти
У мнея есть SPI NOR FLASH чип (AT45DB021). Каждая страница размером 256 байт.
При записи и стирании я оперирую страницами (при записи я должен передать опкод+номер страницы), минимальный размер стирания – страница.

Стирание , запись, частичная запись
Код: plaintext
1.
2.
3.
void at45d_erase_page(uint16_t page) 
void at45d_wr_page(const void* buffer, uint16_t page)
void at45d_wr_page_offset(const void* buffer, uint16_t page, uint16_t start_byte_in_page,  uint16_t nr_of_bytes)


Я хочу использовать файловую систему для SPI NOR FLASH – SPIFFS.
Для этого нужно передать свои функции чтения, записи, стирания в SPIFFS.
Разработчики файловой системы определяют сигнатуру функций так
Код: plaintext
1.
2.
3.
4.
5.
6.
/* spi read call function type */
typedef s32_t (*spiffs_read)(u32_t addr, u32_t size, u8_t *dst);
/* spi write call function type */
typedef s32_t (*spiffs_write)(u32_t addr, u32_t size, u8_t *src);
/* spi erase call function type */
typedef s32_t (*spiffs_erase)(u32_t addr, u32_t size);


То есть они оперируют адресами а не страницами. По адресу и размеру нужно рассчитать начальную и конечную страницу.
К примеру адрес=200 размер=600. Тогда
На страницу 0 нужно дописать 56 байт (с 200 по 256)
На страницу 1 – полный размер – 256 байт
На страницу 2 – полный размер – 256 байт
На страницу 3 – первые 32 байт.
Я реализовал функции так
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
s32_t my_at45d_write(u32_t address, u32_t size, u8_t *buffer)
{
	uint32_t max_bytes_to_read;
	uint32_t start_page, last_page=0, this_page, pages;
	uint32_t start_byte_in_page;
	uint32_t last_page_bytes;
	uint32_t write_chunk;

	// See if specified address is out of bounds
	if(address > AT45D_ADR_MAX)
	{
	    return -10048;
	}

	max_bytes_to_read = AT45D_ADR_MAX - address + 1;
	if(size > max_bytes_to_read)
	{
	   size = max_bytes_to_read;
	}

    #if VAL_IS_PWR_OF_TWO(AT45D_PAGE_SIZE)
	start_page         = address >> 8;
    start_byte_in_page = address & 0xff;
    pages = size >> 8;
    #else
    start_page        = address / AT45D_PAGE_SIZE;
    start_byte_in_page = address % AT45D_PAGE_SIZE;
    pages = size / AT45D_PAGE_SIZE;
    #endif

    last_page_bytes = size % AT45D_PAGE_SIZE;

	if (last_page_bytes)
		pages++;

	last_page = pages-1;

	for (this_page = start_page; this_page < pages; this_page++)
	{
		if (this_page == start_page)
		{
			write_chunk = AT45D_PAGE_SIZE - start_byte_in_page;
			at45d_wr_page_offset(buffer, this_page, start_byte_in_page, write_chunk);
			buffer += write_chunk;
		}
		else if (this_page == last_page)
		{
			at45d_wr_page_offset(buffer, this_page, 0, last_page_bytes);
		}
		else
		{
			at45d_wr_page(buffer, this_page);
			buffer += AT45D_PAGE_SIZE;
		}
	}

    return 0;
}

s32_t my_at45d_erase(u32_t address, u32_t size)
{
	uint32_t start_page, next_page, pages;
	uint32_t last_page_bytes;

    #if VAL_IS_PWR_OF_TWO(AT45D_PAGE_SIZE)
	start_page         = address >> 8;
    pages = size >> 8;
    #else
    start_page        = address / AT45D_PAGE_SIZE;
    pages = size / AT45D_PAGE_SIZE;
    #endif

    last_page_bytes = size % AT45D_PAGE_SIZE;
    if (last_page_bytes)
    	pages++;

    for (next_page = start_page; next_page < pages; next_page++)
    {
    	 at45d_erase_page(next_page);
    }

	return 0;
}



Я нигде не ошибся?
...
Рейтинг: 0 / 0
17.02.2021, 03:20
    #40046054
Пётр Седов
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Алгоритм записи на чип флэш памяти
jenya7, вы не учли, что первая страница и последняя страница -- это может быть одна и та же страница, если диапазон «address <= n < address + size» полностью умещается в одной странице. Я бы делал примерно так:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
void my_at45d_write(u32_t address, u32_t size, const u8_t* buffer) {
  if (size == 0) {return;}
  uint32_t first_page = address / AT45D_PAGE_SIZE;
  uint32_t last_page = (address + size - 1) / AT45D_PAGE_SIZE;
  const u8_t* buf_p = buffer;
  for (uint32_t page = first_page; page <= last_page; page++) {
    if ((page == first_page) || (page == last_page)) {
      uint32_t page_start = page * AT45D_PAGE_SIZE;
      uint32_t page_end = (page + 1) * AT45D_PAGE_SIZE;
      uint32_t block_start = max(page_start, address);
      uint32_t block_end = min(page_end, address + size);
      uint32_t len = block_end - block_start;
      at45d_wr_page_offset(buf_p, page, block_start - page_start, len);
      buf_p += len;
    } else {
      at45d_wr_page(buf_p, page);
      buf_p += AT45D_PAGE_SIZE;
    }
  }
  assert(buf_p == buffer + size);
}
...
Рейтинг: 0 / 0
17.02.2021, 12:34
    #40046166
Leonid Kudryavtsev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Алгоритм записи на чип флэш памяти
IMHO странная файловая система для флешек, которая не умеет / требует от программиста работать со страницами.
...
Рейтинг: 0 / 0
17.02.2021, 13:12
    #40046217
jenya7
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Алгоритм записи на чип флэш памяти
Пётр Седов
jenya7, вы не учли, что первая страница и последняя страница -- это может быть одна и та же страница, если диапазон «address <= n < address + size» полностью умещается в одной странице. Я бы делал примерно так:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
void my_at45d_write(u32_t address, u32_t size, const u8_t* buffer) {
  if (size == 0) {return;}
  uint32_t first_page = address / AT45D_PAGE_SIZE;
  uint32_t last_page = (address + size - 1) / AT45D_PAGE_SIZE;
  const u8_t* buf_p = buffer;
  for (uint32_t page = first_page; page <= last_page; page++) {
    if ((page == first_page) || (page == last_page)) {
      uint32_t page_start = page * AT45D_PAGE_SIZE;
      uint32_t page_end = (page + 1) * AT45D_PAGE_SIZE;
      uint32_t block_start = max(page_start, address);
      uint32_t block_end = min(page_end, address + size);
      uint32_t len = block_end - block_start;
      at45d_wr_page_offset(buf_p, page, block_start - page_start, len);
      buf_p += len;
    } else {
      at45d_wr_page(buf_p, page);
      buf_p += AT45D_PAGE_SIZE;
    }
  }
  assert(buf_p == buffer + size);
}


спасибо.
...
Рейтинг: 0 / 0
17.02.2021, 13:14
    #40046218
jenya7
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Алгоритм записи на чип флэш памяти
Leonid Kudryavtsev
IMHO странная файловая система для флешек, которая не умеет / требует от программиста работать со страницами.

я сам недоволен этим фактом. но почему то все файловые системы для флеш памяти требуют реализации адресного чтения, записи, стирания.
...
Рейтинг: 0 / 0
17.02.2021, 13:26
    #40046227
jenya7
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Алгоритм записи на чип флэш памяти
Пётр Седов
jenya7, вы не учли, что первая страница и последняя страница -- это может быть одна и та же страница, если диапазон «address <= n < address + size» полностью умещается в одной странице. Я бы делал примерно так:

но page_start = page * AT45D_PAGE_SIZE; - верно только для последней страницы, так как всегда даст начало страницы.
...
Рейтинг: 0 / 0
17.02.2021, 15:16
    #40046295
Пётр Седов
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Алгоритм записи на чип флэш памяти
jenya7
page_start = page * AT45D_PAGE_SIZE; - верно только для последней страницы
Это верно для всех страниц:
page = 0: page_start = 0
page = 1: page_start = 256
page = 2: page_start = 512
page = 3: page_start = 768
и т. д. (AT45D_PAGE_SIZE = 256).

Нетривиальный код только для первой страницы и последней страницы (которые могут быть одной и той же страницей). Там есть 2 диапазона:
* page_start <= n < page_end
* address <= n < address + size
С помощью функций max и min, мы считаем пересечение этих 2-ух диапазонов, это получается 3-ий диапазон «block_start <= n < block_end», который и надо записать в страницу.
...
Рейтинг: 0 / 0
17.02.2021, 16:46
    #40046332
jenya7
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Алгоритм записи на чип флэш памяти
Пётр Седов
jenya7
page_start = page * AT45D_PAGE_SIZE; - верно только для последней страницы
Это верно для всех страниц:
page = 0: page_start = 0
page = 1: page_start = 256
page = 2: page_start = 512
page = 3: page_start = 768
и т. д. (AT45D_PAGE_SIZE = 256).

Нетривиальный код только для первой страницы и последней страницы (которые могут быть одной и той же страницей). Там есть 2 диапазона:
* page_start <= n < page_end
* address <= n < address + size
С помощью функций max и min, мы считаем пересечение этих 2-ух диапазонов, это получается 3-ий диапазон «block_start <= n < block_end», который и надо записать в страницу.

ах да. моя ошибка.
а max и min можно переписать так?
block_start = address - page_start;
block_end = (address + size) - page_end;
...
Рейтинг: 0 / 0
17.02.2021, 18:46
    #40046389
Пётр Седов
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Алгоритм записи на чип флэш памяти
jenya7
а max и min можно переписать так?
block_start = address - page_start;
block_end = (address + size) - page_end;
Я бы не стал :). По моей задумке, block_start и block_end -- это точки в той же «системе координат», что и page_start, page_end, address, address + size. А вот уже в функцию at45d_wr_page_offset передаётся начало блока относительно начала страницы:
Пётр Седов
Код: plaintext
1.
at45d_wr_page_offset(buf_p, page, block_start - page_start, len);

...
Рейтинг: 0 / 0
Форумы / Программирование [игнор отключен] [закрыт для гостей] / Алгоритм записи на чип флэш памяти / 9 сообщений из 9, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]