powered by simpleCommunicator - 2.0.49     © 2025 Programmizd 02
Форумы / Программирование [игнор отключен] [закрыт для гостей] / Алгоритм записи на чип флэш памяти
9 сообщений из 9, страница 1 из 1
Алгоритм записи на чип флэш памяти
    #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
Алгоритм записи на чип флэш памяти
    #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
Алгоритм записи на чип флэш памяти
    #40046166
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
IMHO странная файловая система для флешек, которая не умеет / требует от программиста работать со страницами.
...
Рейтинг: 0 / 0
Алгоритм записи на чип флэш памяти
    #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
Алгоритм записи на чип флэш памяти
    #40046218
jenya7
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Leonid Kudryavtsev
IMHO странная файловая система для флешек, которая не умеет / требует от программиста работать со страницами.

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

но page_start = page * AT45D_PAGE_SIZE; - верно только для последней страницы, так как всегда даст начало страницы.
...
Рейтинг: 0 / 0
Алгоритм записи на чип флэш памяти
    #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
Алгоритм записи на чип флэш памяти
    #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
Алгоритм записи на чип флэш памяти
    #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]