added polling by priority

This commit is contained in:
john30
2014-12-07 14:49:44 +01:00
parent a8c1343218
commit 1a138dfe1c
4 changed files with 175 additions and 57 deletions
Regular → Executable
+16 -17
View File
@@ -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;
+3
View File
@@ -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
View File
@@ -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
View File
@@ -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;