From 55c17cf2b6bf923809699c4019f7c5816cd3b01c Mon Sep 17 00:00:00 2001 From: EgorShin <98223248+EgorShin@users.noreply.github.com> Date: Tue, 8 Oct 2024 10:34:05 +0700 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=BF=D0=B8=D1=81=D0=B0=D0=BB=20ge?= =?UTF-8?q?t=20=D0=B8=20put,=20=D0=BF=D0=BE=D1=87=D0=B8=D0=BD=D0=B8=D0=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- libraries/.vscode/c_cpp_properties.json | 18 ++++ libraries/.vscode/launch.json | 24 +++++ libraries/.vscode/settings.json | 73 ++++++++++++-- libraries/EEPROM/src/EEPROM.cpp | 45 --------- libraries/EEPROM/src/EEPROM.h | 123 +++++++++++++++++++++--- 5 files changed, 219 insertions(+), 64 deletions(-) create mode 100644 libraries/.vscode/c_cpp_properties.json create mode 100644 libraries/.vscode/launch.json diff --git a/libraries/.vscode/c_cpp_properties.json b/libraries/.vscode/c_cpp_properties.json new file mode 100644 index 0000000..72461c3 --- /dev/null +++ b/libraries/.vscode/c_cpp_properties.json @@ -0,0 +1,18 @@ +{ + "configurations": [ + { + "name": "windows-gcc-x64", + "includePath": [ + "${workspaceFolder}/**" + ], + "compilerPath": "D:/Progi/Strawberry/c/bin/gcc.exe", + "cStandard": "${default}", + "cppStandard": "${default}", + "intelliSenseMode": "windows-gcc-x64", + "compilerArgs": [ + "" + ] + } + ], + "version": 4 +} \ No newline at end of file diff --git a/libraries/.vscode/launch.json b/libraries/.vscode/launch.json new file mode 100644 index 0000000..abd5da5 --- /dev/null +++ b/libraries/.vscode/launch.json @@ -0,0 +1,24 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "C/C++ Runner: Debug Session", + "type": "cppdbg", + "request": "launch", + "args": [], + "stopAtEntry": false, + "externalConsole": true, + "cwd": "c:/Users/biska/AppData/Local/Arduino15/packages/Elron/hardware/MIK32_Amur/0.2.0/libraries/EEPROM/src", + "program": "c:/Users/biska/AppData/Local/Arduino15/packages/Elron/hardware/MIK32_Amur/0.2.0/libraries/EEPROM/src/build/Debug/outDebug", + "MIMode": "gdb", + "miDebuggerPath": "gdb", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + } + ] + } + ] +} \ No newline at end of file diff --git a/libraries/.vscode/settings.json b/libraries/.vscode/settings.json index a6c7df7..b12517e 100644 --- a/libraries/.vscode/settings.json +++ b/libraries/.vscode/settings.json @@ -1,10 +1,67 @@ { - "files.associations": { - "cstdint": "cpp", - "compare": "cpp", - "array": "cpp", - "string": "cpp", - "string_view": "cpp", - "initializer_list": "cpp" - } + "files.associations": { + "cstdint": "cpp", + "compare": "cpp", + "array": "cpp", + "string": "cpp", + "string_view": "cpp", + "initializer_list": "cpp" + }, + "C_Cpp_Runner.cCompilerPath": "gcc", + "C_Cpp_Runner.cppCompilerPath": "g++", + "C_Cpp_Runner.debuggerPath": "gdb", + "C_Cpp_Runner.cStandard": "", + "C_Cpp_Runner.cppStandard": "", + "C_Cpp_Runner.msvcBatchPath": "C:/Program Files/Microsoft Visual Studio/VR_NR/Community/VC/Auxiliary/Build/vcvarsall.bat", + "C_Cpp_Runner.useMsvc": false, + "C_Cpp_Runner.warnings": [ + "-Wall", + "-Wextra", + "-Wpedantic", + "-Wshadow", + "-Wformat=2", + "-Wcast-align", + "-Wconversion", + "-Wsign-conversion", + "-Wnull-dereference" + ], + "C_Cpp_Runner.msvcWarnings": [ + "/W4", + "/permissive-", + "/w14242", + "/w14287", + "/w14296", + "/w14311", + "/w14826", + "/w44062", + "/w44242", + "/w14905", + "/w14906", + "/w14263", + "/w44265", + "/w14928" + ], + "C_Cpp_Runner.enableWarnings": true, + "C_Cpp_Runner.warningsAsError": false, + "C_Cpp_Runner.compilerArgs": [], + "C_Cpp_Runner.linkerArgs": [], + "C_Cpp_Runner.includePaths": [], + "C_Cpp_Runner.includeSearch": [ + "*", + "**/*" + ], + "C_Cpp_Runner.excludeSearch": [ + "**/build", + "**/build/**", + "**/.*", + "**/.*/**", + "**/.vscode", + "**/.vscode/**" + ], + "C_Cpp_Runner.useAddressSanitizer": false, + "C_Cpp_Runner.useUndefinedSanitizer": false, + "C_Cpp_Runner.useLeakSanitizer": false, + "C_Cpp_Runner.showCompilationTime": false, + "C_Cpp_Runner.useLinkTimeOptimization": false, + "C_Cpp_Runner.msvcSecureNoWarnings": false } \ No newline at end of file diff --git a/libraries/EEPROM/src/EEPROM.cpp b/libraries/EEPROM/src/EEPROM.cpp index 4ff50a0..4ab2572 100644 --- a/libraries/EEPROM/src/EEPROM.cpp +++ b/libraries/EEPROM/src/EEPROM.cpp @@ -104,51 +104,6 @@ uint16_t EEPROMClass:: length( void ) return (uint16_t)EEPROM_LENGHT; } -// // template< typename T > -// void* EEPROMClass:: put(int idx, void* dataPointer) -// { -// // Проверка адекватности адреса idx -// if (((uint32_t)idx >= (uint32_t)EEPROM_LENGHT) || (idx < 0)) -// return dataPointer; // #TODO Добавить сообщение об ошибке -// // Проверка того, что данные влезут в eeprom, если начинать с текущего адреса -// if (sizeof(dataPointer) > ((int)EEPROM_LENGHT - idx)) -// return dataPointer; // #TODO Добавить сообщение об ошибке - -// uint32_t write_data_buf[EEPROM_PAGE_WORDS] = {}; - -// // Вычисление адресы начала нужной страницы -// uint32_t addr = EEPROM_START_ADDR + (((uint32_t)idx) / EEPROM_PAGE_SIZE) * EEPROM_PAGE_SIZE; -// // Читаем нужную страницу -// HAL_EEPROM_Read(&heeprom, (uint16_t)addr, write_data_buf, EEPROM_PAGE_WORDS, EEPROM_OP_TIMEOUT); -// uint8_t size = sizeof(dataPointer); -// memcpy((void *)((uint8_t *)write_data_buf + idx), (void *)&size, 20); - -// HAL_EEPROM_Erase(&heeprom, (uint16_t)addr, EEPROM_PAGE_WORDS, HAL_EEPROM_WRITE_SINGLE, EEPROM_OP_TIMEOUT); -// HAL_EEPROM_Write(&heeprom, (uint16_t)addr, write_data_buf, EEPROM_PAGE_WORDS, HAL_EEPROM_WRITE_SINGLE, EEPROM_OP_TIMEOUT); - -// // Количество байт данных для записи. -// // int count = sizeof(T); - -// // Цикл для записи данных побайтно в EEPROM. -// // for(uint16_t i = 0; i < sizeof(T); i++) { -// // // Запись текущего байта данных в EEPROM. -// // EEPROM.update(ee_idx + i, *ptr++ ); -// // } - -// // Запись данных в eeprom -// // Возврат ссылки на записанный объект. -// return dataPointer; -// } -template< typename T > -T& EEPROMClass:: get(int idx, T &t) { - // EEPtr e = idx; // Указатель на адрес в EEPROM - // uint8_t *ptr = (uint8_t*) &t; // Преобразуем ссылку на объект данных в указатель на байт - // for (int count = sizeof(T); count; --count, ++e) { - // *ptr++ = *e; // Читаем данные из EEPROM и записываем в объект - // } - return t; // Возвращаем ссылку на переданный объект с прочитанными данными -} - void HAL_read(uint16_t addr, uint32_t * data) { HAL_EEPROM_Read(&heeprom, (uint16_t)addr, data, EEPROM_PAGE_WORDS, EEPROM_OP_TIMEOUT); diff --git a/libraries/EEPROM/src/EEPROM.h b/libraries/EEPROM/src/EEPROM.h index ca1116d..40471d1 100644 --- a/libraries/EEPROM/src/EEPROM.h +++ b/libraries/EEPROM/src/EEPROM.h @@ -154,42 +154,70 @@ struct EEPROMClass{ // Сдвиг начала записи данных uint32_t dataShift = 0; uint32_t writeSize = dataSize; + // uint8_t* dataPointer_8 = (uint8_t*)dataPointer; + // uint8_t* writePointer_8 = (uint8_t*)write_data_buf; // Вычисление адресы начала нужной страницы uint32_t addr = EEPROM_START_ADDR + (((uint32_t)idx) / EEPROM_PAGE_SIZE) * EEPROM_PAGE_SIZE; + // Адрес искомого слова в eeprom: EEPROM_START_ADDR + (uint32_t)idx + uint32_t word_addr = EEPROM_START_ADDR + (((uint32_t)idx) / EEPROM_WORD_SIZE) * EEPROM_WORD_SIZE; + // Индекс искомого слова в массиве write_data_buf: адрес слова в eeprom за вычетом адреса начала страницы + uint32_t word_idx = (word_addr - addr) / EEPROM_WORD_SIZE; // Адрес начала данных на странице uint32_t byte_addr = (uint32_t)idx % EEPROM_PAGE_SIZE; + // Номер байта в составе слова + uint32_t byte_idx = ((uint32_t)idx) % EEPROM_WORD_SIZE; // Чтение первой страницы HAL_read((uint16_t)addr, write_data_buf); // Если данные не влезут на первую страницу, то записываем только то, что влезло if (EEPROM_PAGE_SIZE - byte_addr < dataSize) { writeSize = EEPROM_PAGE_SIZE - byte_addr; + // lastWord = EEPROM_PAGE_WORDS - 1; } + uint32_t lastWord = (writeSize + byte_idx - 1) / EEPROM_WORD_SIZE + word_idx; dataSize -= writeSize; - // Копирование данных в буфер для записи в три этапа: первый - копирование того, что идёт до первого целого слова, - // второй - копирование целых слов, третий - копирование того, что идёт после последнего целого слова + // Запись данных постранично, сначала записываем первую страницу - отдельно memcpy((void *)((uint8_t *)write_data_buf + byte_addr), (void*)dataPointer, writeSize); - + // Разворачиваем слова + for(uint8_t i = word_idx; i <= lastWord; i++) + { + uint32_t word = write_data_buf[i]; + write_data_buf[i] = 0; + write_data_buf[i] = ((word & 0xFF)<<24) | ((word & (0xFF<<8))<<8) | ((word & (0xFF<<16))>>8) | ((word & (0xFF<<24))>>24); + } + // for (uint8_t i = 0; i < writeSize; i++, dataPointer_8++) + // *(writePointer_8 + byte_addr + i) = *(dataPointer_8); HAL_erase((uint16_t)addr); HAL_write((uint16_t)addr, write_data_buf); // Если данные остались после записи первой страницы, то пишем их постранично, пока не закончатся while (dataSize > 0) { - addr += EEPROM_PAGE_SIZE; - HAL_read((uint16_t)addr, write_data_buf); dataShift += writeSize; + // addr = EEPROM_START_ADDR + ((dataShift) / EEPROM_PAGE_SIZE) * EEPROM_PAGE_SIZE; + addr += EEPROM_PAGE_SIZE; //Почему-то не работает с uint32_t данными + // addr = EEPROM_START_ADDR; + HAL_read((uint16_t)addr, write_data_buf); writeSize = dataSize; if (EEPROM_PAGE_SIZE < dataSize) { writeSize = EEPROM_PAGE_SIZE; - dataShift += writeSize; + // dataShift += writeSize; } - dataSize -= writeSize; - memcpy((void *)((uint8_t *)write_data_buf), (void*)(dataPointer + dataShift), writeSize); - + lastWord = (writeSize - 1) / EEPROM_WORD_SIZE; + memcpy((void *)(write_data_buf), (void*)((uint8_t *)dataPointer + dataShift), writeSize); + // Разворачиваем слова + for(uint8_t i = 0; i <= lastWord; i++) + { + uint32_t word = write_data_buf[i]; + write_data_buf[i] = 0; + write_data_buf[i] = ((word & 0xFF)<<24) | ((word & (0xFF<<8))<<8) | ((word & (0xFF<<16))>>8) | ((word & (0xFF<<24))>>24); + } + // for (uint8_t i = 0; i < writeSize; i++, dataPointer_8++) + // *(write_data_buf + byte_addr + i) = *dataPointer_8; HAL_erase((uint16_t)addr); HAL_write((uint16_t)addr, write_data_buf); + dataSize -= writeSize; } // Количество байт данных для записи. @@ -206,8 +234,81 @@ struct EEPROMClass{ return dataPointer; } - template - T& get(int address, T& data); + template< typename T > + T& get(int idx, T& dataPointer) { + // EEPtr e = idx; // Указатель на адрес в EEPROM + // uint8_t *ptr = (uint8_t*) &t; // Преобразуем ссылку на объект данных в указатель на байт + // for (int count = sizeof(T); count; --count, ++e) { + // *ptr++ = *e; // Читаем данные из EEPROM и записываем в объект + // } + + // Проверка адекватности адреса idx + if (((uint32_t)idx >= (uint32_t)EEPROM_LENGHT) || (idx < 0)) + return dataPointer; // #TODO Добавить сообщение об ошибке + + uint32_t read_data_buf[EEPROM_PAGE_WORDS] = {}; + // Размер данных + uint32_t dataSize = sizeof(dataPointer); + // Сдвиг начала чтения данных + uint32_t dataShift = 0; + uint32_t readSize = dataSize; + + // Вычисление адресы начала нужной страницы + uint32_t addr = EEPROM_START_ADDR + (((uint32_t)idx) / EEPROM_PAGE_SIZE) * EEPROM_PAGE_SIZE; + // Адрес искомого слова в eeprom: EEPROM_START_ADDR + (uint32_t)idx + uint32_t word_addr = EEPROM_START_ADDR + (((uint32_t)idx) / EEPROM_WORD_SIZE) * EEPROM_WORD_SIZE; + // Индекс искомого слова в массиве write_data_buf: адрес слова в eeprom за вычетом адреса начала страницы + uint32_t word_idx = (word_addr - addr) / EEPROM_WORD_SIZE; + // Адрес начала данных на странице + uint32_t byte_addr = (uint32_t)idx % EEPROM_PAGE_SIZE; + // Номер байта в составе слова + uint32_t byte_idx = ((uint32_t)idx) % EEPROM_WORD_SIZE; + // Чтение первой страницы + HAL_read((uint16_t)addr, read_data_buf); + uint32_t lastWord = (dataSize + byte_idx - 1) / EEPROM_WORD_SIZE + word_idx; + if (EEPROM_PAGE_SIZE - byte_addr < dataSize) + { + readSize = EEPROM_PAGE_SIZE - byte_addr; + lastWord = EEPROM_PAGE_WORDS - 1; + } + dataSize -= readSize; + // Разворачиваем слова + for(uint8_t i = word_idx; i <= lastWord; i++) + { + uint32_t word = read_data_buf[i]; + read_data_buf[i] = 0; + read_data_buf[i] = ((word & 0xFF)<<24) | ((word & (0xFF<<8))<<8) | ((word & (0xFF<<16))>>8) | ((word & (0xFF<<24))>>24); + } + // Чтение данных постранично, сначала читаем первую страницу - отдельно + memcpy((void *)dataPointer, (void*)((uint8_t *)read_data_buf + byte_addr), readSize); + + // Если данные остались после записи первой страницы, то пишем их постранично, пока не закончатся + while (dataSize > 0) + { + addr += EEPROM_PAGE_SIZE; + HAL_read((uint16_t)addr, read_data_buf); + dataShift += readSize; + readSize = dataSize; + if (EEPROM_PAGE_SIZE < dataSize) + { + readSize = EEPROM_PAGE_SIZE; + // dataShift += readSize; + } + lastWord = (dataSize - 1) / EEPROM_WORD_SIZE; + dataSize -= readSize; + // Разворачиваем слова + for(uint8_t i = word_idx; i <= lastWord; i++) + { + uint32_t word = read_data_buf[i]; + read_data_buf[i] = 0; + read_data_buf[i] = ((word & 0xFF)<<24) | ((word & (0xFF<<8))<<8) | ((word & (0xFF<<16))>>8) | ((word & (0xFF<<24))>>24); + } + memcpy((void *)(dataPointer + dataShift), (void*)((uint8_t *)read_data_buf), readSize); + // for (uint8_t i = 0; i < readSize; i++, dataPointer_8++) + // *(read_data_buf + byte_addr + i) = *dataPointer_8; + } + return dataPointer; // Возвращаем ссылку на переданный объект с прочитанными данными +} //Functionality to 'get' and 'put' objects to and from EEPROM. // template< typename T > T &get( int idx, T &t ){