mirror of
https://github.com/BotChain-Robots/firmware.git
synced 2026-07-08 09:37:21 +02:00
able to write and read from nvs; completed topology test main
This commit is contained in:
@@ -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){
|
||||
|
||||
@@ -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_;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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:
|
||||
|
||||

|
||||
|
||||
# cat
|
||||
|
||||
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣴⣿⣿⡷⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
||||
|
||||
BIN
main/images/sample_topology.png
Normal file
BIN
main/images/sample_topology.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 65 KiB |
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user