documentation for class BusLoop added.

This commit is contained in:
Roland Jax
2014-11-20 16:54:00 +01:00
parent 737e8e6938
commit b806210cfa
3 changed files with 261 additions and 65 deletions
+39 -45
View File
@@ -42,12 +42,6 @@ BusMessage::BusMessage(const std::string command, const bool poll, const bool sc
pthread_cond_init(&m_cond, NULL); pthread_cond_init(&m_cond, NULL);
} }
BusMessage::~BusMessage()
{
pthread_mutex_destroy(&m_mutex);
pthread_cond_destroy(&m_cond);
}
const std::string BusMessage::getMessageStr() const std::string BusMessage::getMessageStr()
{ {
std::string result; std::string result;
@@ -70,7 +64,7 @@ const std::string BusMessage::getMessageStr()
BusLoop::BusLoop(Commands* commands) 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_priorRetry(false), m_scan(false), m_scanFull(false), m_scanIndex(0)
{ {
m_port = new Port(A.getOptVal<const char*>("device"), A.getOptVal<bool>("nodevicecheck")); m_port = new Port(A.getOptVal<const char*>("device"), A.getOptVal<bool>("nodevicecheck"));
@@ -223,7 +217,7 @@ void* BusLoop::run()
} }
if (m_stop == true) { if (m_running == false) {
if (m_port->isOpen() == true) if (m_port->isOpen() == true)
m_port->close(); m_port->close();
@@ -343,28 +337,29 @@ void BusLoop::analyseCycData()
skipfirst = true; skipfirst = true;
} }
void BusLoop::addPollMessage() void BusLoop::collectSlave()
{ {
int index = m_commands->nextPollCommand(); std::vector<unsigned char>::iterator it;
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::string busCommand(A.getOptVal<const char*>("address")); for (int i = 0; i < 2; i++) {
busCommand += m_commands->getBusCommand(index); bool found = false;
std::transform(busCommand.begin(), busCommand.end(), busCommand.begin(), tolower); unsigned char mm = m_sstr[i];
BusMessage* message = new BusMessage(busCommand, true, false); if (i == 0) {
L.log(bus, trace, " msg: %s", busCommand.c_str()); 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; return RESULT_OK;
} }
void BusLoop::collectSlave() void BusLoop::addPollMessage()
{ {
std::vector<unsigned char>::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++) { std::string busCommand(A.getOptVal<const char*>("address"));
bool found = false; busCommand += m_commands->getBusCommand(index);
unsigned char mm = m_sstr[i]; std::transform(busCommand.begin(), busCommand.end(), busCommand.begin(), tolower);
if (i == 0) { BusMessage* message = new BusMessage(busCommand, true, false);
if (mm == 0xFF) L.log(bus, trace, " msg: %s", busCommand.c_str());
mm = 0x04;
else
mm += 0x05;
}
for (it = m_slave.begin(); it != m_slave.end(); it++) addMessage(message);
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());
}
} }
} }
+220 -18
View File
@@ -30,79 +30,200 @@
/** the maximum time [us] allowed for retrieving a byte from an addressed slave */ /** the maximum time [us] allowed for retrieving a byte from an addressed slave */
#define RECV_TIMEOUT 10000 #define RECV_TIMEOUT 10000
/** possible command types */
enum CommandType { invalid, broadcast, masterMaster, masterSlave }; enum CommandType { invalid, broadcast, masterMaster, masterSlave };
/**
* @brief class for data/message transfer between baseloop and busloop.
*/
class BusMessage class BusMessage
{ {
public: 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(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; } 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; } SymbolString getCommand() const { return m_command; }
/**
* @brief get the result string.
* @return the result string.
*/
SymbolString getResult() const { return m_result; } 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) void setResult(const SymbolString result, const int resultCode)
{ m_result = result; m_resultCode = 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(); 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 void waitSignal() { pthread_cond_wait(&m_cond, &m_mutex); } // TODO timeout
/**
* @brief send notification.
*/
void sendSignal() { pthread_cond_signal(&m_cond); } void sendSignal() { pthread_cond_signal(&m_cond); }
private: private:
/** the command type */
CommandType m_type; CommandType m_type;
/** true if message is of type polling */
bool m_poll; bool m_poll;
/** true if message is of type scanning */
bool m_scan; bool m_scan;
/** the command string (master data) */
SymbolString m_command; SymbolString m_command;
/** the result string (slave data) */
SymbolString m_result; SymbolString m_result;
/** the result code of result string */
int m_resultCode; int m_resultCode;
/** mutex variable for exclusive lock */
pthread_mutex_t m_mutex; pthread_mutex_t m_mutex;
/** condition variable for exclusive lock */
pthread_cond_t m_cond; pthread_cond_t m_cond;
}; };
/**
* @brief class busloop which handle all bus activities.
*/
class BusLoop : public Thread class BusLoop : public Thread
{ {
public: public:
/**
* @brief create a busloop instance and set the commands instance.
* @param commands the commands instance.
*/
BusLoop(Commands* commands); BusLoop(Commands* commands);
/**
* @brief destructor.
*/
~BusLoop(); ~BusLoop();
/**
* @brief endless loop for busloop instance.
* @return void pointer.
*/
void* run(); 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); } 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; } 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; } 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 ; } void raw() { m_logRawData == true ? m_logRawData = false : m_logRawData = true ; }
/** /**
* @brief set the name of dump file. * @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; } void setDumpFile(const std::string& dumpFile) { m_dumpFile = dumpFile; }
/** /**
* @brief set the max size of dump file. * @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; } 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 ; } void dump() { m_dumping == true ? m_dumping = false : m_dumping = true ; }
private: private:
/** the commands instance */
Commands* m_commands; Commands* m_commands;
/** the port instance which control the ebus device */
Port* m_port; Port* m_port;
/** the name of dump file*/ /** the name of dump file*/
@@ -111,28 +232,54 @@ private:
/** max. size of dump file */ /** max. size of dump file */
long m_dumpSize; long m_dumpSize;
/** true if dumping of raw bytes to file is enabled */
bool m_dumping; bool m_dumping;
/** true if logging of raw bytes is enabled */
bool m_logRawData; 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; 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; bool m_priorRetry;
/** queue for bus messages */
WQueue<BusMessage*> m_busQueue; WQueue<BusMessage*> m_busQueue;
/** string for cycle bus data */
SymbolString m_sstr; SymbolString m_sstr;
double m_pollInterval; /** number of send retries for one bus command */
long m_recvTimeout;
int m_sendRetries; int m_sendRetries;
/** number of lock retries (acquire bus) for one bus command */
int m_lockRetries; int m_lockRetries;
/** time for receiving answer from slave [us] */
long m_recvTimeout;
/** waiting time for bus acquire [us] */
long m_acquireTime; long m_acquireTime;
/** time between to polling commands [s] */
double m_pollInterval;
/** vector with collected slave addresses */
std::vector<unsigned char> m_slave; std::vector<unsigned char> m_slave;
/** true if bus scanning for collected slave addresses is active */
bool m_scan; bool m_scan;
/** true if bus scanning for all slave addresses is active */
bool m_scanFull; bool m_scanFull;
/** internal index do get next scan command */
size_t m_scanIndex; size_t m_scanIndex;
/** /**
@@ -142,16 +289,71 @@ private:
*/ */
int writeDumpFile(const char* byte); 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(); 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); void collectCycData(const int numRecv);
/**
* @brief the analyzing of collected bytes. collecting of slave address will be triggered.
*/
void analyseCycData(); void analyseCycData();
void addPollMessage();
int acquireBus(); /**
BusMessage* sendCommand(); * @brief determine and collect slave addresses.
int sendByte(const unsigned char sendByte); */
int recvSlaveAck(unsigned char& recvByte);
int recvSlaveData(SymbolString& result);
void collectSlave(); 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(); void addScanMessage();
}; };
+2 -2
View File
@@ -140,7 +140,7 @@ public:
void* run(); void* run();
/** /**
* @brief closs active connection. * @brief close active connection.
*/ */
void stop() const { m_notify.notify(); } void stop() const { m_notify.notify(); }
@@ -185,7 +185,7 @@ class Network : public Thread
public: 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 local true to accept connections only for local host.
* @param netQueue the remote queue for network messages. * @param netQueue the remote queue for network messages.
*/ */