diff --git a/src/cmd.cpp b/src/cmd.cpp index b16f3d368b11b6c0956818e53a96eb31305091cc..c28f9f0d783c97700bfebd7940b75981bac2f299 100644 --- a/src/cmd.cpp +++ b/src/cmd.cpp @@ -91,6 +91,8 @@ CMDstatus CMD::command(string line, TermOutput& termout, string& cmdname, Server req_ret = Mread(argc,argv,termout,sd); } else if(cmd == MWRITE) { req_ret = Mwrite(argc,argv,termout,sd); + } else if(cmd == RELOAD) { + req_ret = Reload(argc,argv,termout,sd); /* * ^^^^^ parse user command ^^^^^ * @@ -374,6 +376,44 @@ CMDstatus CMD::Mwrite(int argc, char* argv[], TermOutput& termout, Serverdat *sd return ret; } +CMDstatus CMD::Reload(int argc, char* argv[], TermOutput& termout, Serverdat *sd) +{ + CMDstatus ret = {CMD_STATUS_ERROR,0,0}; + + po::options_description generic("Reloads REGMAPs"); + generic.add_options() + ("help,h", "shows this help text") + ("doit", "Preforms REGMAP reload") + ; + + po::options_description cmdline_options; + po::options_description visible("Allowed options"); + cmdline_options.add(generic); + visible.add(generic); + + try { + po::positional_options_description p; + po::variables_map vm; + po::store(po::command_line_parser(argc,argv). + options(cmdline_options).positional(p).run(), vm); + po::notify(vm); + + if (vm.count("help")) { + termout.strout << "usage: " << RELOAD << " [options]" << endl + << "Options: " << generic << endl; + return {CMD_STATUS_OK,0,0}; + } else if (vm.count("doit")) { + cerr << "RELOAD invoked from user" << endl; + termout.strout << "Reload REGMAP now!" << endl; + ret.status=CMD_REQUEST_SIGHUP; + } else throw runtime_error("missing argument(s)"); + } catch(po::error& e) { + termout.strerr << e.what() << endl; + } catch(std::exception& e) { + termout.strerr << e.what() << endl; + } + return ret; +} /*********************** * End user commands * diff --git a/src/cmd.h b/src/cmd.h index 2b06b0d9c12e743ded6521265a86c177ab7cf761..731968d9861f9190b73f5c4ca88de4f1a1b52686 100644 --- a/src/cmd.h +++ b/src/cmd.h @@ -31,6 +31,7 @@ #define CMD_EMPTY -2 #define CMD_REQUEST_BINARY 2 #define CMD_REQUEST_QUIT 3 +#define CMD_REQUEST_SIGHUP 4 typedef struct { int status; @@ -52,6 +53,7 @@ private: const std::string INFO="ls"; const std::string MREAD="read"; const std::string MWRITE="mwrite"; + const std::string RELOAD="reload"; std::vector<std::string> supported_cmds; @@ -62,6 +64,7 @@ private: CMDstatus Info(int argc, char* argv[], TermOutput& termout, Serverdat *sd); CMDstatus Mread(int argc, char* argv[], TermOutput& termout, Serverdat *sd); CMDstatus Mwrite(int argc, char* argv[], TermOutput& termout, Serverdat *sd); + CMDstatus Reload(int argc, char* argv[], TermOutput& termout, Serverdat *sd); public: CMD() { @@ -71,6 +74,7 @@ private: supported_cmds.push_back(INFO); supported_cmds.push_back(MREAD); supported_cmds.push_back(MWRITE); + supported_cmds.push_back(RELOAD); } ~CMD() {}; diff --git a/src/common.cpp b/src/common.cpp index 16fbf6e7afb333a2255468af31f151b83c1da6ed..1f70b1586c76358bf84497b7ad590ab7f4931858 100644 --- a/src/common.cpp +++ b/src/common.cpp @@ -87,25 +87,36 @@ std::vector<int> Common::get_nodes(void) return nodes; } -bool Common::get_system_info(TermOutput& termout, std::vector<int> nodes, const string what) +RegisterMap * Common::get_RegisterMap(TermOutput& termout, int node) { - bool retval = false; - uint retcnt = 0; + auto n = select_node(node); + return n->get_RegisterMap(termout.strout); +} + +bool Common::monitor(TermOutput& termout) +{ + bool retval=false; + uint retcnt=0; + std::vector<int> nodes = get_nodes(); + for(uint idx=0;idx<nodes.size();idx++) { + auto node = select_node(nodes[idx]); - for(auto n : nodes) { - auto node = select_node(n); print_node_id(termout.strout,node); - if(node->get_system_info(termout.strout,what)) retcnt++; + if(idx > 0) termout.strout << ","; + termout.strout << "["; + try { + if(node->composite_call(termout.strout, "system")) { + retcnt++; + } + } catch(std::exception& e) { + termout.strerr << e.what() << endl; + } + termout.strout << "]"; } retval = (retcnt==nodes.size()); return retval; } -RegisterMap * Common::get_RegisterMap(TermOutput& termout, int node) -{ - auto n = select_node(node); - return n->get_RegisterMap(termout.strout); -} bool Common::read(TermOutput& termout, const string addr, const uint offs, const int len) { @@ -131,7 +142,7 @@ bool Common::read(TermOutput& termout, const string addr, const uint offs, const retcnt++; } } else if(type == "dev") { - if(node->get_system_info(termout.strout, peripheral)) { + if(node->composite_call(termout.strout, peripheral)) { retcnt++; } else { termout.strerr << "no such peripheral: " << peripheral; diff --git a/src/common.h b/src/common.h index 43665224f79cc76e2ceb4360ff75ac007b10ef85..46214968b1d7f4a59f7978afea480903db559127 100644 --- a/src/common.h +++ b/src/common.h @@ -48,8 +48,7 @@ public: ~Common(); std::vector<int> get_nodes(void); - - bool get_system_info(TermOutput& termout, std::vector<int> nodes, const std::string what); + bool monitor(TermOutput& termout); bool mwrite(TermOutput& termout, const std::string addr, const uint offs, const std::vector<int>& data); diff --git a/src/node.cpp b/src/node.cpp index 57760d737145508d041fbc60d5a569a2c2d071aa..4764f896193b2d24cbff5d0414468c013e226212 100644 --- a/src/node.cpp +++ b/src/node.cpp @@ -63,19 +63,21 @@ Node::~Node() delete periph_system; } -bool Node::get_system_info(ostringstream& strs,const string what) { - if(what == "system") { +bool Node::composite_call(ostringstream& strs,const string peripheral) { + if(peripheral == "system") { return periph_system->read_system_info(strs); - } else if(what == "name") { + } else if(peripheral == "name") { strs << "read_design_name:" << periph_system->read_design_name(); return true; - } else if(what == "stamps") { + } else if(peripheral == "stamps") { return periph_system->read_stamps(strs); - } else if(what == "note") { + } else if(peripheral == "note") { strs << "read_design_note:" << periph_system->read_design_note(); return true; - } else if(what == "sensors") { + } else if(peripheral == "sensors") { return periph_system->read_unb_sensors(strs,LocalNr); + } else if(peripheral == "status") { + return periph_system->read_unb_status(strs); } else return false; } diff --git a/src/node.h b/src/node.h index e972fdc4342bd83485a573210c86254c4aa46c5a..78f3e16dae85e079fde21cf50d955e17366620fb 100644 --- a/src/node.h +++ b/src/node.h @@ -82,7 +82,7 @@ class Node { const uint GetNr() { return LocalNr; } const std::string GetType() { return Type; } - bool get_system_info(std::ostringstream& strs,const std::string what); + bool composite_call(std::ostringstream& strs, const std::string peripheral); bool mread(std::ostringstream& strs,const std::string addr, const uint offs, std::vector<int>& data, const uint len); bool mwrite(std::ostringstream& strs,const std::string addr, const uint offs, diff --git a/src/periph/system.cpp b/src/periph/system.cpp index 720ebb2909fe2662b74ec8b5496a36f26d008529..34703d2ccf4a200f6cc397ac77cc23b222b06d66 100644 --- a/src/periph/system.cpp +++ b/src/periph/system.cpp @@ -44,6 +44,7 @@ Periph_system::Periph_system(UNBos &commdev, { my_expected_design_name = expected_design_name; my_expected_firmware_version = expected_firmware_version; + my_current_status = "offline"; registerMap = new RegisterMap(read_reg_map()); @@ -53,8 +54,13 @@ Periph_system::Periph_system(UNBos &commdev, registerMap->add_register("dev/stamps", 0, 0, 0xffffffff, 0, "RO"); registerMap->add_register("dev/note", 0, 0, 0xffffffff, 0, "RO"); registerMap->add_register("dev/sensors", 0, 0, 0xffffffff, 0, "RO"); + registerMap->add_register("dev/status", 0, 0, 0xffffffff, 0, "RO"); - std::string design_name = read_design_name(); + try { + std::string design_name = read_design_name(); + } catch(std::exception& e) { + cerr << "Periph_system::Periph_system:read_design_name(): " << e.what() << endl; + } } bool Periph_system::Read(const string addr_str, const uint32_t offset, const uint32_t nvalues, uint32_t *data_ptr) @@ -93,6 +99,12 @@ bool Periph_system::Write(const string addr_str, const uint32_t offset, const ui return unbos.writeRegister(addr,nvalues,data_ptr); } +bool Periph_system::read_unb_status(ostringstream& strs) +{ + strs << my_current_status << endl; + return true; +} + /* """Peripheral system_info Register map: @@ -125,6 +137,7 @@ bool Periph_system::read_system_info(ostringstream& strs) sprintf(str,"Hardware version = %d\n",hardware_version); strs << str; if(design_name == my_expected_design_name && firmware_version == my_expected_firmware_version) { + my_current_status = "online"; retval = true; } else { retval = false; @@ -136,6 +149,9 @@ bool Periph_system::read_system_info(ostringstream& strs) syslog(LOG_WARNING,"Node configuration mismatch!! (read_design_name/version=%s/%d, expected=%s/%d)\n", design_name.c_str(), firmware_version, my_expected_design_name.c_str(), my_expected_firmware_version); + + my_current_status = "offline"; + registerMap->setAllPermission_NA(); } return retval; } @@ -273,7 +289,9 @@ RegisterMap Periph_system::read_reg_map(void) uint32_t *data = new uint32_t[nvalues * sizeof(uint32_t)]; if(!unbos.readRegister(addr, nvalues, data)) { delete[] data; - throw runtime_error("unbos.Read()"); + //throw runtime_error("unbos.Read()"); + cerr << "unbos.readRegister failed" << endl; + return reg; } for(uint i=0; i < nvalues; i++) { diff --git a/src/periph/system.h b/src/periph/system.h index e6561595d19633cb12e2fcc91f44e6a576e61c62..e6affd85d4f6d1476a92b5a210453f97091f231d 100644 --- a/src/periph/system.h +++ b/src/periph/system.h @@ -32,6 +32,7 @@ private: RegisterMap *registerMap; std::string my_expected_design_name; uint my_expected_firmware_version; + std::string my_current_status; bool Read(const string addr_str, const uint32_t offset, const uint32_t nvalues, uint32_t *data_ptr); bool Write(const string addr_str, const uint32_t offset, const uint32_t nvalues, uint32_t *data_ptr); @@ -47,6 +48,7 @@ public: const std::vector<int>& data); std::string read_design_name(void); std::string read_design_note(void); + bool read_unb_status(std::ostringstream& strs); bool read_stamps(ostringstream& strs); bool read_unb_sensor(uint32_t *sensor, const uint nodeNr); bool read_unb_sensors(ostringstream& strs, const uint nodeId); diff --git a/src/registers.cpp b/src/registers.cpp index f31d8b91ba0954e611d1c23db3d2addb96a1a4f2..98917c9362831a8088be789e321c928b2f9ce41c 100644 --- a/src/registers.cpp +++ b/src/registers.cpp @@ -28,6 +28,7 @@ void RegisterMap::add_register(const std::string name, const uint32_t base, const uint32_t span, const uint32_t mask, const uint32_t shift, const std::string access) { + cout << "RegisterMap::add_register: " << name << endl; register_info r={base, span, mask, shift, access}; reg.insert(reg.end(), std::pair<std::string, register_info>(name, r)); } @@ -119,3 +120,11 @@ bool RegisterMap::getWritePermission(const std::string name) } return false; } + +void RegisterMap::setAllPermission_NA(void) +{ + cerr << "RegisterMap::setAllPermission_NA()" << endl; + for(auto &m : reg) { + m.second.access = "NA"; + } +} diff --git a/src/registers.h b/src/registers.h index 3bec6427bbaa20454d817f2b3a26364bce521fab..739d62b943cb9153d0dca5c89360d6e5490a50bb 100644 --- a/src/registers.h +++ b/src/registers.h @@ -58,6 +58,8 @@ class RegisterMap { bool getReadPermission(const std::string name); bool getWritePermission(const std::string name); void setPermission_NA(const std::string name) { reg[name].access = "NA"; } + void setAllPermission_NA(void); + std::vector<std::string> getRegnames(std::string prefix); std::vector<std::string> getRegnames_full(std::string prefix); diff --git a/src/sdpunb.cpp b/src/sdpunb.cpp index 96cce9d8b8f53fc8b4a64a6ad34b149f7b91a3bc..166b5ef2438957918eff96e4b51e7648e9317934 100644 --- a/src/sdpunb.cpp +++ b/src/sdpunb.cpp @@ -73,16 +73,29 @@ void monitor(void) CMDstatus cmdstatus = {CMD_STATUS_OK, 0,0}; CMDstatus cmdstatusnew = cmdstatus; TermOutput termout; +#define c_NOF_RETRIES_MONITOR 3 + int retries = c_NOF_RETRIES_MONITOR; while(ServerRunning) { - usleep(1000000); - while(!SD.monitor_mutex.try_lock()) { cerr << "mutex not ready\n"; usleep(100000); } - //cmdstatusnew = Cmd.command("read /unb0/pn[0:2]/dev/system", termout, cmdname, &SD); - cmdstatusnew = Cmd.command("read /unb0/pn[0]/dev/system", termout, cmdname, &SD); - SD.monitor_mutex.unlock(); - if(cmdstatusnew.status != CMD_EMPTY) cmdstatus = cmdstatusnew; - cout << "Monitor thread: " << print_termout(termout) << endl; - termout.clear(); + usleep(1000000); + + while(!SD.monitor_mutex.try_lock()) { cerr << "mutex not ready\n"; usleep(100000); } + if(!SD.unb->monitor(termout)) { + retries--; + cerr << "Retrying " << retries << endl; + } else { + retries = c_NOF_RETRIES_MONITOR; + } + SD.monitor_mutex.unlock(); + + if(cmdstatusnew.status != CMD_EMPTY) cmdstatus = cmdstatusnew; + cout << "Monitor thread: " << print_termout(termout) << endl; + termout.clear(); + + if(retries <= 0) { + //cerr << "Re-initializing, Read register maps again!" << endl; + //raise(SIGHUP) + } } } @@ -129,6 +142,8 @@ void control_server(TCPSSocket *sock, const int clientId, std::atomic<size_t> *n termout.clear(); if(cmdstatus.status == CMD_REQUEST_QUIT) { quit = true; + } else if(cmdstatus.status == CMD_REQUEST_SIGHUP) { + raise(SIGHUP); } } } diff --git a/src/uniboard.conf b/src/uniboard.conf index e390adb2d0da94a68adfe158cbecfb3b24404a9d..63550ed7a9194b8d5a6f7da9bb28f7d16efc88d4 100644 --- a/src/uniboard.conf +++ b/src/uniboard.conf @@ -4,7 +4,7 @@ # NODE config: # gn ipaddr expected firmware expected version node 0 10.99.1.1 unb2b_minimal 2 -#node 1 10.99.1.2 unb2b_minimal 2 +node 1 10.99.1.2 unb2b_minimal 2 #node 2 10.99.1.3 unb2b_minimal 2 #node 3 10.99.1.4 unb2b_minimal 2