From b806210cfaf5202896c82a270af38f7ca507a445 Mon Sep 17 00:00:00 2001 From: Roland Jax Date: Thu, 20 Nov 2014 16:54:00 +0100 Subject: [PATCH] documentation for class BusLoop added. --- src/ebusd/busloop.cpp | 84 +++++++-------- src/ebusd/busloop.h | 238 ++++++++++++++++++++++++++++++++++++++---- src/ebusd/network.h | 4 +- 3 files changed, 261 insertions(+), 65 deletions(-) diff --git a/src/ebusd/busloop.cpp b/src/ebusd/busloop.cpp index ddba6485..ee772096 100644 --- a/src/ebusd/busloop.cpp +++ b/src/ebusd/busloop.cpp @@ -42,12 +42,6 @@ BusMessage::BusMessage(const std::string command, const bool poll, const bool sc pthread_cond_init(&m_cond, NULL); } -BusMessage::~BusMessage() -{ - pthread_mutex_destroy(&m_mutex); - pthread_cond_destroy(&m_cond); -} - const std::string BusMessage::getMessageStr() { std::string result; @@ -70,7 +64,7 @@ const std::string BusMessage::getMessageStr() BusLoop::BusLoop(Commands* commands) - : m_commands(commands), m_stop(false), m_lockCounter(0), + : m_commands(commands), m_running(true), m_lockCounter(0), m_priorRetry(false), m_scan(false), m_scanFull(false), m_scanIndex(0) { m_port = new Port(A.getOptVal("device"), A.getOptVal("nodevicecheck")); @@ -223,7 +217,7 @@ void* BusLoop::run() } - if (m_stop == true) { + if (m_running == false) { if (m_port->isOpen() == true) m_port->close(); @@ -343,28 +337,29 @@ void BusLoop::analyseCycData() skipfirst = true; } -void BusLoop::addPollMessage() +void BusLoop::collectSlave() { - int index = m_commands->nextPollCommand(); - if (index < 0) { - L.log(bus, error, "polling index out of range"); - } - else { - // TODO: implement as methode from class commands? - std::string tmp; - tmp += (*m_commands)[index][1]; - tmp += " "; - tmp += (*m_commands)[index][2]; - L.log(bus, event, " polling [%4d] %s", index, tmp.c_str()); + std::vector::iterator it; - std::string busCommand(A.getOptVal("address")); - busCommand += m_commands->getBusCommand(index); - std::transform(busCommand.begin(), busCommand.end(), busCommand.begin(), tolower); + for (int i = 0; i < 2; i++) { + bool found = false; + unsigned char mm = m_sstr[i]; - BusMessage* message = new BusMessage(busCommand, true, false); - L.log(bus, trace, " msg: %s", busCommand.c_str()); + if (i == 0) { + if (mm == 0xFF) + mm = 0x04; + else + mm += 0x05; + } - addMessage(message); + for (it = m_slave.begin(); it != m_slave.end(); it++) + if ((*it) == mm) + found = true; + + if (found == false && isMaster(mm) == false && mm != BROADCAST) { + m_slave.push_back(mm); + L.log(bus, event, " new slave: %d %02x", m_slave.size(), m_slave.back()); + } } } @@ -635,29 +630,28 @@ int BusLoop::recvSlaveData(SymbolString& result) return RESULT_OK; } -void BusLoop::collectSlave() +void BusLoop::addPollMessage() { - std::vector::iterator it; + int index = m_commands->nextPollCommand(); + if (index < 0) { + L.log(bus, error, "polling index out of range"); + } + else { + // TODO: implement as methode from class commands? + std::string tmp; + tmp += (*m_commands)[index][1]; + tmp += " "; + tmp += (*m_commands)[index][2]; + L.log(bus, event, " polling [%4d] %s", index, tmp.c_str()); - for (int i = 0; i < 2; i++) { - bool found = false; - unsigned char mm = m_sstr[i]; + std::string busCommand(A.getOptVal("address")); + busCommand += m_commands->getBusCommand(index); + std::transform(busCommand.begin(), busCommand.end(), busCommand.begin(), tolower); - if (i == 0) { - if (mm == 0xFF) - mm = 0x04; - else - mm += 0x05; - } + BusMessage* message = new BusMessage(busCommand, true, false); + L.log(bus, trace, " msg: %s", busCommand.c_str()); - for (it = m_slave.begin(); it != m_slave.end(); it++) - if ((*it) == mm) - found = true; - - if (found == false && isMaster(mm) == false && mm != BROADCAST) { - m_slave.push_back(mm); - L.log(bus, event, " new slave: %d %02x", m_slave.size(), m_slave.back()); - } + addMessage(message); } } diff --git a/src/ebusd/busloop.h b/src/ebusd/busloop.h index d03bc06a..5021351b 100644 --- a/src/ebusd/busloop.h +++ b/src/ebusd/busloop.h @@ -30,79 +30,200 @@ /** the maximum time [us] allowed for retrieving a byte from an addressed slave */ #define RECV_TIMEOUT 10000 +/** possible command types */ enum CommandType { invalid, broadcast, masterMaster, masterSlave }; +/** + * @brief class for data/message transfer between baseloop and busloop. + */ class BusMessage { public: + /** + * @brief constructs a new bus message instance and determine command type. + * @param command the command data to write on bus. + * @param poll true if message type is polling. + * @param scan true if message type is scanning. + */ BusMessage(const std::string command, const bool poll, const bool scan); - ~BusMessage(); + /** + * @brief destructor. + */ + ~BusMessage() + { + pthread_mutex_destroy(&m_mutex); + pthread_cond_destroy(&m_cond); + } + + /** + * @brief get the command type. + * @return the command type. + */ CommandType getType() const { return m_type; } - bool isPoll() const { return m_poll; } - bool isScan() const { return m_scan; } + /** + * @brief get the command string. + * @return the command string. + */ SymbolString getCommand() const { return m_command; } + + /** + * @brief get the result string. + * @return the result string. + */ SymbolString getResult() const { return m_result; } - bool isErrorResult() const { return m_resultCode < 0; } - const char* getResultCodeCStr() const { return getResultCode(m_resultCode); } + /** + * @brief set the result string and result code. + * @param result the result string. + * @param resultCode the result code. + */ void setResult(const SymbolString result, const int resultCode) { m_result = result; m_resultCode = resultCode; } + /** + * @brief return status of result code. + * @return true if result code is negativ. + */ + bool isErrorResult() const { return m_resultCode < 0; } + + /** + * @brief return output string of result code. + * @return the output string of result code. + */ + const char* getResultCodeCStr() const { return getResultCode(m_resultCode); } + + /** + * @brief return the message string or error result string. + * @return the message string or error result string. + */ const std::string getMessageStr(); + /** + * @brief return polling flag of message type. + * @return true if message type is polling. + */ + bool isPoll() const { return m_poll; } + + /** + * @brief return scanning flag of message type. + * @return true if message type is scanning. + */ + bool isScan() const { return m_scan; } + + /** + * @brief wait on notification. + */ void waitSignal() { pthread_cond_wait(&m_cond, &m_mutex); } // TODO timeout + + /** + * @brief send notification. + */ void sendSignal() { pthread_cond_signal(&m_cond); } private: + /** the command type */ CommandType m_type; + + /** true if message is of type polling */ bool m_poll; + + /** true if message is of type scanning */ bool m_scan; + + /** the command string (master data) */ SymbolString m_command; + + /** the result string (slave data) */ SymbolString m_result; + + /** the result code of result string */ int m_resultCode; + /** mutex variable for exclusive lock */ pthread_mutex_t m_mutex; + + /** condition variable for exclusive lock */ pthread_cond_t m_cond; + }; - +/** + * @brief class busloop which handle all bus activities. + */ class BusLoop : public Thread { public: + /** + * @brief create a busloop instance and set the commands instance. + * @param commands the commands instance. + */ BusLoop(Commands* commands); + + /** + * @brief destructor. + */ ~BusLoop(); + /** + * @brief endless loop for busloop instance. + * @return void pointer. + */ void* run(); - void stop() { m_stop = true; } + /** + * @brief shut down busloop. + */ + void stop() { m_running = false; } + + /** + * @brief add a new bus message to internal message queue. + * @param message the bus message. + */ void addMessage(BusMessage* message) { m_busQueue.add(message); } + /** + * @brief switch to new commands instance. + * @param commands reference of new loaded commands instance. + */ void reload(Commands* commands) { m_commands = commands; } + /** + * @brief scanning ebus do determine bus members. + * @param full if true a scan of all slave addresses will be done. + */ void scan(const bool full=false) { m_scan = true; m_scanFull = full; m_scanIndex = 0; } + /** + * @brief toggle (on/off) logging of raw data to logging system. + */ void raw() { m_logRawData == true ? m_logRawData = false : m_logRawData = true ; } /** * @brief set the name of dump file. - * @param name the file name of dump file. + * @param dumpFile the file name of dump file. */ void setDumpFile(const std::string& dumpFile) { m_dumpFile = dumpFile; } /** * @brief set the max size of dump file. - * @param size the max. size of the dump file, before switching. + * @param dumpSize the max. size of the dump file, before switching. */ void setDumpSize(const long dumpSize) { m_dumpSize = dumpSize; } + /** + * @brief toggle (on/off) dumping of raw bytes to a dump file. + */ void dump() { m_dumping == true ? m_dumping = false : m_dumping = true ; } private: + /** the commands instance */ Commands* m_commands; + + /** the port instance which control the ebus device */ Port* m_port; /** the name of dump file*/ @@ -111,28 +232,54 @@ private: /** max. size of dump file */ long m_dumpSize; + /** true if dumping of raw bytes to file is enabled */ bool m_dumping; + /** true if logging of raw bytes is enabled */ bool m_logRawData; - bool m_stop; + /** true if this instance is running */ + bool m_running; + /** bus access is not allowed if counter is greater than 0 */ int m_lockCounter; + + /** if true, we lost bus acquire but same priority class. + * after next SYN sign we are allowed to try again to aquire bus. + */ bool m_priorRetry; + /** queue for bus messages */ WQueue m_busQueue; + + /** string for cycle bus data */ SymbolString m_sstr; - double m_pollInterval; - long m_recvTimeout; + /** number of send retries for one bus command */ int m_sendRetries; + + /** number of lock retries (acquire bus) for one bus command */ int m_lockRetries; + + /** time for receiving answer from slave [us] */ + long m_recvTimeout; + + /** waiting time for bus acquire [us] */ long m_acquireTime; + /** time between to polling commands [s] */ + double m_pollInterval; + + /** vector with collected slave addresses */ std::vector m_slave; + /** true if bus scanning for collected slave addresses is active */ bool m_scan; + + /** true if bus scanning for all slave addresses is active */ bool m_scanFull; + + /** internal index do get next scan command */ size_t m_scanIndex; /** @@ -142,16 +289,71 @@ private: */ int writeDumpFile(const char* byte); + /** + * @brief fetch next byte of device input buffer (dumping and raw logging). + * @return next byte of device. + */ unsigned char fetchByte(); + + /** + * @brief collect cycle bytes. the analysis of collected bytes will be triggered after next SYN sign. + * @param numRecv the number of bytes to analyze. + */ void collectCycData(const int numRecv); + + /** + * @brief the analyzing of collected bytes. collecting of slave address will be triggered. + */ void analyseCycData(); - void addPollMessage(); - int acquireBus(); - BusMessage* sendCommand(); - int sendByte(const unsigned char sendByte); - int recvSlaveAck(unsigned char& recvByte); - int recvSlaveData(SymbolString& result); + + /** + * @brief determine and collect slave addresses. + */ void collectSlave(); + + /** + * @brief try to acquire bus for sending purpose. + * @return result code of bus acquiring. + */ + int acquireBus(); + + /** + * @brief handle sending of a bus command. + * @return a reference to sent bus message. + */ + BusMessage* sendCommand(); + + /** + * @brief send 1 byte to bus device. + * @param sendByte the byte to send. + * @return result code of byte sending. + */ + int sendByte(const unsigned char sendByte); + + /** + * @brief receive ACK from slave. + * @param reference for receive byte. + * @return result code of receiving byte. + */ + int recvSlaveAck(unsigned char& recvByte); + + /** + * @brief receive slave data block. + * @param reference for result string. + * @return result code of receiving slave data. + */ + int recvSlaveData(SymbolString& result); + + /** + * @brief add a polling bus message to internal message queue. + * @param message the bus message. + */ + void addPollMessage(); + + /** + * @brief add a scanning bus message to internal message queue. + * @param message the bus message. + */ void addScanMessage(); }; diff --git a/src/ebusd/network.h b/src/ebusd/network.h index 2f25b46e..18b02d29 100644 --- a/src/ebusd/network.h +++ b/src/ebusd/network.h @@ -140,7 +140,7 @@ public: void* run(); /** - * @brief closs active connection. + * @brief close active connection. */ void stop() const { m_notify.notify(); } @@ -185,7 +185,7 @@ class Network : public Thread public: /** - * @brief create a new network instance and listening for incoming connections. + * @brief create a network instance and listening for incoming connections. * @param local true to accept connections only for local host. * @param netQueue the remote queue for network messages. */