Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: NaturalTinyShell_ice libmDot-12Sept mbed-rtos mbed
Fork of ICE by
src/CommandParser/cmd.cpp
- Committer:
- jmarkel44
- Date:
- 2016-09-27
- Revision:
- 133:c871de2d2b90
- Parent:
- 132:45821e189dd0
- Child:
- 148:ee3cbaafe355
- Child:
- 152:c03ebcda54ef
File content as of revision 133:c871de2d2b90:
/* * =============================================================== * Natural Tiny Shell (NT-Shell) Application example. * Version 0.0.6 * =============================================================== * Copyright (c) 2010-2011 Shinichiro Nakamura * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * =============================================================== */ #include "cmd.h" #include <mbed.h> #include <utility> #include "ntshell.h" #include "ntopt.h" #include "global.h" #include "ConfigurationHandler.h" #include "ModbusMasterApi.h" #include "LogLocalApi.h" #include "LoggerApi.h" #include "OutputTask.h" #include "mDot.h" #include "rtos.h" #include "rtc.h" Serial serial(USBTX, USBRX); ntshell_t ntshell; extern mDot *GLOBAL_mdot; typedef struct { char *command; // command (from shell) char *description; // descrption void (*func)(int argc, char **argv); // callback function } command_table_t; // see cmd.h const command_table_t cmdlist[] = { {"?", "help command", cmd_help }, //{"create-control", "create a control", cmd_create }, {"cat", "cat a file", cmd_cat }, {"cif", "create a test input file", cmd_cif }, {"cmf", "create a manual control file", cmd_cmf }, {"cof", "create a test output file", cmd_cof }, {"create-manual", "create a manual control", cmd_createManual }, {"create-setpoint", "create a setpoint control", cmd_createSetpoint }, {"create-timer", "create a timer control", cmd_createTimer }, {"destroy-control", "destroy a control", cmd_destroy }, {"heap", "show heap statistics", cmd_heap }, {"help", "help command", cmd_help }, {"log-level", "get/set mDot log level", cmd_logLevel }, {"ls", "list user files", cmd_ls }, {"modify-control", "modify a control", cmd_modify }, {"modmap", "dump modbus register map", cmd_modmap }, {"reset", "reset the controller", cmd_reset }, {"reset-stats", "reset current mDot statistics", cmd_resetStats }, {"rm", "remove a user file", cmd_rm }, {"rssi-stats", "get current rssi stats", cmd_rssiStats }, {"set-time", "set current time", cmd_settime }, {"show-controls", "display active controls", cmd_ShowControls }, {"show-outputs", "dump outputs", cmd_outputs }, {"snr-stats", "get current SNR stats", cmd_snrStats }, {"stack", "get thread stack usage stats", cmd_stack }, {"stats", "get current mDot statistics", cmd_stats }, {"time", "get current time", cmd_time }, {"sout", "set output", cmd_sout }, {"simin", "simulate input", cmd_simin }, {"deep", "dump EEP", cmd_deep }, {"peep", "push EEP", cmd_peep }, {"ins-log", "insert log event", cmd_inslog }, {NULL, NULL, NULL} }; int func_read(char *buf, int cnt); int func_write(const char *buf, int cnt); int func_cb_ntshell(const char *text); void func_cb_ntopt(int argc, char **argv); /** * Serial read function. */ int func_read(char *buf, int cnt) { for (int i = 0; i < cnt; i++) { buf[i] = serial.getc(); } return 0; } /** * Serial write function. */ int func_write(const char *buf, int cnt) { for (int i = 0; i < cnt; i++) { serial.putc(buf[i]); } return 0; } /** * Callback function for ntshell module. */ int func_cb_ntshell(const char *text) { return ntopt_parse(text, func_cb_ntopt); } /** * Callback function for ntopt module. */ void func_cb_ntopt(int argc, char **argv) { if (argc == 0) { return; } int execnt = 0; const command_table_t *p = &cmdlist[0]; while (p->command != NULL) { if (strcmp(argv[0], p->command) == 0) { p->func(argc, argv); execnt++; } p++; } if (execnt == 0) { printf("Command not found.\r\n"); } wait_ms(250); } /************************* callback functions *******************************/ void cmd_cat(int argc, char **argv) { if ( argc != 2 ) { printf("\rusage: cat <filename>\n"); return; } mDot::mdot_file file = GLOBAL_mdot->openUserFile(argv[1], mDot::FM_RDONLY); if ( file.fd < 0 ) { printf("\rFailed to open %s\n", argv[1]); return; } char *data_buf = (char*) malloc(file.size); bool rc = GLOBAL_mdot->readUserFile(file, data_buf, file.size); if ( rc != true ) { printf("\rFailed to read %s\n", argv[1]); goto cleanup; } printf("%s\n", data_buf); cleanup: free(data_buf); GLOBAL_mdot->closeUserFile(file); } /***************************************************************************** * Function: cmd_help * Description: displays the list of commands available * * @param argc (not used) * @param argv (not used) * @return none *****************************************************************************/ void cmd_help(int argc, char **argv) { UNUSED(argc); UNUSED(argv); const command_table_t *tblPtr = cmdlist; while (tblPtr->command) { printf("\r%-32s:\t%s\n", tblPtr->command, tblPtr->description); tblPtr++; } printf("\r\n"); } /***************************************************************************** * Function: cmd_logLevel * Description: get or set the current log-level * * @param argc (not used) * @param argv (not used) * @return none *****************************************************************************/ void cmd_logLevel(int argc, char **argv) { uint8_t logLevel = 0; const char *mapper[] = { "NONE", "FATAL", "ERROR", "WARNING", "INFO", "DEBUG", "TRACE" }; if ( argc == 1 ) { printf("\r current log-level set to %s\r\n", mapper[GLOBAL_mdot->getLogLevel()]); goto usage; } if ( argc != 2 ) { usage: printf("\rusage: log-level [0-6]\n"); printf("\r 0 = NONE\n"); printf("\r 1 = FATAL\n"); printf("\r 2 = ERROR\n"); printf("\r 3 = WARNING\n"); printf("\r 4 = INFO\n"); printf("\r 5 = DEBUG\n"); printf("\r 6 = TRACE\r\n"); return; } logLevel = atoi(argv[1]); if ( logLevel > 6 ) goto usage; // reassign the log level printf("...setting log-level to %s\r\n", mapper[logLevel]); GLOBAL_mdot->setLogLevel(logLevel); printf("\r\n"); } /***************************************************************************** * Function: cmd_ls * Description: list the user files on flash * * @param argc (not used) * @param argv (not used) * @return none *****************************************************************************/ void cmd_ls(int argc, char **argv) { UNUSED(argc); UNUSED(argv); vector<mDot::mdot_file> userFiles; userFiles = GLOBAL_mdot->listUserFiles(); vector<mDot::mdot_file>::iterator pos; for ( pos = userFiles.begin(); pos != userFiles.end(); ++pos ) { printf("\r %-33s %d\n", pos->name, pos->size); } printf("\r\n"); } /***************************************************************************** * Function: cmd_ShowControls * Description: show active controls * * @param argc (not used) * @param argv (not used) * @return none *****************************************************************************/ void cmd_ShowControls(int argc, char **argv) { UNUSED(argc); UNUSED(argv); ConfigurationHandler_showControls(); printf("\r\n"); } /***************************************************************************** * Function: cmd_reset * Description: reset the cpu * * @param argc (not used) * @param argv (not used) * @return none *****************************************************************************/ void cmd_reset(int argc, char **argv) { UNUSED(argc); UNUSED(argv); GLOBAL_mdot->resetCpu(); } /***************************************************************************** * Function: cmd_rm * Description: removes a user file from flash * * @param argc-> number of args * @param argv-> filename * @return none *****************************************************************************/ void cmd_rm(int argc, char **argv) { UNUSED(argc); UNUSED(argv); if ( argc != 2 ) { printf("\rusage: rm <filename>\n"); return; } if ( strcmp(argv[1], "*") == 0 ) { vector<mDot::mdot_file> userFiles; userFiles = GLOBAL_mdot->listUserFiles(); vector<mDot::mdot_file>::iterator pos; for ( pos = userFiles.begin(); pos != userFiles.end(); ++pos ) { GLOBAL_mdot->deleteUserFile(pos->name); } } else { GLOBAL_mdot->deleteUserFile(argv[1]); } } /***************************************************************************** * Function: cmd_create * Description: create a control * * @param argc-> number of args * @param argv-> control name, control type * @return none *****************************************************************************/ void cmd_create(int argc, char **argv) { if ( argc != 3 ) { printf("\r\nusage: create [controlName] [controlType]\n"); printf("\rcontrolType-> 0=timer, 1=PID, 2=setpoint, 3=composite, 4=manual\r\n"); return; } // send a message to the configuration handler to create the control Message_t *msg = MailBox.alloc(); memset(msg, 0, sizeof(Message_t)); msg->action = ACTION_CREATE; msg->control = (Control_t) atoi(argv[2]); strncpy(msg->controlFile, argv[1], sizeof(msg->controlFile)-1); printf("%s: Sending a create request for control %s type = %u\r\n", __func__, msg->controlFile, msg->control); MailBox.put(msg); printf("\r\n"); return; } /***************************************************************************** * Function: cmd_destroy * Description: reset the cpu * * @param argc-> number of arguments * @param argv-> control name, control type * @return none *****************************************************************************/ void cmd_destroy(int argc, char **argv) { if ( argc != 3 ) { printf("\r\nusage: destroy [controlName] [controlType]\n"); printf("\rcontrolType-> 0=timer, 1=PID, 2=setpoint, 3=composite, 4=manual\r\n"); return; } // send a message to the configuration handler to destroy the control Message_t *msg = MailBox.alloc(); memset(msg, 0, sizeof(Message_t)); msg->action = ACTION_DESTROY; msg->control = (Control_t) atoi(argv[2]); strncpy(msg->controlFile, argv[1], sizeof(msg->controlFile)-1); printf("%s: Sending a destroy request for control %s\r\n", __func__, msg->controlFile); MailBox.put(msg); printf("\r\n"); return; } /***************************************************************************** * Function: cmd_createSetpoint * Description: create control file * * @param argc-> number of args * @param argv-> filename * @return none *****************************************************************************/ void cmd_createSetpoint(int argc, char **argv) { if ( argc != 7 ) { printf("\rusage: create-setpoint <filename> <id> <input> <output> <direction> <tolerance>\n"); printf("\rexample: create-setpoint control_sp_1.json SPC_01 i_tra01 o_rly1 1 5\r\n"); return; } if ( strncmp(argv[1], CONTROL_SP_STR, strlen(CONTROL_SP_STR)) != 0 ) { printf("\rFilename must be prefixed with control_sp_*\n"); return; } char data_buf[1024]; snprintf(data_buf, sizeof(data_buf), "{ " "\"id\": \"%s\", " "\"priority\": \"800\"," "\"input\": \"%s\", " "\"output\": \"%s\", " "\"setpoint\": \"100\"," "\"prodfact\": \"100\"," "\"actingDir\": \"%s\", " "\"halert\": \"115\"," "\"lalert\": \"85\", " "\"hfs\": \"130\"," "\"lfs\": \"70\", " "\"tol\": \"%s\" }", argv[2], argv[3], argv[4], argv[5], argv[6] ); bool status = GLOBAL_mdot->saveUserFile(argv[1], (void *)data_buf, 1024); if( status != true ) { logInfo("(%d)save file failed, status=%d", __LINE__, status); return; } // send a message to the configuration handler to create the control Message_t *msg = MailBox.alloc(); memset(msg, 0, sizeof(Message_t)); msg->action = ACTION_CREATE; msg->control = CONTROL_SETPOINT; strncpy(msg->controlFile, argv[1], sizeof(msg->controlFile)-1); printf("%s: Sending a create request for control %s type = %u\r\n", __func__, msg->controlFile, msg->control); MailBox.put(msg); printf("\r\n"); return; } /***************************************************************************** * Function: cmd_createTimer * Description: create control file * * @param argc-> number of args * @param argv-> filename * @return none *****************************************************************************/ void cmd_createTimer(int argc, char **argv) { if ( argc != 6 ) { printf("\rusage: create-timer <filename> <id> <output> <priority> <duration>\n"); printf("\rexample: create-timer control_tm_1.json timer-1 o_rly1 750 60\n"); printf("\r <startTime> is epoch time\n"); printf("\r <duration> is in seconds\r\n"); return; } if ( strncmp(argv[1], CONTROL_TM_STR, strlen(CONTROL_TM_STR)) != 0 ) { printf("\rFilename must be prefixed with control_tm_*\n"); return; } char time_buf[32]; sprintf(time_buf, "%lu", time(NULL)+5); char data_buf[1024]; snprintf(data_buf, sizeof(data_buf), "{ " "\"id\": \"%s\", " "\"output\": \"%s\", " "\"priority\": \"%s\", " "\"starttime\": \"%s\", " "\"duration\": \"%s\", ", argv[2], argv[3], argv[4], time_buf, argv[5] ); bool status = GLOBAL_mdot->saveUserFile(argv[1], (void *)data_buf, 1024); if( status != true ) { logInfo("(%d)save file failed, status=%d", __LINE__, status); return; } // send a message to the configuration handler to create the control Message_t *msg = MailBox.alloc(); memset(msg, 0, sizeof(Message_t)); msg->action = ACTION_CREATE; msg->control = CONTROL_TIMER; strncpy(msg->controlFile, argv[1], sizeof(msg->controlFile)-1); printf("%s: Sending a create request for control %s type = %u\r\n", __func__, msg->controlFile, msg->control); MailBox.put(msg); printf("\r\n"); return; } /***************************************************************************** * Function: cmd_createManual * Description: create a manual control * * @param argc-> number of args * @param argv-> filename * @return none *****************************************************************************/ void cmd_createManual(int argc, char **argv) { if ( argc != 5 ) { printf("\rusage: create-manual <filename> <id> <output> <state>\n"); printf("\rexample: create-manual control_mn_1.json man-1 o_rly1 1\r\n"); return; } char data_buf[1024]; snprintf(data_buf, sizeof(data_buf), "{ " "\"id\": \"%s\", " "\"output\": \"%s\", " "\"type\": \"1\", " "\"priority\": \"100\", " "\"duration\": \"0\", " "\"setpoint\": \"0\", " "\"state\": \"%d\", " "\"percent\": \"100\" }", argv[2], argv[3], atoi(argv[4]) ); bool status = GLOBAL_mdot->saveUserFile(argv[1], (void *)data_buf, 1024); if( status != true ) { logInfo("(%d)save file failed, status=%d", __LINE__, status); return; } // send a message to the configuration handler to create the control Message_t *msg = MailBox.alloc(); memset(msg, 0, sizeof(Message_t)); msg->action = ACTION_CREATE; msg->control = CONTROL_MANUAL; strncpy(msg->controlFile, argv[1], sizeof(msg->controlFile)-1); printf("%s: Sending a create request for control %s type = %u\r\n", __func__, msg->controlFile, msg->control); MailBox.put(msg); printf("\r\n"); return; } /***************************************************************************** * Function: cmd_cif * Description: create input file * * @param argc-> number of args * @param argv-> filename * @return none *****************************************************************************/ void cmd_cif(int argc, char **argv) { if ( argc != 3 ) { printf("\rusage: cif <filename> <input>\r\n"); printf("\rexampe: cif input_i_tra01.json i_tra01\n"); return; } char data_buf[1024]; snprintf(data_buf, sizeof(data_buf), "{ " "\"id\": \"%s\", " "\"name\": \"TRASAR\", " "\"units\": \"PPM\", " "\"min\": \"0\", " "\"max\": \"300\", " "\"node\": \"1\", " "\"reg\": \"9\", " "\"rtype\": \"1\", " "\"type\": \"0\", " "\"size\": \"2\", " "\"order\": \"2\", " "\"rfreq\": \"5\", " "\"fmt\": \"%%.2f\" } ", argv[2] ); bool status = GLOBAL_mdot->saveUserFile(argv[1], (void *)data_buf, 1024); if( status != true ) { logInfo("(%d)save file failed, status=%d", __LINE__, status); } logInfo("Sending Mail To ModbusMasterMailBox, filename=%s", argv[1]); Message_t *mail = ModbusMasterMailBox.alloc(); mail->action = ACTION_READ_FILE; strncpy( mail->controlFile, argv[1], (sizeof(mail->controlFile)-1)); ModbusMasterMailBox.put(mail); } /***************************************************************************** * Function: cmd_cmf * Description: create manual control file * * @param argc-> number of args * @param argv-> filename * @return none *****************************************************************************/ void cmd_cmf(int argc, char **argv) { if ( argc != 2 ) { printf("\rusage: cmf <filename> <relay\r\n"); printf("\rexmaple: cmd control_mn_1.json o_rly1"); return; } char data_buf[1024]; snprintf(data_buf, sizeof(data_buf), "{ " "\"id\": \"%s\", " "\"type\": \"1\", " "\"priority\": \"100\", " "\"duration\": \"30\", " // seconds "\"setpoint\": \"2000.0\", " "\"state\": \"1\", " "\"percent\": \"100\", }", argv[2] ); bool status = GLOBAL_mdot->saveUserFile(argv[1], (void *)data_buf, 1024); if( status != true ) { logInfo("(%d)save file failed, status=%d", __LINE__, status); } } /***************************************************************************** * Function: cmd_cof * Description: create output file * * @param argc-> number of args * @param argv-> filename * @return none *****************************************************************************/ void cmd_cof(int argc, char **argv) { if ( argc != 5 ) { printf("\rusage: cof <filename> <output> <name> <reg>\r\n"); printf("\rexample: cof output_rly1.json o_rly1 Relay1 1\r\n"); return; } char data_buf[1024]; snprintf(data_buf, sizeof(data_buf), "{ " "\"id\": \"%s\", " "\"name\": \"%s\", " "\"units\": \"\", " "\"min\": \"0\", " "\"max\": \"300\", " "\"node\": \"0\", " "\"reg\": \"%s\", " "\"rtype\": \"1\", " "\"type\": \"16\", " "\"size\": \"2\", " "\"order\": \"2\", " "\"fmt\": \"%%.2f\", " "\"rfreq\": \"5\", " "\"toperiod\": \"0\", " "\"scalelo\": \"0\", " "\"scalehi\": \"100\" }", argv[2], argv[3], argv[4]); bool status = GLOBAL_mdot->saveUserFile(argv[1], (void *)data_buf, 1024); if( status != true ) { logInfo("(%d)save file failed, status=%d", __LINE__, status); } // send a message to the modbust master logInfo("Sending mail to ModbusMasterMailBox, filename=%s", argv[1]); Message_t *modbus_mail = ModbusMasterMailBox.alloc(); modbus_mail->action = ACTION_READ_FILE; strncpy( modbus_mail->controlFile, argv[1], (sizeof(modbus_mail->controlFile)-1)); ModbusMasterMailBox.put(modbus_mail); // send a message to the output master logInfo("Sending mail to OutputMaster, filename = %s", argv[1]); OutputControlMsg_t *output_mail = OutputMasterMailBox.alloc(); output_mail->action = ACTION_NEW; strncpy(output_mail->controlFile, argv[1], sizeof(output_mail->controlFile)-1); OutputMasterMailBox.put(output_mail); } /***************************************************************************** * Function: cmd_heap * Description: display heap statistics * * @param argc (not used) * @param argv (not used) * @return none *****************************************************************************/ void cmd_heap(int argc, char **argv) { UNUSED(argc), UNUSED(argv); __heapstats((__heapprt)fprintf,stderr); // print initial free heap size } /***************************************************************************** * Function: cmd_modify * Description: modify an active control * * @param argc (not used) * @param argv (not used) * @return none *****************************************************************************/ void cmd_modify(int argc, char **argv) { // stubbed printf("\rNot yet implemented.\n"); return; } /***************************************************************************** * Function: cmd_stats * Description: display mDot stats * * @param argc (not used) * @param argv (not used) * @return none *****************************************************************************/ void cmd_stats(int argc, char **argv) { UNUSED(argc); UNUSED(argv); mDot::mdot_stats stats = GLOBAL_mdot->getStats(); printf("\r Up: %u\n", stats.Up); printf("\r Down: %u\n", stats.Down); printf("\r Joins: %u\n", stats.Joins); printf("\r JoinFails: %u\n", stats.JoinFails); printf("\r MissedAcks: %u\n", stats.MissedAcks); printf("\r CRCErrors: %u\n", stats.CRCErrors); printf("\r\n"); printf("\r Freq band: %u\n", GLOBAL_mdot->getFrequencyBand()); printf("\r Freq subband: %u\n", GLOBAL_mdot->getFrequencySubBand()); printf("\r Session data rate: %u\n", GLOBAL_mdot->getSessionDataRate()); printf("\r Public Network Mode: %s\n", GLOBAL_mdot->getPublicNetwork() ? "yes" : "no"); printf("\r Application device port: %u\n", GLOBAL_mdot->getAppPort()); printf("\r Class: %s\n", GLOBAL_mdot->getClass().c_str()); printf("\r Max packet length: %u\n", GLOBAL_mdot->getMaxPacketLength()); std::vector<uint8_t> na = GLOBAL_mdot->getNetworkAddress(); std::string str(na.begin(), na.end()); printf("\r Network address: %s\n", str.c_str()); printf("\r Network name: %s\n", GLOBAL_mdot->getNetworkName().c_str()); std::vector<uint8_t> nid = GLOBAL_mdot->getNetworkId(); std::string networkIdStr(nid.begin(), nid.end()); printf("\r Network ID: %s\n", networkIdStr.c_str()); printf("\r Join byter order: %s\n", GLOBAL_mdot->getJoinByteOrder() == 0 ? "LSB" : "MSB"); printf("\r Join retries: %u\n", GLOBAL_mdot->getJoinRetries()); printf("\r Join mode: %u\n", GLOBAL_mdot->getJoinMode()); printf("\r Network join status: %s\n", GLOBAL_mdot->getNetworkJoinStatus() ? "yes" : "no"); printf("\r Link fail count: %u\n", GLOBAL_mdot->getLinkFailCount()); printf("\r Packets Tx'd to gateway: %u\n", GLOBAL_mdot->getUpLinkCounter()); printf("\r Packets Rx'd from gateway: %u\n", GLOBAL_mdot->getDownLinkCounter()); printf("\r AES encryption: %s\n", GLOBAL_mdot->getAesEncryption() ? "enabled" : "disabled"); printf("\r Tx data rate: %u\n", GLOBAL_mdot->getTxDataRate()); printf("\r Datarate Details: %s\n", GLOBAL_mdot->getDateRateDetails(GLOBAL_mdot->getTxDataRate()).c_str()); printf("\r Tx power: %u\n", GLOBAL_mdot->getTxPower()); printf("\r Antenna gain: %u\n", GLOBAL_mdot->getAntennaGain()); printf("\r Min frequency: %u\n", GLOBAL_mdot->getMinFrequency()); printf("\r Max frequency: %u\n", GLOBAL_mdot->getMaxFrequency()); printf("\r CRC enabled: %s\n", GLOBAL_mdot->getCrc() ? "yes" : "no"); printf("\r ACK enabled: %s\n", GLOBAL_mdot->getAck() ? "yes" : "no"); printf("\r\n"); } /***************************************************************************** * Function: cmd_resetStats * Description: resets the mDot stats * * @param argc (not used) * @param argv (not used) * @return none *****************************************************************************/ void cmd_resetStats(int argc, char **argv) { UNUSED(argc); UNUSED(argv); GLOBAL_mdot->resetStats(); } /***************************************************************************** * Function: cmd_rssiStats * Description: displays mDot RSSI statistics * * @param argc (not used) * @param argv (not used) * @return none *****************************************************************************/ void cmd_rssiStats(int argc, char **argv) { UNUSED(argc); UNUSED(argv); mDot::rssi_stats s = GLOBAL_mdot->getRssiStats(); printf("\r Last: %d dB\n", s.last); printf("\r Min: %d dB\n", s.min); printf("\r Max: %d dB\n", s.max); printf("\r Avg: %d dB\n", s.avg); printf("\r\n"); } /***************************************************************************** * Function: cmd_snrStats * Description: displays signal-to-noise ratio stats * * @param argc (not used) * @param argv (not used) * @return none *****************************************************************************/ void cmd_snrStats(int argc, char **argv) { mDot::snr_stats s = GLOBAL_mdot->getSnrStats(); printf("\r Last: %d cB\n", s.last); printf("\r Min: %d cB\n", s.min); printf("\r Max: %d cB\n", s.max); printf("\r Avg: %d cB\n", s.avg); printf("\r\n"); } /***************************************************************************** * Function: cmd_stack * Description: display thread stack statisics * * @param argc (not used) * @param argv (not used) * @return none *****************************************************************************/ void cmd_stack(int argc, char **argv) { vector<pair<string, Thread*> > taskList; const char *mapper[] = { "Inactive", "Ready", "Running", "WaitingDelay", "WaitingInterval", "WaitingOr", "WaitingAnd", "WaitingSempahore", "WaitingMailbox", "WaitingMutex" }; //simply add your task to the list... taskList.push_back(make_pair((string)"AnalyticsLogger", GLOBAL_analyticsLogger_thread)); taskList.push_back(make_pair((string)"BLEHandler", GLOBAL_BLE_thread)); taskList.push_back(make_pair((string)"CloudDataHandler", GLOBAL_CDH_thread)); taskList.push_back(make_pair((string)"ConfigHandler", GLOBAL_configHandler_thread)); taskList.push_back(make_pair((string)"ControlTask", GLOBAL_controlTask_thread)); taskList.push_back(make_pair((string)"ModbusMaster", GLOBAL_modbusMaster_thread)); taskList.push_back(make_pair((string)"OutputTask", GLOBAL_outputTask_thread)); for ( vector<pair<string, Thread*> >::iterator pos = taskList.begin(); pos != taskList.end(); ++ pos) { printf("\r %-32s size/free/used/max = %u/%u/%u/%u\tpri=%-8u state=%-20s\n", pos->first.c_str(), pos->second->stack_size(), pos->second->free_stack(), pos->second->used_stack(), pos->second->max_stack(), pos->second->get_priority(), mapper[pos->second->get_state()]); } printf("\r\n"); } /***************************************************************************** * Function: cmd_modmap * Description: dump modbus register map *****************************************************************************/ void cmd_modmap(int argc, char **argv) { UNUSED(argc); UNUSED(argv); ModbusValue value; std::map<std::string, ModbusRegister>::iterator iter; for (iter = ModbusRegisterMap.begin(); iter != ModbusRegisterMap.end(); ++iter) { ModbusMasterReadRegister( iter->first, &value ); printf("tag=%s, name=%s, units=%s, node=%d, reg=%d, size=%d, order=%d, value=%2.2f\r\n", iter->first.c_str(), iter->second.name.c_str(), iter->second.units.c_str(), iter->second.node, iter->second.reg, iter->second.size, iter->second.order, value.value ); } } /***************************************************************************** * Function: cmd_time * Description: display real-time clock ****************************************************************************/ void cmd_time(int argc, char **argv) { UNUSED(argc); UNUSED(argv); time_t rawtime; time(&rawtime); int iyr=0, imo=0, idy=0, ihr=0, imn=0, isc=0; rtc_get_time(&iyr, &imo, &idy, &ihr, &imn, &isc); printf("RTC time: %04d-%02d-%02d %02d:%02d:%02d\r\n", iyr, imo, idy, ihr, imn, isc); printf("\repoch timestamp: %lu\r\n", time(NULL)); } /***************************************************************************** * Function: cmd_outputs * Description: display outputs ****************************************************************************/ void cmd_outputs(int argc, char **argv) { UNUSED(argc); UNUSED(argv); DisplayOutputs(); } /***************************************************************************** * Function: cmd_sout * Description: set output * * @param argc-> number of args * @param argv-> output * @return none *****************************************************************************/ void cmd_sout(int argc, char **argv) { float value = atof( argv[2] ); if ( argc != 3 ) { printf("\rusage: sout <output> <value>\r\n"); printf("\rexample: sout o_rly1 1\r\n"); return; } ModbusMasterWriteRegister( argv[1], value ); } /***************************************************************************** * Function: cmd_settime * Description: set real-time clock * * @param argc-> number of args * @param argv-> input * @return none *****************************************************************************/ void cmd_settime(int argc, char **argv) { if ( argc != 7 ) { printf("\rusage: set-time <yyyy> <mm> <dd> <hh> <mm> <ss>\n"); printf("\rexample: set-time 2016 12 25 12 0 0\r\n"); return; } rtc_set_time(atoi(argv[1]), // year atoi(argv[2]), // month atoi(argv[3]), // day atoi(argv[4]), // hr atoi(argv[5]), // min atoi(argv[6])); // sec } /***************************************************************************** * Function: cmd_simin * Description: simulat input * * @param argc-> number of args * @param argv-> input * @return none *****************************************************************************/ void cmd_simin(int argc, char **argv) { float value = atof( argv[2] ); if ( argc < 3 ) { printf("\rusage: simin <input> <value> <low> <hi> <step>\r\n"); printf("\rexample: simin i_tra01 100 90 110 5\r\n"); return; } SimulateInputMap[argv[1]].start_value = atof(argv[2]); ModbusRegisterMap[argv[1]].simulated = true; if ( argc < 3 ) { SimulateInputMap[argv[1]].min = 0; SimulateInputMap[argv[1]].max = 0; return; } SimulateInputMap[argv[1]].min = atof(argv[3]); SimulateInputMap[argv[1]].max = atof(argv[4]); SimulateInputMap[argv[1]].step = atof(argv[5]); } void cmd_deep( int argc, char **argv ) { UNUSED(argc); UNUSED(argv); char logString[LOG_BYTES_PER_ENTRY]; LogLocalApi_PopEntry( logString ); if( logString[0] != '\0' ) { printf("%s\r\n", logString ); } else { printf("%s\r\n", "No String Found" ); } } void cmd_peep( int argc, char **argv ) { UNUSED(argc); UNUSED(argv); std::string logString = "This is a string to log"; LogLocalApi_PushEntry( logString.c_str() ); } void cmd_inslog( int argc, char **argv ) { UNUSED(argc); UNUSED(argv); EventReasonStruct_t eventReason; eventReason.eventReason = EVENT_REASON_AUTO; eventReason.inputValue = 100.00; strncpy(eventReason.inputTag, "i_stub01", sizeof(eventReason.inputTag) ); eventReason.outputValue = 0.0; strncpy(eventReason.outputTag, "o_stub01", sizeof(eventReason.outputTag) ); EventLoggerApi( eventReason ); }