reduced DataField::read() and ::write() to a single SymbolString, adjusted BusHandler accordingly, fix for BusRequest::notify, added define for and corrected send timeout, added syn after failed send, fixed cleanup, reduced logging

This commit is contained in:
john30
2014-12-06 16:54:32 +01:00
parent b0749c8662
commit c4812bd16c
2 changed files with 40 additions and 26 deletions
+34 -24
View File
@@ -97,6 +97,7 @@ void BusRequest::notify(result_t result)
m_result = result; m_result = result;
m_finished = true; m_finished = true;
pthread_cond_signal(&m_cond);
pthread_mutex_unlock(&m_mutex); pthread_mutex_unlock(&m_mutex);
} }
@@ -134,8 +135,6 @@ void BusHandler::run()
} while (isRunning() == true); } while (isRunning() == true);
} }
#define RECV_TIMEOUT 4500
result_t BusHandler::handleSymbol() result_t BusHandler::handleSymbol()
{ {
long timeout = SYN_TIMEOUT; long timeout = SYN_TIMEOUT;
@@ -187,7 +186,7 @@ result_t BusHandler::handleSymbol()
// send symbol if necessary // send symbol if necessary
if (sending == true) { if (sending == true) {
if (m_port->send(&sendSymbol, 1) == 1) if (m_port->send(&sendSymbol, 1) == 1)
timeout = RECV_TIMEOUT; timeout = SEND_TIMEOUT;
else { else {
sending = false; sending = false;
timeout = 0; timeout = 0;
@@ -198,12 +197,18 @@ result_t BusHandler::handleSymbol()
// receive next symbol (optionally check reception of sent symbol) // receive next symbol (optionally check reception of sent symbol)
ssize_t count = m_port->recv(timeout, 1); ssize_t count = m_port->recv(timeout, 1);
if (count < 0) if (count <= 0 && m_state == bs_ready && sending == false)
return RESULT_OK; // TODO keep "no signal" within auto-syn state
if (count < 0) { // count < 0 is a RESULT_ERR_ code
if (m_request != NULL)
return setState(bs_sendSyn, count);
return setState(bs_skip, count); return setState(bs_skip, count);
}
if (count == 0) { if (count == 0) {
if (m_state == bs_ready) if (m_request != NULL)
return RESULT_OK; // TODO keep "no signal" within auto-syn state return setState(bs_sendSyn, RESULT_ERR_TIMEOUT);
return setState(bs_skip, RESULT_ERR_TIMEOUT); return setState(bs_skip, RESULT_ERR_TIMEOUT);
} }
@@ -221,18 +226,19 @@ result_t BusHandler::handleSymbol()
case bs_ready: case bs_ready:
if (m_request != NULL && sending == true) { if (m_request != NULL && sending == true) {
if (m_requests.remove(m_request) == false) {
// request already timed out
m_request = NULL;
return setState(bs_sendSyn, RESULT_ERR_TIMEOUT);
}
// check arbitration // check arbitration
if (recvSymbol == sendSymbol) { // arbitration successful if (recvSymbol == sendSymbol) { // arbitration successful
if (m_requests.remove(m_request) == false) {
// request already timed out
m_request = NULL;
return setState(bs_sendSyn, RESULT_ERR_TIMEOUT);
}
m_nextSendPos = 1; m_nextSendPos = 1;
m_repeat = false; m_repeat = false;
return setState(bs_sendCmd, RESULT_OK); return setState(bs_sendCmd, RESULT_OK);
} }
// arbitration lost // arbitration lost
m_request = NULL;
setState(m_state, RESULT_ERR_BUS_LOST); // try again later setState(m_state, RESULT_ERR_BUS_LOST); // try again later
} }
result = m_command.push_back(recvSymbol, false); // expect no escaping for master address result = m_command.push_back(recvSymbol, false); // expect no escaping for master address
@@ -411,18 +417,21 @@ result_t BusHandler::setState(BusState state, result_t result)
if (result < RESULT_OK || (result != RESULT_OK && state == bs_skip)) if (result < RESULT_OK || (result != RESULT_OK && state == bs_skip))
L.log(bus, error, " %s during %s, switching to %s", getResultCode(result), getStateCode(m_state), getStateCode(state)); L.log(bus, error, " %s during %s, switching to %s", getResultCode(result), getStateCode(m_state), getStateCode(state));
else if (m_request != NULL || state == bs_sendCmd || state==bs_sendResAck || state==bs_sendSyn)
m_state = state; L.log(bus, trace, " switching from %s to %s", getStateCode(m_state), getStateCode(state));
if (m_request != NULL) { if (m_request != NULL) {
if (state == bs_sendSyn) { if (state == bs_sendSyn) {
// L.log(bus, trace, "notify request (syn): %s", getResultCode(result));
m_request->m_slave = m_response; // TODO nicer m_request->m_slave = m_response; // TODO nicer
m_request->notify(result); m_request->notify(result);
m_request = NULL; m_request = NULL;
} else if (result != RESULT_OK) { } else if (result != RESULT_OK) {
// L.log(bus, trace, "notify request: %s", getResultCode(result));
m_request->notify(result); m_request->notify(result);
m_request = NULL; m_request = NULL;
} }
} }
m_state = state;
if (state == bs_ready || state == bs_skip) { if (state == bs_ready || state == bs_skip) {
m_command.clear(); m_command.clear();
@@ -437,6 +446,18 @@ result_t BusHandler::setState(BusState state, result_t result)
void BusHandler::transferCompleted(TransferType type) void BusHandler::transferCompleted(TransferType type)
{ {
Message* msg = m_messages->find(m_command);
if (msg != NULL) {
ostringstream output;
result_t result = msg->decode(pt_masterData, m_command, output);
if (result == RESULT_OK)
result = msg->decode(pt_slaveData, m_response, output);
if (result != RESULT_OK)
L.log(bus, error, "unable to parse %s %s from %s / %s: %s", msg->getClass().c_str(), msg->getName().c_str(), m_command.getDataStr().c_str(), m_response.getDataStr().c_str(), getResultCode(result));
else
L.log(bus, trace, "%s %s: %s", msg->getClass().c_str(), msg->getName().c_str(), output.str().c_str());
return;
}
switch (type) switch (type)
{ {
case tt_broadcast: case tt_broadcast:
@@ -448,16 +469,5 @@ void BusHandler::transferCompleted(TransferType type)
case tt_masterSlave: case tt_masterSlave:
L.log(bus, trace, "received master %s, slave %s", m_command.getDataStr().c_str(), m_response.getDataStr().c_str()); L.log(bus, trace, "received master %s, slave %s", m_command.getDataStr().c_str(), m_response.getDataStr().c_str());
break; break;
default:
return;
}
Message* msg = m_messages->find(m_command);
if (msg != NULL) {
ostringstream output;
result_t result = msg->decode(m_command, m_response, output);
if (result != RESULT_OK)
L.log(bus, error, "unable to parse %s %s from %s / %s: %s", msg->getClass().c_str(), msg->getName().c_str(), m_command.getDataStr().c_str(), m_response.getDataStr().c_str(), getResultCode(result));
else
L.log(bus, trace, "%s %s: %s", msg->getClass().c_str(), msg->getName().c_str(), output.str().c_str());
} }
} }
+6 -2
View File
@@ -34,10 +34,14 @@
using namespace std; using namespace std;
/** the maximum allowed time [us] for retrieval of a single symbol from an addressed slave. */ /** the maximum allowed time [us] for retrieving a symbol from an addressed slave. */
#define SLAVE_RECV_TIMEOUT 10000 #define SLAVE_RECV_TIMEOUT 10000
/** the maximum allowed time [us] for retrieval of an AUTO-SYN symbol (should be generated in <45ms). */ /** the maximum allowed time [us] for retrieving the AUTO-SYN symbol (should be generated in <45ms). */
#define SYN_TIMEOUT 50000 #define SYN_TIMEOUT 50000
/** the maximum duration [us] of a single symbol. */
#define SYMBOL_DURATION 5100
/** the maximum allowed time [us] for retrieving back a sent symbol. */
#define SEND_TIMEOUT 6000
/** the possible bus states. */ /** the possible bus states. */
enum BusState { enum BusState {