Форум программистов, компьютерный форум, киберфорум
Микроконтроллеры ARM, Cortex, STM32
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.80/75: Рейтинг темы: голосов - 75, средняя оценка - 4.80
7 / 7 / 0
Регистрация: 26.11.2018
Сообщений: 262

Запись данных в флэш W25Q, интерфейс SPI. STM32F103

08.02.2021, 21:31. Показов 16670. Ответов 33
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Всем привет.
Появилась идея записывать данные сенсора / сенсоров в флэш память W25Q128.
Ни разу этого не делал.. Поэтому не могу понять как правильно записывать данные.

Пробовал записывать данные побайтно
C
1
2
3
4
5
6
7
8
9
10
11
12
13
    // Filling data in array
    for(int i = 0; i <= 10; i++)
    {
        W25qxx_WriteByte(i, i);                 // Write one byte
    }
 
    // Reading data from Flash
    HAL_Delay(1);
    uint8_t read_buff[10] = {0};
    for(int i = 0; i <= 10; i++)
    {
        W25qxx_ReadByte(&read_buff[i], i);           // Read one byte
    }
Пробовал записывать в 16 страниц, то есть в один сектор, и читать разными способами.
C
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
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // Write all sector. One sector = 16 pages. One sector = 256*16 4096 bytes
    // W25qxx_EraseChip();
    // Erase sector 0
    W25qxx_EraseSector(0);
    // Init buffer for write
    char buff_for_write_on_flash[255] = {0};
    memset (buff_for_write_on_flash, 1, sizeof(buff_for_write_on_flash));
 
    ////////////  Write all pages in sector data in flash.
    // One sector has 16 pages
    for(uint8_t i = 0; i<=15; i++)
    {
        // 1. Write number
//      memset (buff_for_write_on_flash, i, sizeof(buff_for_write_on_flash));
//      W25qxx_WritePage(buff_for_write_on_flash, i, 0, 0);
        // 2. Write string
        sprintf(buff_for_write_on_flash, "%s", "TEST");
        W25qxx_WritePage(buff_for_write_on_flash, i, 0, 0);
 
    }
    //////////// 1. Read all pages using read page function
    char buff_for_read_from_flash[256] = {0};
    for(int i = 0; i<=15; i++)
    {
        memset (buff_for_read_from_flash, 0, sizeof(buff_for_read_from_flash));
        W25qxx_ReadPage(buff_for_read_from_flash, i, 0, 0);
    }
 
    //////////// 2.Read all pages using read all SECTOR function
    uint8_t buffer_for_read_sector[4096] = {0};
    W25qxx_ReadSector(buffer_for_read_sector, 0, 0, 0);
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Есть драйвер в котором есть необходимые функции:

C
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
uint8_t W25qxx_Init(void);
 
void W25qxx_EraseChip(void);
void W25qxx_EraseSector(uint32_t SectorAddr);
void W25qxx_EraseBlock(uint32_t BlockAddr);
 
uint32_t W25qxx_PageToSector(uint32_t PageAddress);
uint32_t W25qxx_PageToBlock(uint32_t PageAddress);
uint32_t W25qxx_SectorToBlock(uint32_t SectorAddress);
uint32_t W25qxx_SectorToPage(uint32_t SectorAddress);
uint32_t W25qxx_BlockToPage(uint32_t BlockAddress);
 
uint8_t W25qxx_IsEmptyPage(uint32_t Page_Address, uint32_t OffsetInByte);
uint8_t W25qxx_IsEmptySector(uint32_t Sector_Address, uint32_t OffsetInByte);
uint8_t W25qxx_IsEmptyBlock(uint32_t Block_Address, uint32_t OffsetInByte);
 
void W25qxx_WriteByte(uint8_t byte, uint32_t addr);
void W25qxx_WritePage(uint8_t *pBuffer, uint32_t Page_Address, uint32_t OffsetInByte, uint32_t NumByteToWrite_up_to_PageSize);
void W25qxx_WriteSector(uint8_t *pBuffer, uint32_t Sector_Address, uint32_t OffsetInByte, uint32_t NumByteToWrite_up_to_SectorSize);
void W25qxx_WriteBlock(uint8_t* pBuffer, uint32_t Block_Address, uint32_t OffsetInByte, uint32_t NumByteToWrite_up_to_BlockSize);
 
void W25qxx_ReadByte(uint8_t *pBuffer, uint32_t Bytes_Address);
void W25qxx_ReadBytes(uint8_t *pBuffer, uint32_t ReadAddr, uint32_t NumByteToRead);
void W25qxx_ReadPage(uint8_t *pBuffer, uint32_t Page_Address, uint32_t OffsetInByte, uint32_t NumByteToRead_up_to_PageSize);
void W25qxx_ReadSector(uint8_t *pBuffer, uint32_t Sector_Address, uint32_t OffsetInByte, uint32_t NumByteToRead_up_to_SectorSize);
void W25qxx_ReadBlock(uint8_t *pBuffer, uint32_t Block_Address, uint32_t OffsetInByte,uint32_t NumByteToRead_up_to_BlockSize);
Вопрос, как правильно записывать данные?
Допустим, нужно периодически записывать структуру данных где есть:
1. Номер записи
2. Название сенсора
3. Данные сенсора.
Если это писать в одну страницу, в которой есть 256 байт, то останется много не использованной памяти в странице.
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
08.02.2021, 21:31
Ответы с готовыми решениями:

stm32f103 spi sd card keil
доброго времени суток. ктото может ткнуть носом, где можно взять пример работы с сд картой под кейл. уже сломал голову.

STM32F103 + SPI EEPROM M95M01
Всем привет! Пытаюсь написать алгоритм работы с SPI EEPROM, но из-за недостатка опыта сомневаюсь в правильности алгоритмов, потому...

Не понятно маркировка SPI флэш-памяти
Имеется модуль SPI флэш-память не понятной мне маркировки, может кто сталкивался? Доподлинное известно, что это чип BIOS'а. Судя по...

33
 Аватар для Voland_
1983 / 1276 / 131
Регистрация: 04.01.2010
Сообщений: 4,607
08.02.2021, 22:51
У вас же есть функция "W25qxx_WriteByte()". Значит можно побайтно писать данные. В чем проблема? Просто учитывайте, что стирание происходит посекторно, минимум. Ну, если записывать нужно одну и ту же структуру - во Флеши ее записывают последовательно, "размазывая" по всему отведенному пространству флеши. Дополнительно, дописывают "количество" записей, чтобы оценить ресурс страницы FLASH на запись. Это называется "aging control". Есть и другие названия, но цель одна - определить с помощью моделей количество оставшихся записей в страницу. Потому что запись при различных условиях (напряжение питания и температура) влияет в конечном итоге на ресурс страницы.

Рекомендую поискать библиотеки "EEPROM emulation". Они есть и для STM8/STM32, и у многих (почти всех) других производителей. Простенькие, но для начала и большинства задач их достаточно.
1
7 / 7 / 0
Регистрация: 26.11.2018
Сообщений: 262
09.02.2021, 01:56  [ТС]
Я придумал как-то так записывать данные.

C
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
void test_write_read_bytes()
{
    W25qxx_EraseChip();
    // Filling data in array
    char tx_data[10] = "TEST ";
    int number = 0;
    int k = 0;
    int r = 0;
    for(int k = 1; k <= 10; k++)
    {
        // add number at the end fo string
        snprintf(tx_data, sizeof(tx_data), "TEST %d", k );
        for(int i =0 ; i<=sizeof(tx_data); i++)
        {
            W25qxx_WriteByte(tx_data[i], r++);
        }
    }
 
    // Reading data from Flash
    HAL_Delay(1);
    uint8_t read_buff[1000] = {0};
    for(int i = 0; i <= 200; i++)
    {
        W25qxx_ReadByte(&read_buff[i], i);           // Read one byte
    }
Добавлено через 2 часа 46 минут
Сделал так. Но проблема.. В функцию W25qxx_WriteByte мне нужно подавать по одному байту.
Когда был массив, то проблем как передать не было, но у меня сейчас структура, и я незнаю как ее передать побайтно в эту функцию

C
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
void test_write_read_bytes()
{
    // Create structure
    struct sensors_data{
        int number_of_measure;
        char sensor_name_1[11];
        char sensor_1_data[4];
    };
    struct sensors_data sensors_data_t;             // Creating sensors_data_t structure variable
    struct sensors_data_t *sensors_data_t_p;        // Create pointer on struct
    sensors_data_t_p = &sensors_data_t;
 
    W25qxx_EraseChip();                 // Erase all flash chip
 
    int k = 0;
    int r = 0;
 
    for(int k = 1; k <= 10; k++)
    {
        strcpy( sensors_data_t.sensor_name_1, "Sensor_1:");
        for(int i =0 ; i<=sizeof(sensors_data_t); i++)
        {
            sensors_data_t.number_of_measure = 1;
            strcpy( sensors_data_t.sensor_1_data, "99");
            // Writing in flash sensors_data_t structure byte by bytes
            W25qxx_WriteByte(sensors_data_t_p, r++);
        }
    }
 
    // Reading data from Flash
    HAL_Delay(1);
    uint8_t read_buff[1000] = {0};
    for(int i = 0; i <= 200; i++)
    {
        W25qxx_ReadByte(&read_buff[i], i);           // Read one byte
    }
0
 Аватар для Voland_
1983 / 1276 / 131
Регистрация: 04.01.2010
Сообщений: 4,607
09.02.2021, 10:04
Цитата Сообщение от OlegD_STM32 Посмотреть сообщение
у меня сейчас структура, и я незнаю как ее передать побайтно в эту функцию
ну обычно в цикле, вызывающем SendByte() Вам нужно два элемента - указатель на начало массива и размер массива. То есть:
C
1
2
3
void send_buffer(char *buffer, unsigned long flash_offset, unsigned int size) {
...
}
В итоге, тогда есть возможность передать вашу структуру вызовом:
C
1
send_buffer((char*)&sensors_data_t, 0x102030, 1234);
то есть "записать буфер, начиная с адреса 0x102030, размером 1234 байта".
1
7 / 7 / 0
Регистрация: 26.11.2018
Сообщений: 262
10.02.2021, 14:17  [ТС]
Правильно ли я понимаю распределение памяти по страницам, блоках и секторах?
В странице есть 265 байт в секторе 16 страниц. Так что в одном секторе 256 * 16 = 4096 байт.
В одном блоке 16 секторов по 4096 байт. Итак 16 * 4096 = 65536 байт в обно блоке.
В микросхеме W25Q128 блоков 256. Итак 256 * 65536 = 16777216 б во всей микросхеме.

Для того чтобы структура данными кратно поместилась в память одной страницы нужно чтобы ее размер был 32 байта. Тогда структура поместится 8 раз в одну страницу. И (допустим) чтобы при заполнении одного сектора структура не была записана между двумя секторами.
Стирать можно либо сектор или блок или всю микросхему.
Записывать можно побайтно, по странице, по сектору, или по блоку.
Стирать можно сектор, блок, или всю память.

Функция записи одного байта принимает в качестве аргумента байт, а не адрес на байт, и адрес записи.
C
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
//###################################################################################################################
void W25qxx_WriteByte(uint8_t byte, uint32_t addr)
{
    while(w25qxx.Lock == 1)
        W25qxx_Delay(1);
 
    w25qxx.Lock = 1;
 
    W25qxx_WaitForWriteEnd();
    W25qxx_WriteEnable();
 
    W25QFLASH_CS_SELECT;
 
    W25qxx_Spi(W25_PAGE_PROGRAMM);
 
    if(w25qxx.ID >= W25Q256)
        W25qxx_Spi((addr & 0xFF000000) >> 24);
 
    W25qxx_Spi((addr & 0xFF0000) >> 16);
    W25qxx_Spi((addr & 0xFF00) >> 8);
    W25qxx_Spi(addr & 0xFF);
 
    W25qxx_Spi(byte);
 
    W25QFLASH_CS_UNSELECT;
 
    W25qxx_WaitForWriteEnd();
 
    w25qxx.Lock = 0;
}
 
//###################################################################################################################
Итак, мне нужно сделать цикл, который будет повторяться 32 раза (размер структуры в байтах) в котором я буду передавать в функцию W25qxx_WriteByte один байт, и делать инкремент адреса для записи в флэш память.
Поэтому я передаю в функцию write_struct_in_flash копию структуры, и хочу побайтно ее передать в функцию W25qxx_WriteByte.
В функции write_struct_in_flash мне нужно при каждой итерации цикла увеличивать адресов флэш памяти flash_offset и полученной структуры на 1 байт.

Я до сих пор не понимаю как передать побайтно эту структуру в функцию W25qxx_WriteByte (uint8_t byte, uint32_t flash_offset)

C
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
// ----------------------------------------------------------------------------
void save_data_in_flash(void)
{
    struct sensors_data sensors_data_t;                             // Creating sensors_data_t structure variable
    //struct sensors_data *sensors_data_t_p = &sensors_data_t;      // Create pointer on structure
 
    sensors_data_t.number_of_measure = 1;                           // Test filling data
    strcpy( sensors_data_t.sensor_name_1, "SI7021:");               // Test filling data
    strcpy( sensors_data_t.sensor_1_data, "T 21, H 70%");           // Test filling data
 
    //W25qxx_EraseChip();                   // Erase all flash chip
 
    unsigned int size = sizeof(sensors_data_t);
    write_struct_in_flash(sensors_data_t, size);
}
 
void write_struct_in_flash(struct sensors_data t, unsigned int size)
{
    static unsigned long flash_offset = 0;              // Flash address 
    if(flash_offset >= 65535)                           // Use only block 0
    {
        flash_offset = 0;
        W25qxx_EraseBlock(0);
    }
    
    for(int i = 0; i<= size; i++)
    {
        // Send data in flash, byte by byte
        flash_offset ++;
        //W25qxx_WriteByte(uint8_t byte, uint32_t flash_offset)
    }
}
// ----------------------------------------------------------------------------
Запись происходит только в один блок 0, если он заполнился данным, тогда блок стирается и перезаписывается с начала снова. Здесь можно сделать чтобы запись шла по всем блокам, и также записывать в счетчик сколько раз был записан блок, или вся память.

я не нашел ни одного примера как правильно паковать данные во внешнюю флэш память(
0
 Аватар для Voland_
1983 / 1276 / 131
Регистрация: 04.01.2010
Сообщений: 4,607
11.02.2021, 10:35
Цитата Сообщение от OlegD_STM32 Посмотреть сообщение
я не нашел ни одного примера
https://github.com/nimaltd/ee'

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

PS: в ходе обсуждения вы нигде не ошиблись - все супер. Небольшая ремарка лишь в том, что в функцию вы передаете всю структуру, а лучше было бы передавать только указатель. Имея функцию для записи данных только известного размера не нужен параметр "size". Это возможно, но как по мне - слишком проприетарное решение.
0
7 / 7 / 0
Регистрация: 26.11.2018
Сообщений: 262
11.02.2021, 18:48  [ТС]
Сейчас я записываю массив в котором есть: название сенсора, порядковый номер записи, данные температуры и влажности.
Данные пишутся в один сектор, это 128 записей. После переполнения сектора, он стирается и записывается по кругу снова. Но проблема в том, что при каждом включении у меня происходит стерання этого сектора, поскольку я не храню переменную flash_offset которая бы указывала на адрес внешний флэш памяти куда были записаны последний раз данные.

C
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
void test_flash_W25Q(void)
{
    uint8_t init=0;
    init = W25qxx_Init();
 
    uint32_t id=0;
    id = W25qxx_ReadID();
 
W25qxx_EraseSector(0);                  // First to all erase sector 0
 
 
 
    uint8_t tempetature = 21;
    uint8_t humidity = 80;
 
    save_data(tempetature, humidity);
 
    tempetature = 30;
    humidity = 90;
 
    save_data(tempetature, humidity);
 
    tempetature = 100;
    humidity = 60;
 
    save_data(tempetature, humidity);
 
 
    // Read sector from flash in the end
    char buff_for_read_from_flash[10000] = {0};         // Buffer for read data from flash
    memset(buff_for_read_from_flash, 0 , sizeof(buff_for_read_from_flash));
    W25qxx_ReadSector(buff_for_read_from_flash, 0, 0, 0);
}
// ----------------------------------------------------------------------------
void save_data(uint8_t tempetature, uint8_t humidity)
{
    static unsigned int number_of_measure = 1;
    static unsigned int flash_offset = 0;               // flash memory offset (One byre writer: flash_offset++)
 
    flash_offset = save_data_in_flash(tempetature, humidity, number_of_measure, flash_offset);
 
    // For save only in one sector
    if(flash_offset >= 4096)                    // 4096: size of one sector
    {
        flash_offset = 0;
        W25qxx_EraseSector(0);                  // First to all erase sector 0
    }
    number_of_measure ++;                       // How many message was save
 
}
// ----------------------------------------------------------------------------
unsigned int save_data_in_flash(uint8_t tempetature, uint8_t humidity, unsigned int number_of_measure, unsigned int flash_offset)
{
    char test_array [32] = {0};
    uint8_t q = 0;                                      // Counter of saved messages
    uint8_t pages = 0;                                  // Counter of pages
    uint8_t size_array = sizeof(test_array)-1;
 
    sprintf(test_array,"%s %d %s%d%s %s%d%s", "sensor_1", number_of_measure, "T:",tempetature, "C", "H:",humidity, "%");    // Write data on array
 
    for(int i = 0; i <=  size_array; i++)                       // Write all bytes from array
    {
        W25qxx_WriteByte(test_array[i], flash_offset++);        // Write all bytes from array
    }
 
    return flash_offset;
}
0
Эксперт .NET
 Аватар для Rius
13121 / 7682 / 1675
Регистрация: 25.05.2015
Сообщений: 23,452
Записей в блоге: 14
11.02.2021, 20:20
OlegD_STM32, задача сохранить настройки, которые будут храниться постоянно или изредка меняться? Или вести длинный лог мониторинга каких-то показаний?
1
7 / 7 / 0
Регистрация: 26.11.2018
Сообщений: 262
11.02.2021, 21:21  [ТС]
Добавлено через 54 секунды
Цитата Сообщение от Rius Посмотреть сообщение
OlegD_STM32, задача сохранить настройки, которые будут храниться постоянно или изредка меняться? Или вести длинный лог мониторинга каких-то показаний?
Задача записывать данные сенсора температуры и влаги. Нужные данные записывать постоянно, и после ресета данные должны дописываться на флэш с того самого места что и до момента ресета. Записывается пока данные циклически в один сектор. Я так понимаю мне нужно записывать еще одну переменную в определенный адрес флеша микроконтроллера или флэш памяти. Которая бы в указывала на последней flash_offset. Даже не одну переменную а две. Вторая это порядковый номер записи. Поскольку записывается все в таком виде:
C
1
sprintf(test_array,"%s %d %s%d%s %s%d%s", "sensor_1", number_of_measure, "T:",tempetature, "C", "H:",humidity, "%");    // Write data on array
0
Эксперт .NET
 Аватар для Rius
13121 / 7682 / 1675
Регистрация: 25.05.2015
Сообщений: 23,452
Записей в блоге: 14
11.02.2021, 21:23
То есть это лог мониторинга?

Добавлено через 47 секунд
Всю флешку можно занять им? Или только определённую часть?
1
 Аватар для Voland_
1983 / 1276 / 131
Регистрация: 04.01.2010
Сообщений: 4,607
11.02.2021, 21:24
Цитата Сообщение от OlegD_STM32 Посмотреть сообщение
проблема в том, что при каждом включении у меня происходит стерання этого сектора, поскольку я не храню переменную flash_offset
Так определяйте эту переменную, пытаясь найти последние записанные данные. Не записанные данные будут заполнены исходным значением FLASH (тут все зависит от архитектуры FLASH - могут быть нули или единицы).
0
7 / 7 / 0
Регистрация: 26.11.2018
Сообщений: 262
11.02.2021, 21:53  [ТС]
Цитата Сообщение от Rius Посмотреть сообщение
То есть это лог мониторинга?
Всю флешку можно занять им? Или только определённую часть?
Да. Сейчас мне достаточно сектора флэш памяти.

Цитата Сообщение от Voland_ Посмотреть сообщение
Так определяйте эту переменную, пытаясь найти последние записанные данные. Не записанные данные будут заполнены исходным значением FLASH (тут все зависит от архитектуры FLASH - могут быть нули или единицы).
Eсть функция: uint8_t W25qxx_IsEmptyPage(uint32_t Page_Address, uint32_t OffsetInByte). Ею можно пройтись и найти последний лог.
В одной странице меня может быть 8 записей.
Алгоритм такой:
1. При включении, просканировать память и найти страницу на которой последний запись. Если дошли до нулевой страницы, тогда считать flash_offset = 0.
2. C адресса конца найденной пустой страници побайтно проверять байты с 0xFF (erase).
3. Если равны, значит в данном байте Нет данных. И делать декремент адрес в пока не попадется первый байт с данными.
4. Если найден байт данным, мы от адреса этого байта отнимает 32 (Размер моего сообщения которое мы записываем char test_array [32]) и записываем это сообщение в наш буфер.
5. Парсимо после слова "sensor 1" номер записи, и обновляем его. Для того чтобы счетчик измерений продолжался с того же числа.

В теории, этот алгоритм должен решить нашу проблему с дозаписи в флэш память данных, и продолжать посслидовно считать наши измерения.

Если я где-то ошибаюсь, или делаю что-то не так, то пишите.
0
Эксперт .NET
 Аватар для Rius
13121 / 7682 / 1675
Регистрация: 25.05.2015
Сообщений: 23,452
Записей в блоге: 14
11.02.2021, 22:08
Для 256 байт слишком мало записей. Напрасный расход ресурса памяти.
Для сообщения надо не 32 байта, а всего лишь каких-то 8.

Парсинг текстов... беее...

При посекторном стирании памяти, хранить весь лог в одном секторе?..

Добавлено через 9 минут
Посмотрите, как пишет данные видеорегистратор в авто.
1
 Аватар для Voland_
1983 / 1276 / 131
Регистрация: 04.01.2010
Сообщений: 4,607
11.02.2021, 22:09
Цитата Сообщение от OlegD_STM32 Посмотреть сообщение
алгоритм должен решить нашу проблему
Вашу проблему, не "нашу" . В остальном все верно. А потом допилите систему с проверкой чексуммы данных, и будет совсем хорошо. Ведь при записи могут быть ошибки. А еще питание может неожиданно сброситься, флешь не идеальна - и данные хоть вы и пишете, они могут оказаться недостоверными. Поэтому, проверять достоверность данных не помешает.

PS: вообще, алгоритмы эмуляции EEPROM могут быть и хитрее. Допустим, когда Вы пишете в несколько страниц появляется необходимость организовывать FIFO (циклический буфер). Тогда в каждой записи нужно включать индекс записи. И искать последнее записанное сообщение по нему.
1
Эксперт .NET
 Аватар для Rius
13121 / 7682 / 1675
Регистрация: 25.05.2015
Сообщений: 23,452
Записей в блоге: 14
11.02.2021, 22:18
Эмуляция eeprom нужна при записи рандомных страниц.
Для лога мониторинга же требуется циклическая перезапись. Она намного проще. Но описанный алгоритм - не то.
1
7 / 7 / 0
Регистрация: 26.11.2018
Сообщений: 262
11.02.2021, 22:26  [ТС]
Цитата Сообщение от Rius Посмотреть сообщение
Для лога мониторинга же требуется циклическая перезапись. Она намного проще. Но описанный алгоритм - не то.
Вы имеете в виду записывать не в один сектор памяти а во всю память?
0
Эксперт .NET
 Аватар для Rius
13121 / 7682 / 1675
Регистрация: 25.05.2015
Сообщений: 23,452
Записей в блоге: 14
11.02.2021, 22:29
Лучше во всю.
Но можно и поменьше, сколько не жалко.
От размера записей, частоты их добавления, размера страниц, выделенного объёма секторов... зависит время исчерпания ресурса. И оно вычисляется.
1
 Аватар для Voland_
1983 / 1276 / 131
Регистрация: 04.01.2010
Сообщений: 4,607
12.02.2021, 00:48
Цитата Сообщение от Rius Посмотреть сообщение
Посмотрите, как пишет данные видеорегистратор в авто.
Видеорегистратора пишет кусками, но с помощью файловой системы .

Ну, то есть да, для упрощения самой задачи можно посоветовать воспользоваться драйвером файловой системы ). Но это ухудшит положение с жизнеспособностью флеши, и увеличит код программы. Зато появится гибкость и все преимущества файловой системы - пиши что хочешь и куда хочешь.
1
Эксперт .NET
 Аватар для Rius
13121 / 7682 / 1675
Регистрация: 25.05.2015
Сообщений: 23,452
Записей в блоге: 14
12.02.2021, 04:30
Voland_, не это важно. Регистратор пишет кусками. Складывая куски последовательно. Под последовательными возрастающими идентификаторами. Когда место в памяти заканчивается, самые старые куски удаляются, а новые пишутся уже на их место.
0
 Аватар для Voland_
1983 / 1276 / 131
Регистрация: 04.01.2010
Сообщений: 4,607
12.02.2021, 10:47
Цитата Сообщение от Rius Посмотреть сообщение
Когда место в памяти заканчивается, самые старые куски удаляются, а новые пишутся уже на их место.
Да, но делается это средствами файловой системы и ее драйвера, а не прямым доступом к FLASH ). Вы не находите, что это важная разница? Алгоритм (самостоятельной) циклической записи во FLASH будет несколько сложнее, чем использование FileSystem API.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
12.02.2021, 10:47
Помогаю со студенческими работами здесь

STM32F4 SPI Master + STM32F103 Slave
Добрый день, столкнулся со странной проблемой SPI. Заключается она в смещении последнего или первого бита посылки. Если оба SPI настраивать...

STM32F103 SPI не дрыгает ножкой NSS
Блин никак не могу заставить стм-ку задрыгать ногой NSS самостоятельно В чем косяк ? #define SPI SPI1 #define...

stm32f103 + eeprom spi (нет любви)
Собсна проблема. EEPROM - 25lc256. Читаем. Отсылаем команду, 16 битный адрес ячейки. Ведомый задирает ногу MISO, т.е. вроде реагирует. И...

STM32F103 - ошибка в описании в режиме SPI SimplexUnidirect?
При попытке подключения АЦП к МК (STM32F103T8U6) по SPI выявилось несовпадение с документацией. Согласно ТД, SPI имеет такое...

STM32F103 и синхронная передача по двум каналам SPI
Доброго времени суток :) Может немного глупый вопрос, но можно ли завести два SPI канала через DMA на вывод так, чтобы данные передавались...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11680&amp;d=1772460536 Одним из. . .
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
SDL3 для Web (WebAssembly): Сборка библиотек: SDL3, Box2D, FreeType, SDL3_ttf, SDL3_mixer и SDL3_image из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru