1
0
mirror of https://github.com/DCC-EX/CommandStation-EX.git synced 2025-04-21 04:21:20 +02:00

update for better task handeling, untested

This commit is contained in:
travis-farmer 2024-12-26 17:21:02 -05:00
parent 51058a66f3
commit 25c01e0ca4
No known key found for this signature in database
GPG Key ID: 0BC296791D14CB35
2 changed files with 162 additions and 138 deletions

View File

@ -90,9 +90,31 @@ void EXIO485::_loop(unsigned long currentMicros) {
DIAG(F("Polling"));
}
if ( hasTasks() && _currentMicros - _cycleStartTimeA >= _cycleTime){
if ( hasTasks()){
_cycleStartTimeA = _currentMicros;
Task* currentTask = getTaskById(getNextTaskId());
if (CurrentTaskID == -1) {
CurrentTaskID = getNextTaskId();
}
Task* currentTask = getTaskById(CurrentTaskID);
if (_currentMicros - _cycleStartTime > 1000000UL) { // timout every 1000ms
_cycleStartTime = _currentMicros;// reset timout
if (taskResendCount >= 2) { // max resends
markTaskCompleted(CurrentTaskID); // kill task and move on
CurrentTaskID = getNextTaskId(); // move on
taskResendCount = 0;
DIAG(F("Move on"));
} else {
currentTask->rxMode = false; // resend
taskResendCount++;
DIAG(F("Resend"));
}
}
if (!currentTask->rxMode) { // Check if a task was found
currentTask->crcPassFail = 0;
uint16_t response_crc = crc16((uint8_t*)currentTask->commandArray, currentTask->byteCount-1);
@ -113,154 +135,154 @@ void EXIO485::_loop(unsigned long currentMicros) {
// delete task command after sending, for now
currentTask->rxMode = true;
DIAG(F("Task"));
markTaskCompleted(currentTask->taskID);
}
}
if ( _serial->available()) {
uint16_t calculated_crc;
int byteCount = 100;
int curByte = _serial->read();
if (curByte == 0xFE && flagStart == false) flagStart = true;
else if ( curByte == 0xFE && flagStart == true) {
flagProc = false;
byteCounter = 0;
flagStarted = true;
flagStart = false;
flagEnded = false;
rxStart = true;
rxEnd = false;
crcPass = false;
memset(received_data, 0, ARRAY_SIZE);
}else if (flagStarted) {
crc[0] = curByte;
byteCounter++;
flagStarted = false;
} else if (byteCounter == 1) {
crc[1] = curByte;
received_crc = (crc[0] << 8) | crc[1];
byteCounter++;
} else if (byteCounter == 2) {
byteCount = curByte;
byteCounter++;
} else if (flagEnded == false && byteCounter >= 3) {
received_data[byteCounter-3] = curByte;
byteCounter++;
}
if (curByte == 0xFD && flagEnd == false) flagEnd = true;
else if ( curByte == 0xFD && flagEnd == true) {
flagEnded = true;
flagEnd = false;
rxEnd = true;
byteCount = byteCounter;
byteCounter = 0;
}
if (flagEnded) {
calculated_crc = crc16((uint8_t*)received_data, byteCount-6);
if (received_crc == calculated_crc) {
crcPass = true;
}
flagEnded = false;
}
// Check CRC validity
if (crcPass) {
// Data received successfully, process it (e.g., print)
int nodeTo = received_data[0];
if (nodeTo == 0) { // for master. master does not retransmit, or a loop will runaway.
flagProc = true;
}
}
} else {
if ( _serial->available()) {
uint16_t calculated_crc;
int byteCount = 100;
int curByte = _serial->read();
if (curByte == 0xFE && flagStart == false) flagStart = true;
else if ( curByte == 0xFE && flagStart == true) {
flagProc = false;
byteCounter = 0;
flagStarted = true;
flagStart = false;
flagEnded = false;
rxStart = true;
rxEnd = false;
crcPass = false;
memset(received_data, 0, ARRAY_SIZE);
}else if (flagStarted) {
crc[0] = curByte;
byteCounter++;
flagStarted = false;
} else if (byteCounter == 1) {
crc[1] = curByte;
received_crc = (crc[0] << 8) | crc[1];
byteCounter++;
} else if (byteCounter == 2) {
byteCount = curByte;
byteCounter++;
} else if (flagEnded == false && byteCounter >= 3) {
received_data[byteCounter-3] = curByte;
byteCounter++;
}
if (curByte == 0xFD && flagEnd == false) flagEnd = true;
else if ( curByte == 0xFD && flagEnd == true) {
flagEnded = true;
flagEnd = false;
rxEnd = true;
byteCount = byteCounter;
byteCounter = 0;
}
if (flagEnded) {
calculated_crc = crc16((uint8_t*)received_data, byteCount-6);
if (received_crc == calculated_crc) {
crcPass = true;
}
flagEnded = false;
if (flagProc) {
int nodeFr = received_data[1];
EXIO485node *node = findNode(nodeFr);
int AddrCode = received_data[2];
switch (AddrCode) {
case EXIOPINS:
{node->setnumDigitalPins(received_data[3]);
node->setnumAnalogPins(received_data[4]);
// See if we already have suitable buffers assigned
if (node->getnumDigialPins()>0) {
size_t digitalBytesNeeded = (node->getnumDigialPins() + 7) / 8;
if (node->getdigitalPinBytes() < digitalBytesNeeded) {
// Not enough space, free any existing buffer and allocate a new one
if (node->cleandigitalPinStates(digitalBytesNeeded)) {
node->setdigitalPinBytes(digitalBytesNeeded);
} else {
DIAG(F("EX-IOExpander485 node:%d ERROR alloc %d bytes"), nodeFr, digitalBytesNeeded);
node->setdigitalPinBytes(0);
}
}
}
// Check CRC validity
if (crcPass) {
// Data received successfully, process it (e.g., print)
int nodeTo = received_data[0];
if (nodeTo == 0) { // for master. master does not retransmit, or a loop will runaway.
flagProc = true;
}
if (node->getnumAnalogPins()>0) {
size_t analogueBytesNeeded = node->getnumAnalogPins() * 2;
if (node->getanalogPinBytes() < analogueBytesNeeded) {
// Free any existing buffers and allocate new ones.
}
if (flagProc) {
int nodeFr = received_data[1];
EXIO485node *node = findNode(nodeFr);
int AddrCode = received_data[2];
switch (AddrCode) {
case EXIOPINS:
{node->setnumDigitalPins(received_data[3]);
node->setnumAnalogPins(received_data[4]);
// See if we already have suitable buffers assigned
if (node->getnumDigialPins()>0) {
size_t digitalBytesNeeded = (node->getnumDigialPins() + 7) / 8;
if (node->getdigitalPinBytes() < digitalBytesNeeded) {
// Not enough space, free any existing buffer and allocate a new one
if (node->cleandigitalPinStates(digitalBytesNeeded)) {
node->setdigitalPinBytes(digitalBytesNeeded);
} else {
DIAG(F("EX-IOExpander485 node:%d ERROR alloc %d bytes"), nodeFr, digitalBytesNeeded);
node->setdigitalPinBytes(0);
}
}
}
if (node->cleanAnalogStates(analogueBytesNeeded)) {
node->setanalogPinBytes(analogueBytesNeeded);
} else {
DIAG(F("EX-IOExpander485 node:%d ERROR alloc analog pin bytes"), nodeFr);
node->setanalogPinBytes(0);
if (node->getnumAnalogPins()>0) {
size_t analogueBytesNeeded = node->getnumAnalogPins() * 2;
if (node->getanalogPinBytes() < analogueBytesNeeded) {
// Free any existing buffers and allocate new ones.
if (node->cleanAnalogStates(analogueBytesNeeded)) {
node->setanalogPinBytes(analogueBytesNeeded);
} else {
DIAG(F("EX-IOExpander485 node:%d ERROR alloc analog pin bytes"), nodeFr);
node->setanalogPinBytes(0);
}
}
}
markTaskCompleted(currentTask->taskID);
break;}
case EXIOINITA: {
for (int i = 0; i < node->getnumAnalogPins(); i++) {
node->setanalogPinMap(received_data[i+3], i);
}
markTaskCompleted(currentTask->taskID);
break;
}
case EXIOVER: {
node->setMajVer(received_data[3]);
node->setMinVer(received_data[4]);
node->setPatVer(received_data[5]);
DIAG(F("EX-IOExpander485: Found node %i v%i.%i.%i"),node->getNodeID(), node->getMajVer(), node->getMinVer(), node->getPatVer());
node->setInitialised();
markTaskCompleted(currentTask->taskID);
break;
}
case EXIORDY: {
markTaskCompleted(currentTask->taskID);
break;
}
case EXIOERR: {
markTaskCompleted(currentTask->taskID);
DIAG(F("EX-IOExplorer485: Some sort of error was received...")); // ;-)
break;
}
case EXIORDAN: {
for (int i = 0; i < node->_numAnaloguePins; i++) {
node->setanalogInputBuffer(received_data[i+3], i);
}
markTaskCompleted(currentTask->taskID);
break;
}
case EXIORDD: {
for (int i = 0; i < (node->_numDigitalPins+7)/8; i++) {
node->setdigitalInputStates(received_data[i+3], i);
}
markTaskCompleted(currentTask->taskID);
break;
}
break;}
case EXIOINITA: {
for (int i = 0; i < node->getnumAnalogPins(); i++) {
node->setanalogPinMap(received_data[i+3], i);
}
break;
}
case EXIOVER: {
node->setMajVer(received_data[3]);
node->setMinVer(received_data[4]);
node->setPatVer(received_data[5]);
DIAG(F("EX-IOExpander485: Found node %i v%i.%i.%i"),node->getNodeID(), node->getMajVer(), node->getMinVer(), node->getPatVer());
node->setInitialised();
break;
}
case EXIORDY: {
break;
}
case EXIOERR: {
DIAG(F("EX-IOExplorer485: Some sort of error was received...")); // ;-)
break;
}
case EXIORDAN: {
for (int i = 0; i < node->_numAnaloguePins; i++) {
node->setanalogInputBuffer(received_data[i+3], i);
}
break;
}
case EXIORDD: {
for (int i = 0; i < (node->_numDigitalPins+7)/8; i++) {
node->setdigitalInputStates(received_data[i+3], i);
}
break;
}
}
}
flagProc = false;
}
}
flagProc = false;
}
// temp debug
}
// Link to chain of EXIO485 instances, left over from EXIO485 template.

View File

@ -428,6 +428,8 @@ struct Task {
};
static const int MAX_TASKS = 50;
int taskIDCntr = 0;
int CurrentTaskID = -1;
int taskResendCount = 0;
Task taskBuffer[MAX_TASKS]; // Buffer to hold up to 100 tasks
int currentTaskIndex = 0;
void initTask() {