blob: d6fe2839e772e0c361123e9f1a3c8c91ae116d12 [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
Armando Montanez28ecccb2020-05-04 15:35:54 -070015#define PW_LOG_MODULE_NAME "KVS"
16
David Rogers5cc5ce82020-03-13 19:19:03 -070017#include "pw_kvs/flash_partition_with_stats.h"
18
19#include <cstdio>
20
21#include "pw_kvs/flash_memory.h"
22#include "pw_log/log.h"
23
24namespace pw::kvs {
25
26Status FlashPartitionWithStats::SaveStorageStats(const KeyValueStore& kvs,
27 const char* label) {
28 // If size is zero saving stats is disabled so do not save any stats.
29 if (sector_counters_.size() == 0) {
Wyatt Heplerd78f7c62020-09-28 14:27:32 -070030 return Status::Ok();
David Rogers5cc5ce82020-03-13 19:19:03 -070031 }
32
33 KeyValueStore::StorageStats stats = kvs.GetStorageStats();
34 size_t utilization_percentage = (stats.in_use_bytes * 100) / size_bytes();
35
36 const char* file_name = "flash_stats.csv";
37 std::FILE* out_file = std::fopen(file_name, "a+");
38 if (out_file == nullptr) {
39 PW_LOG_ERROR("Failed to dump to %s", file_name);
Wyatt Heplerd78f7c62020-09-28 14:27:32 -070040 return Status::NotFound();
David Rogers5cc5ce82020-03-13 19:19:03 -070041 }
42
43 // If file is empty add the header row.
44 std::fseek(out_file, 0, SEEK_END);
45 if (std::ftell(out_file) == 0) {
46 std::fprintf(out_file,
47 "Test Name,Total Erases,Utilization Percentage,Transaction "
48 "Count,Entry Count");
49 for (size_t i = 0; i < sector_counters_.size(); i++) {
50 std::fprintf(out_file, ",Sector %zu", i);
51 }
52 std::fprintf(out_file, "\n");
53 }
54
55 std::fprintf(out_file, "\"%s\",%zu", label, total_erase_count());
56 std::fprintf(out_file,
57 ",%zu,%u,%zu",
58 utilization_percentage,
Wyatt Hepler09b3a2a2020-03-25 13:18:37 -070059 unsigned(kvs.transaction_count()),
David Rogers5cc5ce82020-03-13 19:19:03 -070060 kvs.size());
61
62 for (size_t counter : sector_erase_counters()) {
63 std::fprintf(out_file, ",%zu", counter);
64 }
65
66 std::fprintf(out_file, "\n");
67 std::fclose(out_file);
Wyatt Heplerd78f7c62020-09-28 14:27:32 -070068 return Status::Ok();
David Rogers5cc5ce82020-03-13 19:19:03 -070069}
70
71Status FlashPartitionWithStats::Erase(Address address, size_t num_sectors) {
72 size_t base_index = address / FlashPartition::sector_size_bytes();
73 if (base_index < sector_counters_.size()) {
74 num_sectors = std::min(num_sectors, (sector_counters_.size() - base_index));
75 for (size_t i = 0; i < num_sectors; i++) {
76 sector_counters_[base_index + i]++;
77 }
78 }
79
80 return FlashPartition::Erase(address, num_sectors);
81}
82
83} // namespace pw::kvs