blob: 0b88382832972ebfc2ebfafb3b55e693cf0ce368 [file] [log] [blame]
David Rogers5cc5ce82020-03-13 19:19:03 -07001// Copyright 2020 The Pigweed Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License"); you may not
4// use this file except in compliance with the License. You may obtain a copy of
5// the License at
6//
7// https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12// License for the specific language governing permissions and limitations under
13// the License.
14
David Rogerseb05d882021-10-12 15:24:48 -070015#define PW_LOG_MODULE_NAME "PW_FLASH"
Wyatt Heplerae222dc2020-10-14 10:46:27 -070016#define PW_LOG_LEVEL PW_KVS_LOG_LEVEL
Armando Montanez28ecccb2020-05-04 15:35:54 -070017
David Rogers5cc5ce82020-03-13 19:19:03 -070018#include "pw_kvs/flash_partition_with_stats.h"
19
20#include <cstdio>
21
22#include "pw_kvs/flash_memory.h"
Wyatt Heplerae222dc2020-10-14 10:46:27 -070023#include "pw_kvs_private/config.h"
David Rogers5cc5ce82020-03-13 19:19:03 -070024#include "pw_log/log.h"
25
26namespace pw::kvs {
27
28Status FlashPartitionWithStats::SaveStorageStats(const KeyValueStore& kvs,
29 const char* label) {
Ted Pudlik10ec2bd2021-10-27 21:17:09 +000030 // If empty, saving stats is disabled so do not save any stats.
31 if (sector_counters_.empty()) {
Wyatt Hepler1b3da3a2021-01-07 13:26:57 -080032 return OkStatus();
David Rogers5cc5ce82020-03-13 19:19:03 -070033 }
34
35 KeyValueStore::StorageStats stats = kvs.GetStorageStats();
36 size_t utilization_percentage = (stats.in_use_bytes * 100) / size_bytes();
37
38 const char* file_name = "flash_stats.csv";
39 std::FILE* out_file = std::fopen(file_name, "a+");
40 if (out_file == nullptr) {
41 PW_LOG_ERROR("Failed to dump to %s", file_name);
Wyatt Heplerd78f7c62020-09-28 14:27:32 -070042 return Status::NotFound();
David Rogers5cc5ce82020-03-13 19:19:03 -070043 }
44
45 // If file is empty add the header row.
46 std::fseek(out_file, 0, SEEK_END);
47 if (std::ftell(out_file) == 0) {
48 std::fprintf(out_file,
49 "Test Name,Total Erases,Utilization Percentage,Transaction "
50 "Count,Entry Count");
51 for (size_t i = 0; i < sector_counters_.size(); i++) {
52 std::fprintf(out_file, ",Sector %zu", i);
53 }
54 std::fprintf(out_file, "\n");
55 }
56
57 std::fprintf(out_file, "\"%s\",%zu", label, total_erase_count());
58 std::fprintf(out_file,
59 ",%zu,%u,%zu",
60 utilization_percentage,
Wyatt Hepler09b3a2a2020-03-25 13:18:37 -070061 unsigned(kvs.transaction_count()),
David Rogers5cc5ce82020-03-13 19:19:03 -070062 kvs.size());
63
64 for (size_t counter : sector_erase_counters()) {
65 std::fprintf(out_file, ",%zu", counter);
66 }
67
68 std::fprintf(out_file, "\n");
69 std::fclose(out_file);
Wyatt Hepler1b3da3a2021-01-07 13:26:57 -080070 return OkStatus();
David Rogers5cc5ce82020-03-13 19:19:03 -070071}
72
73Status FlashPartitionWithStats::Erase(Address address, size_t num_sectors) {
74 size_t base_index = address / FlashPartition::sector_size_bytes();
75 if (base_index < sector_counters_.size()) {
76 num_sectors = std::min(num_sectors, (sector_counters_.size() - base_index));
77 for (size_t i = 0; i < num_sectors; i++) {
78 sector_counters_[base_index + i]++;
79 }
80 }
81
82 return FlashPartition::Erase(address, num_sectors);
83}
84
85} // namespace pw::kvs