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/ConfigurationHandler/ConfigurationHandler.cpp
- Committer:
- jmarkel44
- Date:
- 2016-10-19
- Revision:
- 232:8a86b5bf38f7
- Parent:
- 231:f22901955e0c
- Child:
- 250:1cd8ec63e9e9
File content as of revision 232:8a86b5bf38f7:
/******************************************************************************
*
* File: ConfigurationHandler.cpp
* Desciption: source for the ICE Configuration Handler
*
*****************************************************************************/
#include "ConfigurationHandler.h"
#include "global.h"
#include "SetpointControl.h"
#include "TimerControl.h"
#include "CompositeControl.h"
#include "CompositeAlgorithm.h"
#include <algorithm>
StringSetpointMap setpointTable; // setpoint control object table
StringVectorTimerMap timerTable; // timer control object table
StringManualMap manualTable; // manual control object table
StringCompositeMap compositeTable; // composite control object table
StringAlgorithmMap algorithmTable; // composite control algorithms
// local function prototypes
static int loadPersistentControls(void);
// local helper functions
static int createControl(const Message_t *msg);
static int modifyControl(const Message_t *msg);
static int destroyControl(const Message_t *msg);
// sort function for timer controls
bool compareStartTime(const TimerControl *lhs, const TimerControl *rhs)
{
return (lhs->getStartTime() < rhs->getStartTime());
}
/*****************************************************************************
* Function: ConfigurationHandler()
* Description: The ICE Configuration Handler
*
* @param args (unused)
* @return none
*****************************************************************************/
void ConfigurationHandler(void const *args)
{
UNUSED(args);
loadPersistentControls();
osSignalSet(mainThreadId, sig_config_continue);
while ( true ) {
// wait for an event
osEvent evt = MailBox.get();
if (evt.status == osEventMail) {
Message_t *msg = (Message_t*) evt.value.p;
logInfo("\r%s: msg->action = %d\n", __func__, msg->action);
logInfo("\r%s: msg->control = %d\n", __func__, msg->control);
logInfo("\r%s: msg->controlFile = %s\n", __func__, msg->controlFile);
switch ( msg->action ) {
case ACTION_CREATE: {
(void)createControl(msg);
break;
}
case ACTION_MODIFY: {
(void)modifyControl(msg);
break;
}
case ACTION_DESTROY: {
(void)destroyControl(msg);
break;
}
default:
break;
}
// free the message
MailBox.free(msg);
}
}
}
/*****************************************************************************
* Function: ConfigurationHandler_showControls()
* Description: show the controls
*
* @param msg
* @return none
*****************************************************************************/
void ConfigurationHandler_showControls(void)
{
if ( !timerTable.empty() ) {
printf("\r\n");
StringVectorTimerMap::iterator pos;
for ( pos = timerTable.begin(); pos != timerTable.end(); ++pos ) {
vector<TimerControl *>::iterator it;
for ( it = pos->second.begin(); it != pos->second.end(); ++it ) {
(*it)->display();
}
}
}
if ( !setpointTable.empty() ) {
printf("\r\n");
StringSetpointMap::iterator pos;
for ( pos = setpointTable.begin(); pos != setpointTable.end(); ++pos ) {
pos->second->display();
}
}
if ( !manualTable.empty() ) {
printf("\r\n");
StringManualMap::iterator pos;
for ( pos = manualTable.begin(); pos != manualTable.end(); ++pos ) {
pos->second->display();
}
}
if ( !compositeTable.empty() ) {
printf("\r\n");
StringCompositeMap::iterator pos;
for ( pos = compositeTable.begin(); pos != compositeTable.end(); ++pos ) {
pos->second->display();
}
}
}
void ConfigurationHandler_showAlgorithms(void)
{
StringAlgorithmMap::iterator pos;
for ( pos = algorithmTable.begin(); pos != algorithmTable.end(); ++pos ) {
pos->second->display();
}
}
/*****************************************************************************
* Function: loadPersistentControls()
* Description: load persistent controls from flash
*
* @param none
* @return none
*****************************************************************************/
static int loadPersistentControls(void)
{
static bool loaded = false;
if ( !loaded ) { // lazy protection
printf("\rLoading persistent controls: \n");
std::vector<mDot::mdot_file> file_list = GLOBAL_mdot->listUserFiles();
loaded = true;
for (std::vector<mDot::mdot_file>::iterator i = file_list.begin(); i != file_list.end(); ++i) {
if( strncmp( i->name, CONTROL_SP_STR, strlen(CONTROL_SP_STR)) == 0 ) {
// create the setpoint control
Message_t msg;
msg.control = CONTROL_SETPOINT;
strncpy(msg.controlFile, i->name, sizeof(msg.controlFile));
int rc = createControl(&msg);
if ( rc != 0 ) {
logError("%s: failed to load %s", __func__, msg.controlFile);
} else {
printf("\r control %s loaded.\n", msg.controlFile);
}
} else if ( strncmp( i->name, CONTROL_TM_STR, strlen(CONTROL_TM_STR)) == 0 ) {
// create the timer control
Message_t msg;
msg.control = CONTROL_TIMER;
strncpy(msg.controlFile, i->name, sizeof(msg.controlFile));
int rc = createControl(&msg);
if ( rc != 0 ) {
logError("%s: failed to load %s", __func__, msg.controlFile);
} else {
printf("\r control %s loaded.\n", msg.controlFile);
}
} else if ( strncmp( i->name, CONTROL_COMP_STR, strlen(CONTROL_COMP_STR)) == 0 ) {
Message_t msg;
msg.control = CONTROL_COMPOSITE;
strncpy(msg.controlFile, i->name, sizeof(msg.controlFile));
int rc = createControl(&msg);
if ( rc != 0 ) {
logError("%s: failed to load %s\n", __func__, msg.controlFile);
} else {
printf("\r control %s loaded.\n", msg.controlFile);
}
} else if ( strncmp( i->name, CONTROL_CA_STR, strlen(CONTROL_CA_STR)) == 0 ) {
Message_t msg;
msg.control = CONTROL_ALGORITHM;
strncpy(msg.controlFile, i->name, sizeof(msg.controlFile));
int rc = createControl(&msg);
if ( rc != 0 ) {
logError("%s: failed to load %s\n", __func__, msg.controlFile);
} else {
printf("\r control %s loaded.\n", msg.controlFile);
}
} else if ( strncmp( i->name, CONTROL_MN_STR, strlen(CONTROL_MN_STR)) == 0 ) {
// TODO: delete any timed manual control, not continuous...
GLOBAL_mdot->deleteUserFile(i->name);
} else {
logInfo("\rNot A Control File%s\r\n",i->name);
// not a control file
}
}
}
return 0;
}
/*****************************************************************************
* Function: createControl()
* Description: creates a new control
*
* @param none
* @return none
*****************************************************************************/
static int createControl(const Message_t *msg)
{
logInfo("\r%s invoked\n", __func__);
switch (msg->control) {
case CONTROL_SETPOINT: {
SetpointControl *setpointControl = new SetpointControl;
bool rc = setpointControl->load(msg->controlFile);
if ( rc != true ) {
logError("%s: failed to load %s\n", __func__, msg->controlFile);
delete setpointControl;
} else {
setpointTable[msg->controlFile] = setpointControl;
// start the setpoint control
setpointControl->start();
}
break;
}
case CONTROL_TIMER: {
TimerControl *timerControl = new TimerControl;
bool rc = timerControl->load(msg->controlFile);
if ( rc != true ) {
logError("%s: failed to load %s\n", __func__, msg->controlFile);
delete timerControl;
} else {
timerTable[timerControl->getOutput()].push_back(timerControl);
sort(timerTable[timerControl->getOutput()].begin(),
timerTable[timerControl->getOutput()].end(),
compareStartTime);
timerControl->start();
}
break;
}
case CONTROL_MANUAL: {
ManualControl *manualControl = new ManualControl;
bool rc = manualControl->load(msg->controlFile);
if ( rc != true ) {
logError("%s: failed to load %s\n", __func__, msg->controlFile);
delete manualControl;
} else {
manualTable[msg->controlFile] = manualControl;
// start the manual control
manualControl-> start();
}
break;
}
case CONTROL_COMPOSITE: {
CompositeControl *compositeControl = new CompositeControl;
bool rc = compositeControl->load(msg->controlFile);
if ( rc != true ) {
logError("%s: failed to load %s\n", __func__, msg->controlFile);
delete compositeControl;
} else {
compositeTable[msg->controlFile] = compositeControl;
// add this control to the table
compositeControl->start();
}
break;
}
case CONTROL_ALGORITHM: {
CompositeAlgorithm *compositeAlgorithm = new CompositeAlgorithm;
bool rc = compositeAlgorithm->load(msg->controlFile);
if ( rc != true ) {
logError("%s: failed to load %s\n", __func__, msg->controlFile);
} else {
// add this algorithm to the table
algorithmTable[compositeAlgorithm->getId()] = compositeAlgorithm;
}
break;
}
case CONTROL_PID:
default:
logInfo("\r%s: control type %d not implemented yet...\n",
__func__, msg->control);
break;
}
return 0;
}
/*****************************************************************************
* Function: modifyControl()
* Description: modifies a control
*
* @param msg
* @return none
*****************************************************************************/
static int modifyControl(const Message_t *msg)
{
logInfo("\r%s invoked\n", __func__);
switch (msg->control) {
case CONTROL_SETPOINT: {
// find the control in the table
StringSetpointMap::iterator pos;
pos = setpointTable.find(msg->controlFile);
if ( pos != setpointTable.end() ) {
int rc = pos->second->load(msg->controlFile);
if ( rc != true ) {
logError("\rFailed to reload the setpoint control %s\n", msg->controlFile);
} else {
logInfo("\rReloaded the setpoint control %s\n", msg->controlFile);
}
}
break;
}
case CONTROL_MANUAL: {
// find the manual control in the table
StringManualMap::iterator pos;
pos = manualTable.find(msg->controlFile);
if ( pos != manualTable.end() ) {
int rc = pos->second->load(msg->controlFile);
if ( rc != true ) {
logError("\rFailed to reload the manual control %s\n", msg->controlFile);
} else {
logInfo("\rReloaded the manual control %s\n", msg->controlFile);
}
}
break;
}
default:
logError("%s: unknown control %d\n", __func__, msg->control);
break;
}
return 0;
}
/*****************************************************************************
* Function: destroyControl()
* Description: destroys a controls
*
* @param msg
* @return none
*****************************************************************************/
static int destroyControl(const Message_t *msg)
{
logInfo("\r%s invoked\n", __func__);
switch ( msg->control ) {
case CONTROL_SETPOINT: {
StringSetpointMap::iterator pos;
pos = setpointTable.find(msg->controlFile);
if ( pos != setpointTable.end() ) {
GLOBAL_mdot->deleteUserFile(msg->controlFile);
logInfo("%s: deleted %s", __func__, msg->controlFile);
pos->second->unregisterControl();
delete (pos->second);
setpointTable.erase(pos);
} else {
logError("%s: unable to find %s\n", __func__, msg->controlFile);
}
break;
}
case CONTROL_TIMER: {
StringVectorTimerMap::iterator pos;
#if 0
pos = timerTable.find(msg->controlFile);
if ( pos != timerTable.end() ) {
delete ((*pos)->second);
timerTable.erase(pos);
}
#endif
break;
}
case CONTROL_MANUAL: {
StringManualMap::iterator pos;
pos = manualTable.find(msg->controlFile);
if ( pos != manualTable.end() ) {
GLOBAL_mdot->deleteUserFile(msg->controlFile);
logInfo("%s: deleted %s", __func__, msg->controlFile);
pos->second->unregisterControl();
delete (pos->second);
manualTable.erase(pos);
} else {
logError("%s: unable to find %s", __func__, msg->controlFile);
}
break;
}
default:
break;
}
return 0;
}
