able to write and read from nvs; completed topology test main

This commit is contained in:
superkor
2026-01-24 22:17:27 -05:00
parent 5124c97b76
commit 1576c73f3a
8 changed files with 181 additions and 31 deletions

View File

@@ -1,23 +1,48 @@
#include "TopologyBuilder.h"
#ifdef TOPOLOGYBUILDER
namespace Flatbuffers{
SerializedMessage TopologyBuilder::build_topology(const std::vector<flatbuffers::Offset<Topology::NeighbourBlob>>& topology){
SerializedMessage TopologyBuilder::build_topology(const std::unordered_map<uint16_t, std::vector<Topology::ChannelBoardConn>>& topology_map) {
builder_.Clear();
auto neighbours_vec = builder_.CreateVector(topology);
auto topology_offset = Topology::CreateTopologyInfo(builder_, static_cast<uint16_t>(topology.size()), neighbours_vec);
std::vector<flatbuffers::Offset<Topology::NeighbourBlob>> neighbours;
neighbours.reserve(topology_map.size());
for (const auto& [board_id, connections] : topology_map) {
auto conn_vec = builder_.CreateVectorOfStructs(connections);
auto blob = Topology::CreateNeighbourBlob(
builder_,
board_id,
static_cast<uint8_t>(connections.size()),
conn_vec
);
neighbours.push_back(blob);
}
auto neighbours_vec = builder_.CreateVector(neighbours);
auto topology_offset = Topology::CreateTopologyInfo(
builder_,
static_cast<uint16_t>(neighbours.size()),
neighbours_vec
);
builder_.Finish(topology_offset);
return {
builder_.GetBufferPointer(),
builder_.GetSize()
};
return { builder_.GetBufferPointer(), builder_.GetSize() };
}
flatbuffers::Offset<Topology::NeighbourBlob> TopologyBuilder::build_neighbour_info(uint16_t board_id, const std::vector<Topology::ChannelBoardConn>& connections){
auto conn = builder_.CreateVectorOfStructs(connections);
return Topology::CreateNeighbourBlob(builder_, board_id, static_cast<uint8_t>(connections.size()), conn);
flatbuffers::Offset<Topology::NeighbourBlob> TopologyBuilder::build_neighbour_info(
uint16_t board_id,
const std::vector<Topology::ChannelBoardConn>& connections
) {
auto conn_vec = builder_.CreateVectorOfStructs(connections);
return Topology::CreateNeighbourBlob(
builder_,
board_id,
static_cast<uint8_t>(connections.size()),
conn_vec
);
}
Topology::ChannelBoardConn TopologyBuilder::build_connections(uint8_t channel, uint16_t board_id){

View File

@@ -14,11 +14,11 @@ namespace Flatbuffers {
public:
TopologyBuilder() : builder_(RIP_MAX_ROUTES*(sizeof(Topology::NeighbourBlob) + sizeof(Topology::ChannelBoardConn)*MAX_CHANNELS)) {}
SerializedMessage build_topology(const std::vector<flatbuffers::Offset<Topology::NeighbourBlob>>& topology);
flatbuffers::Offset<Topology::NeighbourBlob> build_neighbour_info(uint16_t board_id, const std::vector<Topology::ChannelBoardConn>& connections);
SerializedMessage build_topology(const std::unordered_map<uint16_t, std::vector<Topology::ChannelBoardConn>>& topology_map);
Topology::ChannelBoardConn build_connections(uint8_t channel, uint16_t board_id);
private:
flatbuffers::Offset<Topology::NeighbourBlob> build_neighbour_info(uint16_t board_id, const std::vector<Topology::ChannelBoardConn>& connections);
flatbuffers::FlatBufferBuilder builder_;
};
}

View File

@@ -204,18 +204,90 @@ esp_err_t TopologyManager::get_curr_topology(std::unordered_map<uint16_t, std::v
return ESP_OK;
}
// esp_err_t TopologyManager::write_nvs_topology(){
// if (!ready){
// return ESP_ERR_INVALID_STATE;
// }
// return ESP_OK;
// }
esp_err_t TopologyManager::write_nvs_topology(){
if (!ready){
return ESP_ERR_INVALID_STATE;
}
// esp_err_t TopologyManager::get_nvs_topology(struct Topology& topology){
// if (!ready){
// return ESP_ERR_INVALID_STATE;
// }
// return ESP_OK;
// }
Flatbuffers::SerializedMessage m = builder.build_topology(topology);
ESP_LOGI(TOPOLOGY_DEBUG_TAG, "Saving topology blob...");
esp_err_t res = nvs_set_u32(handle, MOVEMENTS_NVS_TOPOLOGY_DATA_SIZE_KEY, static_cast<uint32_t>(m.size));
res = nvs_commit(handle);
if (res != ESP_OK) {
ESP_LOGE(TOPOLOGY_DEBUG_TAG, "Failed to commit data size");
return res;
}
res = nvs_set_blob(handle, MOVEMENTS_NVS_TOPOLOGY_KEY, m.data, m.size);
if (res != ESP_OK){
ESP_LOGE(TOPOLOGY_DEBUG_TAG, "Failed to write to nvs");
return res;
}
res = nvs_commit(handle);
if (res != ESP_OK) {
ESP_LOGE(TOPOLOGY_DEBUG_TAG, "Failed to commit topology");
return res;
}
return ESP_OK;
}
esp_err_t TopologyManager::get_nvs_topology(std::unordered_map<uint16_t, std::vector<std::pair<uint8_t, uint16_t>>>& topology){
if (!ready) {
return ESP_ERR_INVALID_STATE;
}
size_t size = 0;
esp_err_t res = nvs_get_u32(handle,MOVEMENTS_NVS_TOPOLOGY_DATA_SIZE_KEY, reinterpret_cast<uint32_t*>(&size));
if (res != ESP_OK) {
ESP_LOGE(TOPOLOGY_DEBUG_TAG, "Failed to read data size");
return res;
}
std::vector<uint8_t> buffer(size);
res = nvs_get_blob(handle, MOVEMENTS_NVS_TOPOLOGY_KEY, buffer.data(), &size);
if (res != ESP_OK) {
ESP_LOGE(TOPOLOGY_DEBUG_TAG, "Failed to read blob");
return res;
}
// Verify the FlatBuffer
flatbuffers::Verifier verifier(buffer.data(), buffer.size());
if (!Topology::VerifyTopologyInfoBuffer(verifier)) {
ESP_LOGE(TOPOLOGY_DEBUG_TAG, "FlatBuffer verification failed");
return ESP_ERR_INVALID_ARG;
}
// Parse root
const Topology::TopologyInfo* topo = Topology::GetTopologyInfo(buffer.data());
topology.clear();
// Replace neighbours() with your actual accessor name
auto neighbours = topo->boards();
for (const auto* nb : *neighbours) {
uint16_t board_id = nb->curr_board_id();
std::vector<std::pair<uint8_t, uint16_t>> connections;
connections.reserve(nb->neighbour_connections()->size());
for (const auto* conn : *nb->neighbour_connections()) {
connections.emplace_back(conn->channel(), conn->board_id());
}
topology.emplace(board_id, std::move(connections));
}
return ESP_OK;
}
#endif //MOVEMENTS

View File

@@ -6,6 +6,7 @@
#define MOVEMENTS_NVS_NAMESPACE "movements"
#define MOVEMENTS_NVS_KEY "key"
#define MOVEMENTS_NVS_TOPOLOGY_KEY "topology"
#define MOVEMENTS_NVS_TOPOLOGY_DATA_SIZE_KEY "data_size"
#define MOVEMENTS_DEBUG_TAG "movements"
class MovementManager {

View File

@@ -5,9 +5,9 @@
#include <unordered_map>
#include <unordered_set>
// move these to constants header file?
#include "RMTManager.h"
#include "DataLinkManager.h"
#include "constants/rmt.h"
#include "constants/datalink.h"
#include "Frames.h"
#include "TopologyBuilder.h"
#include <vector>
@@ -26,7 +26,7 @@ class TopologyManager {
esp_err_t verify_topology();
esp_err_t get_curr_topology(std::unordered_map<uint16_t, std::vector<std::pair<uint8_t, uint16_t>>>& topology);
esp_err_t write_nvs_topology();
esp_err_t get_nvs_topology(std::unordered_map<uint16_t, std::vector<Topology::ChannelBoardConn>>& topology);
esp_err_t get_nvs_topology(std::unordered_map<uint16_t, std::vector<std::pair<uint8_t, uint16_t>>>& topology);
private:
std::unordered_map<uint16_t, std::vector<Topology::ChannelBoardConn>> topology;

View File

@@ -42,6 +42,10 @@ To run the sample code, add the compiler variable `PP_MOVE=1` when compiling.
You can use the `SRC_BOARD` compiler variable to set a custom board id.
The sample topology used to test:
![Sample Topology Used for Testing](images/sample_topology.png)
# cat
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣴⣿⣿⡷⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

View File

@@ -44,7 +44,6 @@ extern "C" [[noreturn]] void app_main(void) {
}
ESP_ERROR_CHECK(ret);
esp_netif_init();
esp_event_loop_create_default();
printf("finished esp init\n");
@@ -140,10 +139,59 @@ extern "C" [[noreturn]] void app_main(void) {
if (res != ESP_OK){
ESP_LOGE(MOVEMENT_DEBUG_TAG, "Topology verification incorrectly failed");
restart();
} else {
ESP_LOGI(MOVEMENT_DEBUG_TAG, "Topology verification passed");
}
res = obj.write_nvs_topology();
if (res == ESP_OK){
ESP_LOGI(MOVEMENT_DEBUG_TAG, "Topology NVS write success");
} else {
ESP_LOGE(MOVEMENT_DEBUG_TAG, "Topology NVS write failed");
restart();
}
std::unordered_map<uint16_t, std::vector<std::pair<uint8_t, uint16_t>>> nvs_topology;
res = obj.get_nvs_topology(nvs_topology);
if (res == ESP_OK){
ESP_LOGI(MOVEMENT_DEBUG_TAG, "Topology NVS read success");
} else {
ESP_LOGE(MOVEMENT_DEBUG_TAG, "Topology NVS read failed");
restart();
}
if (nvs_topology.size() != test_connections.size()){
ESP_LOGE(MOVEMENT_DEBUG_TAG, "Topology NVS size is different");
restart();
}
for (const auto& connections : test_connections){
const auto& test = connections.first;
if (nvs_topology.find(connections.second) == nvs_topology.end()){
ESP_LOGE(MOVEMENT_DEBUG_TAG, "Failed to find board %d in topology", connections.second);
restart();
}
if (test.size() != nvs_topology[connections.second].size()){
ESP_LOGE(MOVEMENT_DEBUG_TAG, "Board %d connections are different in topology", connections.second);
restart();
}
}
ESP_LOGI(MOVEMENT_DEBUG_TAG, "Topology NVS R/W success! Got back the same topology");
ESP_LOGI(MOVEMENT_DEBUG_TAG, "Topology NVS got:");
for (const auto& [key, connections] : nvs_topology){
for (const auto& c : connections){
ESP_LOGI(MOVEMENT_DEBUG_TAG, "Board %d -> board %d on channel %d", key, c.second, c.first);
}
}
//test removing a board from topology
uint16_t board_id_to_remove = 2;