added polling by priority
This commit is contained in:
Regular → Executable
+16
-17
@@ -47,9 +47,9 @@ BaseLoop::BaseLoop()
|
||||
else
|
||||
L.log(bas, error, "error reading config files: %s", getResultCode(result));
|
||||
|
||||
/*L.log(bas, event, "commands DB: %d ", m_commands->sizeCmdDB());
|
||||
L.log(bas, event, " cycle DB: %d ", m_commands->sizeCycDB());
|
||||
L.log(bas, event, " polling DB: %d ", m_commands->sizePollDB());*/
|
||||
L.log(bas, event, "commands DB: %d ", m_messages->size());
|
||||
L.log(bas, event, " cycle DB: %d ", m_messages->size(true));
|
||||
L.log(bas, event, " polling DB: %d ", m_messages->sizePoll());
|
||||
|
||||
m_ownAddress = A.getOptVal<int>("address") & 0xff;
|
||||
const bool answer = A.getOptVal<bool>("answer");
|
||||
@@ -65,6 +65,12 @@ BaseLoop::BaseLoop()
|
||||
const unsigned int busAcquireWaitTime = A.getOptVal<unsigned int>("acquiretimeout");
|
||||
const unsigned int slaveRecvTimeout = A.getOptVal<unsigned int>("recvtimeout");
|
||||
const unsigned int lockCount = A.getOptVal<unsigned int>("lockcounter");
|
||||
int pollInterval = A.getOptVal<unsigned int>("pollinterval");
|
||||
if (pollInterval <= 0) {
|
||||
m_pollActive = false;
|
||||
pollInterval = 0;
|
||||
} else
|
||||
m_pollActive = true;
|
||||
|
||||
// create Port
|
||||
m_port = new Port(A.getOptVal<const char*>("device"), A.getOptVal<bool>("nodevicecheck"), logRaw, &BaseLoop::logRaw, dumpRaw, dumpRawFile, dumpRawMaxSize);
|
||||
@@ -75,10 +81,10 @@ BaseLoop::BaseLoop()
|
||||
|
||||
// create BusHandler
|
||||
m_busHandler = new BusHandler(m_port, m_messages,
|
||||
answer ? m_ownAddress : SYN, answer ? (m_ownAddress+5)&0xff : SYN,
|
||||
m_ownAddress, answer,
|
||||
busLostRetries, failedSendRetries,
|
||||
busAcquireWaitTime, slaveRecvTimeout,
|
||||
lockCount);
|
||||
lockCount, pollInterval);
|
||||
m_busHandler->start("bushandler");
|
||||
|
||||
// create network
|
||||
@@ -221,23 +227,16 @@ string BaseLoop::decodeMessage(const string& data)
|
||||
|
||||
if (message != NULL) {
|
||||
|
||||
/*if (message->getPollPriority() > 0)
|
||||
if (m_pollActive == true && message->getPollPriority() > 0) {
|
||||
// get polldata
|
||||
polldata = m_commands->getPollData(index);
|
||||
if (polldata != "") {
|
||||
// decode data
|
||||
Command* command = new Command(index, (*m_commands)[index], polldata);
|
||||
|
||||
// return result
|
||||
result << command->calcResult(cmd);
|
||||
|
||||
delete command;
|
||||
token = message->getLastValue();
|
||||
if (token.empty() == false) {
|
||||
result << token;
|
||||
} else {
|
||||
result << "no data stored";
|
||||
}
|
||||
|
||||
break;
|
||||
}*/
|
||||
}
|
||||
|
||||
SymbolString master;
|
||||
istringstream input;
|
||||
|
||||
@@ -96,6 +96,9 @@ private:
|
||||
/** the own master address for sending on the bus. */
|
||||
unsigned char m_ownAddress;
|
||||
|
||||
/** whether polling the messages is active. */
|
||||
bool m_pollActive;
|
||||
|
||||
/** the @a Port instance. */
|
||||
Port* m_port;
|
||||
|
||||
|
||||
Regular → Executable
+50
-7
@@ -58,20 +58,41 @@ const char* getStateCode(BusState state) {
|
||||
}
|
||||
|
||||
|
||||
BusRequest::BusRequest(SymbolString& master, SymbolString& slave)
|
||||
: m_master(master), m_slave(slave), m_finished(false), m_result(RESULT_SYN)
|
||||
result_t PollRequest::prepare(unsigned char ownMasterAddress)
|
||||
{
|
||||
istringstream input;
|
||||
result_t result = m_message->prepareMaster(ownMasterAddress, m_master, input);
|
||||
if (result == RESULT_OK)
|
||||
L.log(bus, event, " poll msg: %s", m_master.getDataStr().c_str());
|
||||
return result;
|
||||
}
|
||||
|
||||
void PollRequest::notify(result_t result)
|
||||
{
|
||||
ostringstream output;
|
||||
if (result == RESULT_OK) {
|
||||
result = m_message->decode(pt_slaveData, m_slave, output); // decode data
|
||||
}
|
||||
if (result != RESULT_OK)
|
||||
L.log(bus, error, "poll %s failed: %s", m_message->getName().c_str(), getResultCode(result));
|
||||
else
|
||||
L.log(bus, event, "poll %s: %s", m_message->getName().c_str(), output.str().c_str());
|
||||
}
|
||||
|
||||
ActiveBusRequest::ActiveBusRequest(SymbolString& master, SymbolString& slave)
|
||||
: BusRequest(master, slave, false), m_finished(false), m_result(RESULT_SYN)
|
||||
{
|
||||
pthread_mutex_init(&m_mutex, NULL);
|
||||
pthread_cond_init(&m_cond, NULL);
|
||||
}
|
||||
|
||||
BusRequest::~BusRequest()
|
||||
ActiveBusRequest::~ActiveBusRequest()
|
||||
{
|
||||
pthread_mutex_destroy(&m_mutex);
|
||||
pthread_cond_destroy(&m_cond);
|
||||
}
|
||||
|
||||
bool BusRequest::wait(int timeout)
|
||||
bool ActiveBusRequest::wait(int timeout)
|
||||
{
|
||||
m_finished = false;
|
||||
m_result = RESULT_SYN;
|
||||
@@ -93,7 +114,7 @@ bool BusRequest::wait(int timeout)
|
||||
return result == 0;
|
||||
}
|
||||
|
||||
void BusRequest::notify(result_t result)
|
||||
void ActiveBusRequest::notify(result_t result)
|
||||
{
|
||||
pthread_mutex_lock(&m_mutex);
|
||||
|
||||
@@ -108,7 +129,7 @@ void BusRequest::notify(result_t result)
|
||||
result_t BusHandler::sendAndWait(SymbolString& master, SymbolString& slave)
|
||||
{
|
||||
result_t result = RESULT_SYN;
|
||||
BusRequest* request = new BusRequest(master, slave);
|
||||
ActiveBusRequest* request = new ActiveBusRequest(master, slave);
|
||||
|
||||
for (int sendRetries=m_failedSendRetries+1, lostRetries=m_busLostRetries+1; sendRetries>=0; sendRetries--) {
|
||||
m_requests.add(request);
|
||||
@@ -172,6 +193,26 @@ result_t BusHandler::handleSymbol()
|
||||
setState(bs_ready, RESULT_ERR_TIMEOUT); // just to be sure an old BusRequest is cleaned up
|
||||
if (m_remainLockCount == 0) {
|
||||
m_request = m_requests.next(false);
|
||||
if (m_request == NULL && m_pollInterval > 0) { // check for poll/scan
|
||||
time_t now;
|
||||
time(&now);
|
||||
if (m_lastPoll == 0 || difftime(now, m_lastPoll) > m_pollInterval) {
|
||||
Message* message = m_messages->getNextPoll();
|
||||
if (message != NULL) {
|
||||
m_lastPoll = now;
|
||||
PollRequest* request = new PollRequest(m_response, message);
|
||||
result_t ret = request->prepare(m_ownMasterAddress);
|
||||
if (ret != RESULT_OK) {
|
||||
L.log(bus, error, " prepare poll message: %s", getResultCode(ret));
|
||||
delete request;
|
||||
}
|
||||
else {
|
||||
m_request = request;
|
||||
m_requests.add(request);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (m_request != NULL) { // initiate arbitration
|
||||
sendSymbol = m_request->m_master[0];
|
||||
sending = true;
|
||||
@@ -435,8 +476,10 @@ result_t BusHandler::setState(BusState state, result_t result, bool firstRepetit
|
||||
if (m_request != NULL) {
|
||||
if (state == bs_sendSyn || (result != RESULT_OK && firstRepetition == false)) {
|
||||
L.log(bus, debug, "notify request: %s", getResultCode(result));
|
||||
m_request->m_slave = m_response; // TODO nicer
|
||||
m_request->m_slave = SymbolString(m_response, false, false);
|
||||
m_request->notify(result);
|
||||
if (m_request->m_isPoll == true)
|
||||
delete m_request;
|
||||
m_request = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
+106
-33
@@ -58,23 +58,10 @@ enum BusState {
|
||||
bs_sendSyn, // send SYN for completed transfer [active set+get]
|
||||
};
|
||||
|
||||
/** the possible combinations of participants in a single message exchange. */
|
||||
enum MessageDirection {
|
||||
md_thisToAll, // message from us to all (broadcast)
|
||||
md_thisToMaster, // message from us to another master
|
||||
md_thisToSlave, // message from us to another slave
|
||||
md_otherToAll, // message from a master (other than us) to all (broadcast)
|
||||
md_otherToMaster, // message from a master (other than us) to another master (other than us)
|
||||
md_otherToSlave, // message from a master (other than us) to another slave (other than us)
|
||||
md_otherToThisMaster, // message from a master (other than us) to us (as master)
|
||||
md_otherToThisSlave, // message from a master (other than us) to us (as slave)
|
||||
md_undefined,
|
||||
};
|
||||
|
||||
class BusHandler;
|
||||
|
||||
/**
|
||||
* @brief Handles input from and output to the bus with respect to the ebus protocol.
|
||||
* @brief Generic request for sending to and receiving from the bus.
|
||||
*/
|
||||
class BusRequest
|
||||
{
|
||||
@@ -85,13 +72,96 @@ public:
|
||||
* @brief Constructor.
|
||||
* @param master the master data @a SymbolString to send.
|
||||
* @param slave the slave data @a SymbolString received.
|
||||
* @param isPoll whether this is a poll request.
|
||||
*/
|
||||
BusRequest(SymbolString& master, SymbolString& slave);
|
||||
BusRequest(SymbolString& master, SymbolString& slave, bool isPoll)
|
||||
: m_master(master), m_slave(slave), m_isPoll(isPoll) {}
|
||||
|
||||
/**
|
||||
* @brief Destructor.
|
||||
*/
|
||||
virtual ~BusRequest();
|
||||
virtual ~BusRequest() {}
|
||||
|
||||
/**
|
||||
* @brief Notify all waiting threads.
|
||||
*/
|
||||
virtual void notify(result_t result) = 0;
|
||||
|
||||
protected:
|
||||
|
||||
/** the master data @a SymbolString to send. */
|
||||
SymbolString& m_master;
|
||||
|
||||
/** the slave data @a SymbolString received. */
|
||||
SymbolString& m_slave;
|
||||
|
||||
/** whether this is a poll request. */
|
||||
bool m_isPoll;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief A poll @a BusRequest handled by @a BusHandler itself.
|
||||
*/
|
||||
class PollRequest : public BusRequest
|
||||
{
|
||||
friend class BusHandler;
|
||||
public:
|
||||
|
||||
/**
|
||||
* @brief Constructor.
|
||||
* @param slave the slave data @a SymbolString received.
|
||||
* @param message the associated @a Message.
|
||||
*/
|
||||
PollRequest(SymbolString& slave, Message* message)
|
||||
: BusRequest(m_master, slave, true), m_message(message) {}
|
||||
|
||||
/**
|
||||
* @brief Destructor.
|
||||
*/
|
||||
virtual ~PollRequest() {}
|
||||
|
||||
/**
|
||||
* @brief Prepare the master data.
|
||||
* @param masterAddress the master bus address to use.
|
||||
* @return the result code.
|
||||
*/
|
||||
result_t prepare(unsigned char masterAddress);
|
||||
|
||||
// @copydoc
|
||||
virtual void notify(result_t result);
|
||||
|
||||
private:
|
||||
|
||||
/** the master data @a SymbolString. */
|
||||
SymbolString m_master;
|
||||
|
||||
/** the associated @a Message. */
|
||||
Message* m_message;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief An active @a BusRequest that can be waited for.
|
||||
*/
|
||||
class ActiveBusRequest : public BusRequest
|
||||
{
|
||||
friend class BusHandler;
|
||||
public:
|
||||
|
||||
/**
|
||||
* @brief Constructor.
|
||||
* @param master the master data @a SymbolString to send.
|
||||
* @param slave the slave data @a SymbolString received.
|
||||
*/
|
||||
ActiveBusRequest(SymbolString& master, SymbolString& slave);
|
||||
|
||||
/**
|
||||
* @brief Destructor.
|
||||
*/
|
||||
virtual ~ActiveBusRequest();
|
||||
|
||||
/**
|
||||
* @brief Wait for notification.
|
||||
@@ -100,19 +170,11 @@ public:
|
||||
*/
|
||||
bool wait(int timeout);
|
||||
|
||||
/**
|
||||
* @brief Notify all waiting threads.
|
||||
*/
|
||||
void notify(result_t result);
|
||||
// @copydoc
|
||||
virtual void notify(result_t result);
|
||||
|
||||
private:
|
||||
|
||||
/** the master data @a SymbolString to send. */
|
||||
SymbolString& m_master;
|
||||
|
||||
/** the slave data @a SymbolString received. */
|
||||
SymbolString& m_slave;
|
||||
|
||||
/** true once the request is finished. */
|
||||
bool m_finished;
|
||||
|
||||
@@ -139,24 +201,26 @@ public:
|
||||
* @brief Construct a new instance.
|
||||
* @param port the @a Port instance for accessing the bus.
|
||||
* @param messages the @a MessageMap instance with all known @a Message instances.
|
||||
* @param ownMasterAddress the own master address to react on master-master messages, or @a SYN to ignore.
|
||||
* @param ownSlaveAddress the own slave address to react on master-slave messages, or @a SYN to ignore.
|
||||
* @param ownAddress the own master address.
|
||||
* @param answer whether to answer queries for the own master/slave address.
|
||||
* @param busLostRetries the number of times a send is repeated due to lost arbitration.
|
||||
* @param failedSendRetries the number of times a failed send is repeated (other than lost arbitration).
|
||||
* @param slaveRecvTimeout the maximum time in microseconds an addressed slave is expected to acknowledge.
|
||||
* @param busAcquireTimeout the maximum time in microseconds for bus acquisition.
|
||||
* @param lockCount the number of AUTO-SYN symbols before sending is allowed after lost arbitration.
|
||||
* @param pollInterval the interval in seconds in which poll messages are cycled, or 0 if disabled.
|
||||
*/
|
||||
BusHandler(Port* port, MessageMap* messages,
|
||||
const unsigned char ownMasterAddress, const unsigned char ownSlaveAddress,
|
||||
const unsigned char ownAddress, const bool answer,
|
||||
const unsigned int busLostRetries, const unsigned int failedSendRetries,
|
||||
const unsigned int busAcquireTimeout, const unsigned int slaveRecvTimeout,
|
||||
const unsigned int lockCount)
|
||||
const unsigned int lockCount, const unsigned int pollInterval)
|
||||
: m_port(port), m_messages(messages),
|
||||
m_ownMasterAddress(ownMasterAddress), m_ownSlaveAddress(ownSlaveAddress),
|
||||
m_ownMasterAddress(ownAddress), m_ownSlaveAddress((ownAddress+5)&0xff), m_answer(answer),
|
||||
m_busLostRetries(busLostRetries), m_failedSendRetries(failedSendRetries),
|
||||
m_busAcquireTimeout(busAcquireTimeout), m_slaveRecvTimeout(slaveRecvTimeout),
|
||||
m_lockCount(lockCount), m_remainLockCount(lockCount),
|
||||
m_pollInterval(pollInterval), m_lastPoll(0),
|
||||
m_request(NULL), m_nextSendPos(0),
|
||||
m_state(bs_skip), m_repeat(false),
|
||||
m_commandCrcValid(false), m_responseCrcValid(false) {}
|
||||
@@ -213,12 +277,15 @@ private:
|
||||
/** the @a MessageMap instance with all known @a Message instances. */
|
||||
MessageMap* m_messages;
|
||||
|
||||
/** the own master address to react on master-master messages, or @a SYN to ignore. */
|
||||
/** the own master address. */
|
||||
const unsigned char m_ownMasterAddress;
|
||||
|
||||
/** the own slave address to react on master-slave messages, or @a SYN to ignore. */
|
||||
/** the own slave address. */
|
||||
const unsigned char m_ownSlaveAddress;
|
||||
|
||||
/** whether to answer queries for the own master/slave address. */
|
||||
const bool m_answer;
|
||||
|
||||
/** the number of times a send is repeated due to lost arbitration. */
|
||||
const unsigned int m_busLostRetries;
|
||||
|
||||
@@ -237,6 +304,12 @@ private:
|
||||
/** the remaining number of AUTO-SYN symbols before sending is allowed again. */
|
||||
unsigned int m_remainLockCount;
|
||||
|
||||
/** the interval in seconds in which poll messages are cycled, or 0 if disabled. */
|
||||
const unsigned int m_pollInterval;
|
||||
|
||||
/** the time of the last poll, or 0 for never. */
|
||||
time_t m_lastPoll;
|
||||
|
||||
/** the queue of @a BusRequests that shall be handled. */
|
||||
WQueue<BusRequest*> m_requests;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user