Commit 22b5eaf1 authored by Leon Hiemstra's avatar Leon Hiemstra

More robust error handling, added status, reload

parent 2baed43a
......@@ -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 *
......
......@@ -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() {};
......
......@@ -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;
......
......@@ -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);
......
......@@ -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;
}
......
......@@ -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,
......
......@@ -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++) {
......
......@@ -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);
......
......@@ -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";
}
}
......@@ -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);
......
......@@ -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);
}
}
}
......
......@@ -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
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment