Updated logging, binary search to find starting point.

This commit is contained in:
dario 2024-06-04 18:40:48 +02:00
parent a15b2398ab
commit 33e034a429
4 changed files with 56 additions and 24 deletions

View File

@ -61,6 +61,7 @@
#define W25QXX_PAGE_SIZE 0x100 #define W25QXX_PAGE_SIZE 0x100
#define W25QXX_SECTOR_SIZE 0x1000 #define W25QXX_SECTOR_SIZE 0x1000
#define W25QXX_PAGE_PER_SECTOR 0x10
#define W25QXX_BLOCK_32_KB_SIZE 0x8000 #define W25QXX_BLOCK_32_KB_SIZE 0x8000
#define W25QXX_BLOCK_64_KB_SIZE 0xF000 #define W25QXX_BLOCK_64_KB_SIZE 0xF000

View File

@ -26,8 +26,9 @@ namespace sta
* @note If the total capacity of this logger was exceeded, it restarts at the first sector, overwriting its data. * @note If the total capacity of this logger was exceeded, it restarts at the first sector, overwriting its data.
* *
* @param data The data to write to the flash chip. * @param data The data to write to the flash chip.
* @return true if successful, false if the segment end was reached.
*/ */
void write(T data); bool write(T data);
/** /**
* @brief Clear the flash memory used by the logger. * @brief Clear the flash memory used by the logger.
@ -40,7 +41,7 @@ namespace sta
* *
* @return size_t The number of data points. * @return size_t The number of data points.
*/ */
size_t occupied(); size_t count();
/** /**
* @brief Get the number of data points that can be written to the logger before an overflow occurs. * @brief Get the number of data points that can be written to the logger before an overflow occurs.
@ -54,16 +55,18 @@ namespace sta
* *
* @return size_t The number of data points. * @return size_t The number of data points.
*/ */
size_t length(); size_t capacity();
/** /**
* @brief Allows reading a single data point from the segment. * @brief Allows reading a single data point from the segment.
* *
* @param idx The index of the segement. * @param idx The index of the segement.
* @return const T& The read data value. * @return T The read data value.
*/ */
T operator[](std::size_t idx); T operator[](std::size_t idx);
private: private:
void findLast();
W25Qxx * flash_; W25Qxx * flash_;
uint32_t start_; uint32_t start_;
uint32_t end_; uint32_t end_;

View File

@ -17,26 +17,52 @@ namespace sta
{ {
STA_ASSERT(flash != nullptr); STA_ASSERT(flash != nullptr);
STA_ASSERT(endAddr > startAddr); STA_ASSERT(endAddr > startAddr);
// Jump to the last written page.
findLast();
} }
template <typename T> template <typename T>
void Logger<T>::write(T data) void Logger<T>::findLast()
{ {
uint8_t * bytes = (uint8_t*)(&data); address_ = this->flash_->findLast([](uint8_t * buffer) -> bool {
for (size_t i = 0; i < W25QXX_PAGE_SIZE; i++)
{
if (buffer[i] != 0xFF)
{
return true;
}
}
return false;
}, sta::ChunkSize::PAGE, start_ * W25QXX_SECTOR_SIZE, end_ * W25QXX_SECTOR_SIZE);
STA_DEBUG_PRINTF("Starting at page with address %d\n", address_);
}
template <typename T>
bool Logger<T>::write(T data)
{
// If writing the data would exceed the segment length, return false and don't do anything.
if ((address_ + ptr_ + sizeof(T)) / W25QXX_SECTOR_SIZE == end_)
return false;
// Convert the data to a byte array.
uint8_t * bytes = reinterpret_cast<uint8_t*>(&data);
uint8_t length = sizeof(T); uint8_t length = sizeof(T);
// Bytes remaining until the page is full. // Bytes remaining until the page is full.
uint8_t remaining = W25QXX_PAGE_SIZE - ptr_; uint8_t remaining = W25QXX_PAGE_SIZE - ptr_;
STA_DEBUG_PRINTF("Writing at address %d\n", address_+ptr_); STA_DEBUG_PRINTF("Writing at address %d\n", address_ + ptr_);
// If the written data exceeds the remaining bytes in the page. // If the written data exceeds the remaining bytes in the page.
if (ptr_ + length >= W25QXX_PAGE_SIZE) if (ptr_ + length >= W25QXX_PAGE_SIZE)
{ {
// If the segment is full, stop writing data to it. // If the page to written is in a new sector, erase the new sector before writing to it.
if (address_ / W25QXX_SECTOR_SIZE == end_) if (address_ % W25QXX_SECTOR_SIZE == 0)
{ {
return; flash_->sectorErase(address_);
} }
std::memcpy(buffer_ + ptr_, bytes, remaining); std::memcpy(buffer_ + ptr_, bytes, remaining);
@ -45,19 +71,17 @@ namespace sta
bytes += remaining; bytes += remaining;
length -= remaining; length -= remaining;
ptr_ = 0; ptr_ = 0;
STA_DEBUG_PRINTLN("New PAGE!");
address_ += W25QXX_PAGE_SIZE; address_ += W25QXX_PAGE_SIZE;
// If a new sector has to be started, erase the new sector.
if (address_ % W25QXX_SECTOR_SIZE == 0)
{
flash_->sectorErase(address_);
}
} }
std::memcpy(buffer_ + ptr_, bytes, length); std::memcpy(buffer_ + ptr_, bytes, length);
ptr_ += length; ptr_ += length;
// If the end of the segment was reached, flush the temporally stored data.
if ((address_ + ptr_ + sizeof(T)) / W25QXX_SECTOR_SIZE == end_)
flash_->pageProgram(address_, buffer_, W25QXX_PAGE_SIZE);
return true;
} }
template <typename T> template <typename T>
@ -73,19 +97,19 @@ namespace sta
} }
template <typename T> template <typename T>
size_t Logger<T>::occupied() size_t Logger<T>::count()
{ {
return (address_ - start_ * W25QXX_SECTOR_SIZE) / sizeof(T); return ((address_ + ptr_) - start_ * W25QXX_SECTOR_SIZE) / sizeof(T);
} }
template <typename T> template <typename T>
size_t Logger<T>::remaining() size_t Logger<T>::remaining()
{ {
return (end_ * W25QXX_SECTOR_SIZE - address_) / sizeof(T); return (end_ * W25QXX_SECTOR_SIZE - (address_ + ptr_)) / sizeof(T);
} }
template <typename T> template <typename T>
size_t Logger<T>::length() size_t Logger<T>::capacity()
{ {
return (end_ - start_) * W25QXX_SECTOR_SIZE / sizeof(T); return (end_ - start_) * W25QXX_SECTOR_SIZE / sizeof(T);
} }
@ -94,6 +118,7 @@ namespace sta
T Logger<T>::operator[](std::size_t idx) T Logger<T>::operator[](std::size_t idx)
{ {
uint32_t address = start_ * W25QXX_SECTOR_SIZE + idx * sizeof(T); uint32_t address = start_ * W25QXX_SECTOR_SIZE + idx * sizeof(T);
STA_DEBUG_PRINTF("Reading from address %d\n", address);
// If the requested element is in the cache, read it from there. // If the requested element is in the cache, read it from there.
if (address / W25QXX_PAGE_SIZE == address_ / W25QXX_PAGE_SIZE) if (address / W25QXX_PAGE_SIZE == address_ / W25QXX_PAGE_SIZE)

View File

@ -88,6 +88,7 @@ namespace sta
while (left < right) while (left < right)
{ {
middle = (left + right) / 2; middle = (left + right) / 2;
STA_DEBUG_PRINTF("left=%d, middle=%d, right=%d", left, middle, right);
readData(middle * bytes, buffer, bytes); readData(middle * bytes, buffer, bytes);
if (criterion(buffer)) if (criterion(buffer))
@ -101,11 +102,13 @@ namespace sta
} }
middle = (left + right) / 2; middle = (left + right) / 2;
STA_DEBUG_PRINTLN(middle);
readData(middle * bytes, buffer, bytes); readData(middle * bytes, buffer, bytes);
if (criterion(buffer)) if (criterion(buffer))
{ {
middle += 1; middle += 1;
STA_DEBUG_PRINTLN("PLUS ONE");
} }
delete[] buffer; delete[] buffer;