diff --git a/module-sys/Service/Message.cpp b/module-sys/Service/Message.cpp index 0164bb8df..5b8878ee6 100644 --- a/module-sys/Service/Message.cpp +++ b/module-sys/Service/Message.cpp @@ -44,7 +44,7 @@ namespace sys { break; case SystemMessageType ::SwitchPowerMode: - service->SwitchPowerModeHandler(ServicePowerMode::Active); + service->SwitchPowerModeHandler(powerMode); break; case SystemMessageType ::Exit: diff --git a/module-sys/Service/Message.hpp b/module-sys/Service/Message.hpp index aa68acf5b..9cc380ee1 100644 --- a/module-sys/Service/Message.hpp +++ b/module-sys/Service/Message.hpp @@ -86,9 +86,10 @@ namespace sys { public: - SystemMessage(SystemMessageType sysMsgType): + SystemMessage(SystemMessageType sysMsgType,ServicePowerMode pwrMode = ServicePowerMode::Active): Message(BusChannels ::System), - sysMsgType(sysMsgType) + sysMsgType(sysMsgType), + powerMode(pwrMode) { type = Type::System; } @@ -96,6 +97,7 @@ namespace sys Message_t Execute(Service* service) override; SystemMessageType sysMsgType; + ServicePowerMode powerMode; }; class DataMessage : public Message diff --git a/module-sys/SystemManager/SystemManager.cpp b/module-sys/SystemManager/SystemManager.cpp index c885ad28e..8a1cf9292 100644 --- a/module-sys/SystemManager/SystemManager.cpp +++ b/module-sys/SystemManager/SystemManager.cpp @@ -14,34 +14,31 @@ #include -namespace sys -{ +namespace sys { using namespace cpp_freertos; using namespace std; using namespace sys; - const char* systemManagerServiceName = "SysMgrService"; + const char *systemManagerServiceName = "SysMgrService"; SystemManager::SystemManager(TickType_t pingInterval) : Service(systemManagerServiceName), - pingInterval(pingInterval) - { + pingInterval(pingInterval) { // Specify list of channels which System Manager is registered to - busChannels = {BusChannels ::SystemManagerRequests}; + busChannels = {BusChannels::SystemManagerRequests}; } - SystemManager::~SystemManager() - { + SystemManager::~SystemManager() { LogOutput::Output(GetName() + ":destructor"); } - void SystemManager::Run(){ + void SystemManager::Run() { InitHandler(); - if(userInit){ + if (userInit) { userInit(); } @@ -55,8 +52,7 @@ namespace sys EndScheduler(); } - void SystemManager::StartSystem(std::function init) - { + void SystemManager::StartSystem(std::function init) { LogOutput::Output("Initializing system..."); userInit = init; @@ -64,18 +60,49 @@ namespace sys // Start System manager StartService(); - pingPongTimerID = CreateTimer(Ticks::MsToTicks(pingInterval),true); - ReloadTimer(pingPongTimerID); + //M.P: Ping/pong mechanism is turned off. It doesn't bring any value to the system. + //pingPongTimerID = CreateTimer(Ticks::MsToTicks(pingInterval), true); + //ReloadTimer(pingPongTimerID); } - bool SystemManager::CloseSystem(Service* s){ + bool SystemManager::CloseSystem(Service *s) { - Bus::SendUnicast(std::make_shared(SystemManagerMsgType::CloseSystem),systemManagerServiceName,s); + Bus::SendUnicast(std::make_shared(SystemManagerMsgType::CloseSystem), + systemManagerServiceName, s); return true; } - bool SystemManager::CreateService(std::shared_ptr service,Service* caller,TickType_t timeout){ + bool SystemManager::SuspendSystem(Service *caller) { + + for(const auto &w : servicesList){ + if(w->GetName() != caller->GetName()){ + auto ret = Bus::SendUnicast(std::make_shared(SystemMessageType::SwitchPowerMode,ServicePowerMode::SuspendToRAM), + w->GetName(), caller); + if(!ret){ + LOG_FATAL("Service %s failed to enter low-power mode",w->GetName().c_str()); + } + } + + } + } + + bool SystemManager::ResumeSystem(Service *caller) { + for(const auto &w : servicesList){ + + if(w->GetName() != caller->GetName()){ + auto ret = Bus::SendUnicast(std::make_shared(SystemMessageType::SwitchPowerMode,ServicePowerMode::Active), + w->GetName(), caller); + if(!ret){ + LOG_FATAL("Service %s failed to exit low-power mode",w->GetName().c_str()); + } + } + + + } + } + + bool SystemManager::CreateService(std::shared_ptr service, Service *caller, TickType_t timeout) { CriticalSection::Enter(); @@ -85,74 +112,70 @@ namespace sys service->StartService(); auto msg = std::make_shared(SystemMessageType::Start); - auto ret = Bus::SendUnicast(msg,service->GetName(),caller,timeout); + auto ret = Bus::SendUnicast(msg, service->GetName(), caller, timeout); auto resp = std::static_pointer_cast(ret.second); - if(ret.first == ReturnCodes::Success && (resp->retCode == ReturnCodes::Success)){ + if (ret.first == ReturnCodes::Success && (resp->retCode == ReturnCodes::Success)) { return true; - } - else{ + } else { return false; } } - bool SystemManager::DestroyService(const std::string& name,Service* caller,TickType_t timeout){ + bool SystemManager::DestroyService(const std::string &name, Service *caller, TickType_t timeout) { auto msg = std::make_shared(SystemMessageType::Exit); - auto ret = Bus::SendUnicast(msg,name,caller,timeout); + auto ret = Bus::SendUnicast(msg, name, caller, timeout); auto resp = std::static_pointer_cast(ret.second); - if(ret.first == ReturnCodes::Success && (resp->retCode == ReturnCodes::Success)){ + if (ret.first == ReturnCodes::Success && (resp->retCode == ReturnCodes::Success)) { cpp_freertos::LockGuard lck(destroyMutex); - auto serv = std::find_if(servicesList.begin(),servicesList.end(),[&](std::shared_ptrconst &s) { return s->GetName() == name; }); - if(serv == servicesList.end()){ + auto serv = std::find_if(servicesList.begin(), servicesList.end(), + [&](std::shared_ptr const &s) { return s->GetName() == name; }); + if (serv == servicesList.end()) { return false; } servicesList.erase(serv); return true; - } - else{ + } else { return false; } } - ReturnCodes SystemManager::InitHandler(){ + ReturnCodes SystemManager::InitHandler() { isReady = true; - return ReturnCodes ::Success; + return ReturnCodes::Success; } - void SystemManager::TickHandler(uint32_t id) - { - if(id == pingPongTimerID){ + void SystemManager::TickHandler(uint32_t id) { + if (id == pingPongTimerID) { - for(auto &w : servicesList){ - if(w->pingTimestamp==0){ + for (auto &w : servicesList) { + if (w->pingTimestamp == 0) { //no reponse for ping messages, restart system LogOutput::Output(w->GetName() + " failed to response to ping message"); exit(1); - } - else{ + } else { w->pingTimestamp = 0; } } - Bus::SendBroadcast(std::make_shared(SystemMessageType::Ping),this); + Bus::SendBroadcast(std::make_shared(SystemMessageType::Ping), this); } } - Message_t SystemManager::DataReceivedHandler(DataMessage* msg,ResponseMessage* resp) - { - if(msg->channel == BusChannels::SystemManagerRequests){ - SystemManagerMsg* data = static_cast(msg); + Message_t SystemManager::DataReceivedHandler(DataMessage *msg, ResponseMessage *resp) { + if (msg->channel == BusChannels::SystemManagerRequests) { + SystemManagerMsg *data = static_cast(msg); - switch(data->type){ + switch (data->type) { case SystemManagerMsgType::CloseSystem: CloseSystemHandler(); @@ -166,25 +189,25 @@ namespace sys } - void SystemManager:: CloseSystemHandler(){ + void SystemManager::CloseSystemHandler() { LogOutput::Output("Invoking closing procedure..."); DeleteTimer(pingPongTimerID); // We are going to remove services in reversed order of creation CriticalSection::Enter(); - std::reverse(servicesList.begin(),servicesList.end()); + std::reverse(servicesList.begin(), servicesList.end()); CriticalSection::Exit(); retry: - for(auto &w : servicesList){ + for (auto &w : servicesList) { // Sysmgr stores list of all active services but some of them are under control of parent services. // Parent services ought to manage lifetime of child services hence we are sending DestroyRequests only to parents. - if(w->parent == ""){ - auto ret = DestroyService(w->GetName(),this); - if(!ret){ + if (w->parent == "") { + auto ret = DestroyService(w->GetName(), this); + if (!ret) { //no response to exit message, LogOutput::Output(w->GetName() + " failed to response to exit message"); exit(1); @@ -193,8 +216,8 @@ namespace sys } } - if(servicesList.size() == 0){ - enableRunLoop = false; + if (servicesList.size() == 0) { + enableRunLoop = false; } } diff --git a/module-sys/SystemManager/SystemManager.hpp b/module-sys/SystemManager/SystemManager.hpp index b539d090d..0eb5fe906 100644 --- a/module-sys/SystemManager/SystemManager.hpp +++ b/module-sys/SystemManager/SystemManager.hpp @@ -49,6 +49,10 @@ public: // Invoke system close procedure static bool CloseSystem(Service* s); + static bool SuspendSystem(Service* caller); + + static bool ResumeSystem(Service* caller); + // Create new service static bool CreateService(std::shared_ptr service,Service* caller,TickType_t timeout=5000);