From c44f11218bbe8ef5c036c1b90d12243147db784b Mon Sep 17 00:00:00 2001 From: Mateusz Date: Thu, 27 Jun 2019 15:07:47 +0200 Subject: [PATCH] WiP: muxchannel workers --- module-cellular/Modem/GSM0710.hpp | 3 - module-cellular/Modem/InputSerialWorker.cpp | 7 +- module-cellular/Modem/MuxChannel.cpp | 41 ++++++-- module-cellular/Modem/MuxChannel.hpp | 33 ++++++- module-cellular/Modem/MuxDaemon.cpp | 93 +++++++++++++++---- module-cellular/Modem/MuxDaemon.hpp | 24 ++--- .../RTOSWrapper/include}/Mailbox.hpp | 8 -- module-os/RTOSWrapper/include/thread.hpp | 4 +- module-sys/Service/Worker.hpp | 4 +- module-sys/SystemManager/SystemManager.hpp | 2 +- 10 files changed, 155 insertions(+), 64 deletions(-) rename {module-sys/Service => module-os/RTOSWrapper/include}/Mailbox.hpp (98%) diff --git a/module-cellular/Modem/GSM0710.hpp b/module-cellular/Modem/GSM0710.hpp index 590d5f23e..ea009e759 100644 --- a/module-cellular/Modem/GSM0710.hpp +++ b/module-cellular/Modem/GSM0710.hpp @@ -99,9 +99,6 @@ public: // some state // +CMUX=[,[,[,[,[,[,[,[,]]]]]]]] uint32_t cmux_mode = 0; - const static int cmux_subset = 0; - const static int cmux_port_speed = 5; //115200 baud rate - const static int cmux_port_speed_default = 5; //115200 baud rate uint32_t vir_ports = 3; /* number of virtual ports to create */ uint32_t cmux_N1 = 127; //lots of modem only support short frame, like quectel 2G modules uint32_t cmux_FRAME = (cmux_N1 + 6); //lots of modem only support short frame, like quectel 2G modules diff --git a/module-cellular/Modem/InputSerialWorker.cpp b/module-cellular/Modem/InputSerialWorker.cpp index e1cad4055..dcb463d95 100644 --- a/module-cellular/Modem/InputSerialWorker.cpp +++ b/module-cellular/Modem/InputSerialWorker.cpp @@ -141,16 +141,15 @@ int InputSerialWorker::ExtractFrames() { if (muxDaemon->channels[frame->channel].GetState() == MuxChannel::State::Opened) {//reopening, discard the data - { +/* { // TODO:M.P distribute frame to virtual channel char buff[256] = {0}; memcpy(buff, frame->data, frame->length); write_result = frame->length; LOG_DEBUG("Raw data: %s",buff); - } + }*/ - - // write_result = pseudo_device_write(&channellist[frame->channel], frame->data, frame->length); + write_result = muxDaemon->channels[frame->channel].Send(frame->data,frame->length); } else { LOG_INFO("channel %d closed, discard the frame", frame->channel); write_result = frame->length; diff --git a/module-cellular/Modem/MuxChannel.cpp b/module-cellular/Modem/MuxChannel.cpp index 8ae6b553e..ab5295bcd 100644 --- a/module-cellular/Modem/MuxChannel.cpp +++ b/module-cellular/Modem/MuxChannel.cpp @@ -13,7 +13,9 @@ #include "GSM0710.hpp" #include "MuxDaemon.hpp" -MuxChannel::MuxChannel(MuxDaemon *mux,uint32_t logicalNumber,const char *name) : +MuxChannel::MuxChannel(MuxDaemon *mux, uint32_t logicalNumber, const char *name,uint32_t stackDepth) : + cpp_freertos::Thread(std::string{name}, stackDepth/4 /* Stack depth in bytes */, 0), + workerMsgQueue(this), v24signals( static_cast(MuxDefines::GSM0710_SIGNAL_DV ) | static_cast(MuxDefines::GSM0710_SIGNAL_RTR) | static_cast(MuxDefines::GSM0710_SIGNAL_RTC) | static_cast(MuxDefines::GSM0710_EA)), @@ -22,8 +24,7 @@ MuxChannel::MuxChannel(MuxDaemon *mux,uint32_t logicalNumber,const char *name) : logicalNumber(logicalNumber), name(name), state(State::Closed), - mux(mux){ - + mux(mux) { } @@ -33,13 +34,39 @@ MuxChannel::~MuxChannel() { } int MuxChannel::Open() { - // Send virtrual channel request frame to GSM modem - mux->WriteMuxFrame(logicalNumber,NULL,0, static_cast(MuxDefines ::GSM0710_TYPE_SABM) | static_cast(MuxDefines ::GSM0710_PF)); + + enableRunLoop = true; + Start(); + + // Send virtual channel request frame to GSM modem + mux->WriteMuxFrame(logicalNumber, NULL, 0, static_cast(MuxDefines::GSM0710_TYPE_SABM) | + static_cast(MuxDefines::GSM0710_PF)); } int MuxChannel::Close() { + if (mux->inputBuffer->cmux_mode) - mux->WriteMuxFrame(logicalNumber, NULL, 0, static_cast(MuxDefines ::GSM0710_CONTROL_CLD) | static_cast(MuxDefines ::GSM0710_CR)); + mux->WriteMuxFrame(logicalNumber, NULL, 0, static_cast(MuxDefines::GSM0710_CONTROL_CLD) | + static_cast(MuxDefines::GSM0710_CR)); else - mux->WriteMuxFrame(logicalNumber, mux->closeChannelCmd, sizeof(mux->closeChannelCmd), static_cast(MuxDefines ::GSM0710_TYPE_UIH)); + mux->WriteMuxFrame(logicalNumber, mux->closeChannelCmd, sizeof(mux->closeChannelCmd), + static_cast(MuxDefines::GSM0710_TYPE_UIH)); +} + + +void MuxChannel::Run() { + + while(enableRunLoop){ + auto msg = workerMsgQueue.pop(); + + LOG_DEBUG("Received msg size(%d) : %s",msg->m_size,msg->m_data); + + + } +} + +int MuxChannel::Send(uint8_t* data, size_t size) { + + workerMsgQueue.push(std::make_shared(data,size)); + return size; } \ No newline at end of file diff --git a/module-cellular/Modem/MuxChannel.hpp b/module-cellular/Modem/MuxChannel.hpp index 524528436..794da8faa 100644 --- a/module-cellular/Modem/MuxChannel.hpp +++ b/module-cellular/Modem/MuxChannel.hpp @@ -13,10 +13,17 @@ #define PUREPHONE_MUXCHANNEL_HPP #include +#include +#include "Mailbox.hpp" +#include "FreeRTOS.h" +#include "queue.h" +#include "task.h" class MuxDaemon; -class MuxChannel { + +class MuxChannel : public cpp_freertos::Thread { + public: enum class State{ @@ -24,11 +31,27 @@ public: Closed }; - MuxChannel(MuxDaemon* mux,uint32_t logicalNumber,const char* name="Default"); + struct MuxChannelMsg{ + + MuxChannelMsg(uint8_t* data,size_t size){ + m_data = static_cast(malloc(size)); + m_size = size; + } + + ~MuxChannelMsg(){ + free(m_data); + } + + uint8_t* m_data; + size_t m_size; + }; + + MuxChannel(MuxDaemon* mux,uint32_t logicalNumber,const char* name="Default",uint32_t stackDepth=1024); virtual ~MuxChannel(); int Open(); int Close(); + int Send(uint8_t* data, size_t size); std::string& GetName(){ return name; @@ -50,6 +73,12 @@ public: private: + + void Run() override final; + + Mailbox> workerMsgQueue; + bool enableRunLoop = false; + std::string name; State state; MuxDaemon* mux; diff --git a/module-cellular/Modem/MuxDaemon.cpp b/module-cellular/Modem/MuxDaemon.cpp index 1047280a7..7a9bba855 100644 --- a/module-cellular/Modem/MuxDaemon.cpp +++ b/module-cellular/Modem/MuxDaemon.cpp @@ -19,12 +19,65 @@ #include "task.h" constexpr unsigned char MuxDaemon::closeChannelCmd[]; +const uint32_t MuxDaemon::frameSize; +const uint32_t MuxDaemon::virtualPortsCount; +const bool MuxDaemon::cmuxMode; + +namespace QuectelBaudrates { + + // Default value for 115200 key + template + struct Baudrates { + static const int Value = 5; + }; + + template<> + struct Baudrates<115200> { + static const int Value = 5; + }; + + template<> + struct Baudrates<230400> { + static const int Value = 6; + }; + + template<> + struct Baudrates<460800> { + static const int Value = 7; + }; + + template<> + struct Baudrates<921600> { + static const int Value = 8; + }; + + template<> + struct Baudrates<1500000> { + static const int Value = 16; + }; + + template<> + struct Baudrates<2000000> { + static const int Value = 20; + }; + + template<> + struct Baudrates<3000000> { + static const int Value = 23; + }; + + template<> + struct Baudrates<4000000> { + static const int Value = 26; + }; + +} MuxDaemon::MuxDaemon() { cellular = bsp::Cellular::Create(); inSerialDataWorker = std::make_unique(this); - inputBuffer = std::make_unique(virtualPortsCount,frameSize,cmuxMode); + inputBuffer = std::make_unique(virtualPortsCount, frameSize, cmuxMode); } MuxDaemon::~MuxDaemon() { @@ -38,11 +91,13 @@ int MuxDaemon::Start() { LOG_INFO("Modem does not respond to AT commands, trying close mux mode"); //We don't know in what cmux_mode modem currently is so send both types of closing signals - WriteMuxFrame(0, NULL, 0, static_cast(MuxDefines ::GSM0710_CONTROL_CLD) | static_cast(MuxDefines ::GSM0710_CR)); - WriteMuxFrame(0, closeChannelCmd, sizeof(closeChannelCmd), static_cast(MuxDefines ::GSM0710_TYPE_UIH)); + WriteMuxFrame(0, NULL, 0, static_cast(MuxDefines::GSM0710_CONTROL_CLD) | + static_cast(MuxDefines::GSM0710_CR)); + WriteMuxFrame(0, closeChannelCmd, sizeof(closeChannelCmd), + static_cast(MuxDefines::GSM0710_TYPE_UIH)); vTaskDelay(500); // give modem some time to establish mux // Try sending AT command once again - if (SendAT("AT\r\n", 500) == -1){ + if (SendAT("AT\r\n", 500) == -1) { LOG_INFO("Starting power up procedure..."); // If no response, power up modem and try again cellular->PowerUp(); @@ -64,10 +119,9 @@ int MuxDaemon::Start() { // Set up modem configuration - if(hardwareControlFlowEnable){ + if (hardwareControlFlowEnable) { SendAT("AT+IFC=2,2\r\n", 500); // enable flow control function for module - } - else{ + } else { SendAT("AT+IFC=0,0\r\n", 500); // disable flow control function for module } @@ -83,6 +137,8 @@ int MuxDaemon::Start() { SendAT("AT+QCFG=\"urc/ri/smsincoming\",\"off\"\r\n", 500); // Route URCs to UART1 SendAT("AT+QURCCFG=\"urcport\",\"uart1\"\r\n", 500); + // Turn on signal strength change URC + SendAT("AT+QINDCFG=\"csq\",1\r\n", 500); char gsm_command[128] = {}; @@ -90,7 +146,7 @@ int MuxDaemon::Start() { snprintf(gsm_command, sizeof(gsm_command), "AT+CMUX=1\r\n"); } else { snprintf(gsm_command, sizeof(gsm_command), "AT+CMUX=%d,%d,%d,%d\r\n", cmuxMode, - inputBuffer->cmux_subset, quectel_speeds[inputBuffer->cmux_port_speed],frameSize + cmuxSubset, QuectelBaudrates::Baudrates::Value, frameSize ); } @@ -103,14 +159,14 @@ int MuxDaemon::Start() { inSerialDataWorker->Init(); // Create virtual channels - channels.push_back(MuxChannel(this,0,"ControlChannel")); - channels.push_back(MuxChannel(this,1,"NotificationChannel")); + channels.push_back(MuxChannel(this, 0, "ControlChannel")); + channels.push_back(MuxChannel(this, 1, "NotificationChannel")); for (uint32_t i = 2; i < virtualPortsCount; ++i) { - channels.push_back(MuxChannel(this,i,("GenericChannel_" + std::to_string(i)).c_str())); + channels.push_back(MuxChannel(this, i, ("GenericChannel_" + std::to_string(i)).c_str())); } // Mux channels must be initialized in sequence - for(auto &w : channels){ + for (auto &w : channels) { w.Open(); vTaskDelay(200); } @@ -128,7 +184,7 @@ int MuxDaemon::SendAT(const char *cmd, uint32_t timeout) { char buff[256] = {0}; auto bytesWritten = cellular->Write(const_cast(cmd), strlen(cmd)); - LOG_DEBUG("BytesWritten: %d",bytesWritten); + LOG_DEBUG("BytesWritten: %d", bytesWritten); if (cellular->Wait(500)) { @@ -177,7 +233,7 @@ ssize_t MuxDaemon::WriteMuxFrame(int channel, const unsigned char *input, int le } /* let's not use too big frames */ length = std::min(inputBuffer->cmux_N1, static_cast(length)); - if (!inputBuffer->cmux_mode)//basic + if (!cmuxMode)//basic { /* Modified acording PATCH CRC checksum */ /* postfix[0] = frame_calc_crc (prefix + 1, prefix_length - 1); */ @@ -215,10 +271,11 @@ ssize_t MuxDaemon::WriteSerialCache(unsigned char *input, size_t length) { int MuxDaemon::CloseMux() { - for (auto &w : channels) { - if (w.GetState() == MuxChannel::State::Opened) { - LOG_INFO("Logical channel %d closed", w.logicalNumber); - w.Close(); + // Virtual channels need to be deinitialized in reversed order i.e control channel should be closed at the end + for (auto w = channels.size(); --w;) { + if (channels[w].GetState() == MuxChannel::State::Opened) { + LOG_INFO("Logical channel %d closed", channels[w].logicalNumber); + channels[w].Close(); } } diff --git a/module-cellular/Modem/MuxDaemon.hpp b/module-cellular/Modem/MuxDaemon.hpp index 28a5e8943..cc0560155 100644 --- a/module-cellular/Modem/MuxDaemon.hpp +++ b/module-cellular/Modem/MuxDaemon.hpp @@ -76,18 +76,6 @@ private: MUX_STATES_COUNT // keep this the last }; - /* - * The following arrays must have equal length and the values must - * correspond. also it has to correspond to the gsm0710 spec regarding - * baud id of CMUX the command. - */ - constexpr static int baud_rates[] = { - 0, 9600, 19200, 38400, 57600, 115200, 230400, 460800, 921600, 1500000, 2000000, 3000000, 4000000 - }; - - constexpr static int quectel_speeds[] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 16, 20, 23, 26 - }; constexpr static unsigned char closeChannelCmd[] = { static_cast(MuxDefines::GSM0710_CONTROL_CLD ) | @@ -112,11 +100,13 @@ private: * Multiplexer configuration */ - uint32_t baudRate = 115200; - uint32_t virtualPortsCount = 4; // max number of virtual channels supported by EG25 - uint32_t frameSize = 127; // default basic frame size, can be extended to max 32kBytes if needed - bool hardwareControlFlowEnable = false; - bool cmuxMode = false; + const static uint32_t baudRate = 115200; + const static uint32_t virtualPortsCount = 4; // max number of virtual channels supported by EG25 + const static uint32_t frameSize = 1024; // default basic frame size, can be extended to max 32kBytes if needed + const static bool hardwareControlFlowEnable = false; + const static bool cmuxMode = false; + const static uint32_t cmuxSubset = 0; + diff --git a/module-sys/Service/Mailbox.hpp b/module-os/RTOSWrapper/include/Mailbox.hpp similarity index 98% rename from module-sys/Service/Mailbox.hpp rename to module-os/RTOSWrapper/include/Mailbox.hpp index 4787dd36e..82652a4a2 100644 --- a/module-sys/Service/Mailbox.hpp +++ b/module-os/RTOSWrapper/include/Mailbox.hpp @@ -14,11 +14,6 @@ #include #include - -namespace sys -{ - - using namespace cpp_freertos; template @@ -100,7 +95,4 @@ private: }; -} - - #endif /* SYSTEMMANAGER_MAILBOX_HPP_ */ diff --git a/module-os/RTOSWrapper/include/thread.hpp b/module-os/RTOSWrapper/include/thread.hpp index 97c1c371c..50a1f0e5f 100644 --- a/module-os/RTOSWrapper/include/thread.hpp +++ b/module-os/RTOSWrapper/include/thread.hpp @@ -382,7 +382,7 @@ public: // TODO: M.P * The name of this thread. */ #ifndef CPP_FREERTOS_NO_CPP_STRINGS - const std::string Name; + std::string Name; #else char Name[configMAX_TASK_NAME_LEN]; #endif @@ -390,7 +390,7 @@ public: // TODO: M.P /** * Stack depth of this Thread, in words. */ - const uint16_t StackDepth; + uint16_t StackDepth; /** * A saved / cached copy of what the Thread's priority is. diff --git a/module-sys/Service/Worker.hpp b/module-sys/Service/Worker.hpp index 93f84ff0d..c68603e0d 100644 --- a/module-sys/Service/Worker.hpp +++ b/module-sys/Service/Worker.hpp @@ -44,8 +44,8 @@ struct WorkerCommand { */ class Worker { protected: - const uint32_t SERVICE_QUEUE_LENGTH = 10; - const uint32_t SERVICE_QUEUE_SIZE = sizeof( WorkerCommand ); + const static uint32_t SERVICE_QUEUE_LENGTH = 10; + const static uint32_t SERVICE_QUEUE_SIZE = sizeof( WorkerCommand ); sys::Service* service; //queue used by service to send commands to service. diff --git a/module-sys/SystemManager/SystemManager.hpp b/module-sys/SystemManager/SystemManager.hpp index 29a3d402f..f37b5f713 100644 --- a/module-sys/SystemManager/SystemManager.hpp +++ b/module-sys/SystemManager/SystemManager.hpp @@ -13,8 +13,8 @@ #include "timer.hpp" #include "condition_variable.hpp" #include "mutex.hpp" +#include "Mailbox.hpp" #include "Service/Bus.hpp" -#include "Service/Mailbox.hpp" #include "Service/Service.hpp" #include "Service/Message.hpp"