| Directory: | ./ |
|---|---|
| File: | pdserv-1.1.0/src/lib/Task.cpp |
| Date: | 2025-11-02 04:09:49 |
| Exec | Total | Coverage | |
|---|---|---|---|
| Lines: | 117 | 216 | 54.2% |
| Branches: | 38 | 105 | 36.2% |
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | /***************************************************************************** | ||
| 2 | * | ||
| 3 | * $Id$ | ||
| 4 | * | ||
| 5 | * Copyright 2010 Richard Hacker (lerichi at gmx dot net) | ||
| 6 | * | ||
| 7 | * This file is part of the pdserv library. | ||
| 8 | * | ||
| 9 | * The pdserv library is free software: you can redistribute it and/or modify | ||
| 10 | * it under the terms of the GNU Lesser General Public License as published | ||
| 11 | * by the Free Software Foundation, either version 3 of the License, or (at | ||
| 12 | * your option) any later version. | ||
| 13 | * | ||
| 14 | * The pdserv library is distributed in the hope that it will be useful, but | ||
| 15 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | ||
| 16 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public | ||
| 17 | * License for more details. | ||
| 18 | * | ||
| 19 | * You should have received a copy of the GNU Lesser General Public License | ||
| 20 | * along with the pdserv library. If not, see <http://www.gnu.org/licenses/>. | ||
| 21 | * | ||
| 22 | *****************************************************************************/ | ||
| 23 | |||
| 24 | #include "../Debug.h" | ||
| 25 | |||
| 26 | #include <algorithm> | ||
| 27 | #include <numeric> | ||
| 28 | |||
| 29 | #include "ShmemDataStructures.h" | ||
| 30 | #include "SessionTaskData.h" | ||
| 31 | #include "../SessionTask.h" | ||
| 32 | #include "Task.h" | ||
| 33 | #include "Signal.h" | ||
| 34 | #include "Pointer.h" | ||
| 35 | |||
| 36 | ///////////////////////////////////////////////////////////////////////////// | ||
| 37 | // Data structures used in Task | ||
| 38 | ///////////////////////////////////////////////////////////////////////////// | ||
| 39 | struct CopyList { | ||
| 40 | const Signal *signal; | ||
| 41 | const char *src; | ||
| 42 | size_t len; | ||
| 43 | }; | ||
| 44 | |||
| 45 | struct SignalList { | ||
| 46 | enum {Insert = 1, Remove} action; | ||
| 47 | unsigned int signalListId; | ||
| 48 | unsigned int signalPosition; | ||
| 49 | const Signal* signal; | ||
| 50 | }; | ||
| 51 | |||
| 52 | struct PollData { | ||
| 53 | unsigned int request, reply; | ||
| 54 | bool active; | ||
| 55 | struct timespec time; | ||
| 56 | unsigned int count; | ||
| 57 | unsigned int length; | ||
| 58 | const char *addr; | ||
| 59 | struct Data { | ||
| 60 | void *dest; | ||
| 61 | const Signal *signal; | ||
| 62 | } data[]; | ||
| 63 | }; | ||
| 64 | |||
| 65 | ///////////////////////////////////////////////////////////////////////////// | ||
| 66 | ///////////////////////////////////////////////////////////////////////////// | ||
| 67 | 20 | Task::Task(Main *main, double ts, const char * /*name*/): | |
| 68 |
1/2✓ Branch 8 taken 20 times.
✗ Branch 9 not taken.
|
20 | PdServ::Task(ts), main(main), mutex(1) |
| 69 | { | ||
| 70 | 20 | seqNo = 0; | |
| 71 | 20 | signalMemSize = 0; | |
| 72 | 20 | signalPosition = 0; | |
| 73 | 20 | signalListId = 0; | |
| 74 |
1/2✓ Branch 3 taken 20 times.
✗ Branch 4 not taken.
|
20 | std::fill_n(signalTypeCount, 4, 0); |
| 75 | 20 | signalCopyList[0] = 0; | |
| 76 | 20 | copyList[0] = 0; | |
| 77 | 20 | } | |
| 78 | |||
| 79 | ///////////////////////////////////////////////////////////////////////////// | ||
| 80 | ✗ | Task::~Task() | |
| 81 | { | ||
| 82 | ✗ | delete copyList[0]; | |
| 83 | ✗ | delete signalCopyList[0]; | |
| 84 | ✗ | delete signalPosition; | |
| 85 | |||
| 86 | ✗ | for (Signals::iterator it = signals.begin(); it != signals.end(); ++it) | |
| 87 | ✗ | delete *it; | |
| 88 | } | ||
| 89 | |||
| 90 | ///////////////////////////////////////////////////////////////////////////// | ||
| 91 | 20 | size_t Task::getShmemSpace(double T) const | |
| 92 | { | ||
| 93 | 20 | size_t n = signals.size(); | |
| 94 | 20 | size_t minPdoCount = (size_t)(T / sampleTime + 0.5); | |
| 95 | |||
| 96 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 20 times.
|
20 | if (minPdoCount < 10) |
| 97 | ✗ | minPdoCount = 10; | |
| 98 | |||
| 99 | return sizeof(*signalListRp) + sizeof(*signalListWp) | ||
| 100 | + sizeof(*poll) + n*sizeof(*poll->data) | ||
| 101 | + 2 * n * sizeof(*signalList) | ||
| 102 | 20 | + (sizeof(*txPdo) + signalMemSize) * minPdoCount; | |
| 103 | } | ||
| 104 | |||
| 105 | ///////////////////////////////////////////////////////////////////////////// | ||
| 106 | ✗ | SessionTaskData* Task::newSession(PdServ::Session * /*session*/) | |
| 107 | { | ||
| 108 | ✗ | return 0; //new SessionTaskData(session, this, txMemBegin, txMemEnd); | |
| 109 | } | ||
| 110 | |||
| 111 | ///////////////////////////////////////////////////////////////////////////// | ||
| 112 | 20 | void Task::prepare(void *shmem, void *shmem_end) | |
| 113 | { | ||
| 114 | log_debug("S(%p): shmem=%p shmem_end=%p", this, shmem, shmem_end); | ||
| 115 | 20 | size_t n = signals.size(); | |
| 116 | |||
| 117 | 20 | signalListRp = ptr_align<struct SignalList*>(shmem); | |
| 118 | 20 | signalListWp = signalListRp + 1; | |
| 119 | 20 | signalList = ptr_align<struct SignalList>(signalListWp + 1); | |
| 120 | 20 | signalListEnd = signalList + (2*n); | |
| 121 | 20 | *signalListRp = signalList; | |
| 122 | 20 | *signalListWp = signalList; | |
| 123 | |||
| 124 | 20 | poll = ptr_align<struct PollData>(signalListEnd); | |
| 125 | |||
| 126 | 20 | txMemBegin = ptr_align<struct Pdo>(poll->data + n); | |
| 127 | 20 | txMemEnd = shmem_end; | |
| 128 | log_debug("S(%p): txMemBegin=%p", this, txMemBegin); | ||
| 129 | // cerr_debug() << "signallen=" << signalMemSize << " txpdosize=" | ||
| 130 | // << sizeof(*txPdo) << " space=" | ||
| 131 | // << ((const char*)txMemEnd - (const char *)txMemBegin); | ||
| 132 | |||
| 133 | 20 | txPdo = txMemBegin; | |
| 134 | 20 | nextTxPdo = ptr_align<struct Pdo*>(shmem_end) - 2; | |
| 135 | 20 | } | |
| 136 | |||
| 137 | ///////////////////////////////////////////////////////////////////////////// | ||
| 138 | 20 | void Task::rt_init() | |
| 139 | { | ||
| 140 | 20 | signalMemSize = 0; | |
| 141 | |||
| 142 |
1/2✓ Branch 2 taken 20 times.
✗ Branch 3 not taken.
|
20 | copyList[0] = new struct CopyList[signals.size() + 4]; |
| 143 |
2/2✓ Branch 0 taken 60 times.
✓ Branch 1 taken 20 times.
|
80 | for (size_t i = 0; i < 3; i++) |
| 144 | 60 | copyList[i+1] = copyList[i] + signalTypeCount[i] + 1; | |
| 145 | |||
| 146 |
1/2✓ Branch 3 taken 20 times.
✗ Branch 4 not taken.
|
20 | std::fill_n(signalTypeCount, 4, 0); |
| 147 | |||
| 148 | // Clear src field which is end-of-list marker | ||
| 149 |
2/2✓ Branch 2 taken 140 times.
✓ Branch 3 taken 20 times.
|
160 | for (size_t i = 0; i < signals.size() + 4; ++i) |
| 150 | 140 | copyList[0][i].src = 0; | |
| 151 | 20 | } | |
| 152 | |||
| 153 | ///////////////////////////////////////////////////////////////////////////// | ||
| 154 | ✗ | void Task::nrt_init() | |
| 155 | { | ||
| 156 | ✗ | signalVector.resize(signals.size()); | |
| 157 | ✗ | for (Signals::const_iterator it = signals.begin(); | |
| 158 | ✗ | it != signals.end(); ++it) { | |
| 159 | ✗ | const Signal *s = static_cast<const Signal*>(*it); | |
| 160 | ✗ | signalVector[s->index] = s; | |
| 161 | } | ||
| 162 | |||
| 163 | ✗ | signalPosition = new unsigned int[signals.size()]; | |
| 164 | |||
| 165 | ✗ | signalCopyList[0] = new const Signal*[signals.size()]; | |
| 166 | ✗ | for (size_t i = 0; i < 3; i++) | |
| 167 | ✗ | signalCopyList[i+1] = signalCopyList[i] + signalTypeCount[i]; | |
| 168 | |||
| 169 | ✗ | std::fill_n(signalTypeCount, 4, 0); | |
| 170 | } | ||
| 171 | |||
| 172 | ///////////////////////////////////////////////////////////////////////////// | ||
| 173 | 60 | Signal* Task::addSignal( unsigned int decimation, | |
| 174 | const char *path, const PdServ::DataType& datatype, | ||
| 175 | const void *addr, size_t n, const size_t *dim) | ||
| 176 | { | ||
| 177 | 60 | Signal *s = new Signal(this, signals.size(), | |
| 178 |
1/2✓ Branch 3 taken 60 times.
✗ Branch 4 not taken.
|
60 | decimation, path, datatype, addr, n, dim); |
| 179 | |||
| 180 |
1/2✓ Branch 4 taken 60 times.
✗ Branch 5 not taken.
|
60 | signals.push_back(s); |
| 181 | 60 | signalTypeCount[s->dataTypeIndex[s->dtype.align()]]++; | |
| 182 | 60 | signalMemSize += s->memSize; | |
| 183 | |||
| 184 | 60 | return s; | |
| 185 | } | ||
| 186 | |||
| 187 | ///////////////////////////////////////////////////////////////////////////// | ||
| 188 | ✗ | size_t Task::signalCount() const | |
| 189 | { | ||
| 190 | ✗ | return signals.size(); | |
| 191 | } | ||
| 192 | |||
| 193 | ///////////////////////////////////////////////////////////////////////////// | ||
| 194 | ✗ | void Task::getSignalList(const Signal **signalList, size_t *nelem, | |
| 195 | unsigned int *signalListId) const | ||
| 196 | { | ||
| 197 | ✗ | ost::SemaphoreLock lock(mutex); | |
| 198 | |||
| 199 | ✗ | for (unsigned int i = 0; i < 4; ++i) | |
| 200 | ✗ | for (unsigned int j = 0; j < signalTypeCount[i]; ++j) | |
| 201 | ✗ | *signalList++ = signalCopyList[i][j]; | |
| 202 | ✗ | *nelem = std::accumulate(signalTypeCount, signalTypeCount + 4, 0); | |
| 203 | ✗ | *signalListId = (*signalListWp)->signalListId; | |
| 204 | } | ||
| 205 | |||
| 206 | ///////////////////////////////////////////////////////////////////////////// | ||
| 207 | ✗ | void Task::subscribe(const Signal* s, bool insert) const | |
| 208 | { | ||
| 209 | ✗ | ost::SemaphoreLock lock(mutex); | |
| 210 | ✗ | struct SignalList *wp = *signalListWp; | |
| 211 | |||
| 212 | ✗ | if (++wp == signalListEnd) | |
| 213 | ✗ | wp = signalList; | |
| 214 | |||
| 215 | ✗ | while (wp == *signalListRp) | |
| 216 | ✗ | ost::Thread::sleep(static_cast<unsigned>(sampleTime * 1000 / 2 + 1)); | |
| 217 | |||
| 218 | //log_debug("%i %s", insert, s->path.c_str()); | ||
| 219 | |||
| 220 | ✗ | size_t w = s->dataTypeIndex[s->dtype.align()]; | |
| 221 | ✗ | const Signal **scl = signalCopyList[w]; | |
| 222 | |||
| 223 | ✗ | wp->signal = s; | |
| 224 | |||
| 225 | ✗ | if (insert) { | |
| 226 | |||
| 227 | ✗ | wp->action = SignalList::Insert; | |
| 228 | |||
| 229 | ✗ | size_t i = signalTypeCount[w]++; | |
| 230 | ✗ | scl[i] = s; | |
| 231 | ✗ | signalPosition[s->index] = i; | |
| 232 | |||
| 233 | // log_debug("insert %s @ %zu[%zu]", s->path.c_str(), w, i); | ||
| 234 | // debug() << "insert" << s->path << w << i << (void*)signalCopyList[w]; | ||
| 235 | } | ||
| 236 | else { | ||
| 237 | ✗ | size_t pos = signalPosition[s->index]; | |
| 238 | |||
| 239 | // log_debug("erase %s @ %zu", s->path.c_str(), pos); | ||
| 240 | |||
| 241 | ✗ | wp->action = SignalList::Remove; | |
| 242 | ✗ | wp->signalPosition = pos; | |
| 243 | |||
| 244 | // Replace s with last signal on the list | ||
| 245 | ✗ | s = scl[--signalTypeCount[w]]; | |
| 246 | ✗ | scl[pos] = s; | |
| 247 | ✗ | signalPosition[s->index] = pos; | |
| 248 | |||
| 249 | // debug() << "erase" << s->path << w << signalPosition[s->index] | ||
| 250 | // << "copy(" | ||
| 251 | // << (void*)(signalCopyList[w]) | ||
| 252 | // << signalPosition[s->index] + 1 | ||
| 253 | // << signalTypeCount[w] | ||
| 254 | // << signalPosition[s->index]; | ||
| 255 | } | ||
| 256 | |||
| 257 | ✗ | wp->signalListId = ++signalListId; | |
| 258 | // cout << __func__ << s->index << ' ' << insert | ||
| 259 | // << " pos=" << wp->signalPosition << endl; | ||
| 260 | |||
| 261 | ✗ | *signalListWp = wp; | |
| 262 | } | ||
| 263 | |||
| 264 | ///////////////////////////////////////////////////////////////////////////// | ||
| 265 | ✗ | void Task::pollPrepare( const Signal *signal, void *dest) const | |
| 266 | { | ||
| 267 | ✗ | poll->data[poll->count].dest = dest; | |
| 268 | ✗ | poll->data[poll->count].signal = signal; | |
| 269 | ✗ | poll->length += signal->memSize; | |
| 270 | ✗ | poll->count++; | |
| 271 | } | ||
| 272 | |||
| 273 | ///////////////////////////////////////////////////////////////////////////// | ||
| 274 | ✗ | bool Task::pollFinished( const PdServ::Signal * const *, size_t /*nelem*/, | |
| 275 | void * const *, struct timespec *t) const | ||
| 276 | { | ||
| 277 | ✗ | if (!poll->count) | |
| 278 | ✗ | return true; | |
| 279 | |||
| 280 | ✗ | if (!poll->active) { | |
| 281 | ✗ | poll->active = true; | |
| 282 | ✗ | poll->request++; | |
| 283 | ✗ | return false; | |
| 284 | } | ||
| 285 | |||
| 286 | ✗ | if (poll->request != poll->reply) | |
| 287 | ✗ | return false; | |
| 288 | |||
| 289 | ✗ | const char *buf = poll->addr; | |
| 290 | ✗ | for (size_t i = 0; i < poll->count; ++i) { | |
| 291 | ✗ | const Signal *s = poll->data[i].signal; | |
| 292 | ✗ | std::copy(buf, buf + s->memSize, | |
| 293 | ✗ | reinterpret_cast<char*>(poll->data[i].dest)); | |
| 294 | ✗ | buf += s->memSize; | |
| 295 | } | ||
| 296 | |||
| 297 | ✗ | poll->active = false; | |
| 298 | ✗ | poll->count = 0; | |
| 299 | ✗ | poll->length = 0; | |
| 300 | ✗ | if (t) | |
| 301 | ✗ | *t = poll->time; | |
| 302 | |||
| 303 | ✗ | return true; | |
| 304 | } | ||
| 305 | |||
| 306 | ///////////////////////////////////////////////////////////////////////////// | ||
| 307 | ✗ | void Task::updateStatistics( | |
| 308 | double exec_time, double cycle_time, unsigned int overrun) | ||
| 309 | { | ||
| 310 | ✗ | taskStatistics.exec_time = exec_time; | |
| 311 | ✗ | taskStatistics.cycle_time = cycle_time; | |
| 312 | ✗ | taskStatistics.overrun = overrun; | |
| 313 | } | ||
| 314 | |||
| 315 | ///////////////////////////////////////////////////////////////////////////// | ||
| 316 | 1309 | void Task::update(const struct timespec *t) | |
| 317 | { | ||
| 318 |
2/2✓ Branch 8 taken 4 times.
✓ Branch 9 taken 1305 times.
|
1309 | if (poll->request != poll->reply) { |
| 319 |
1/2✗ Branch 10 not taken.
✓ Branch 11 taken 4 times.
|
4 | if (&txPdo->data + poll->length >= txMemEnd) { |
| 320 | ✗ | txPdo = txMemBegin; | |
| 321 | ✗ | txPdo->type = Pdo::Empty; | |
| 322 | ✗ | txPdo->next = 0; | |
| 323 | } | ||
| 324 | |||
| 325 | 4 | char *dst = &txPdo->data; | |
| 326 | |||
| 327 |
1/2✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
|
4 | if (t) |
| 328 | 4 | poll->time = *t; | |
| 329 | else | ||
| 330 | ✗ | poll->time.tv_sec = poll->time.tv_nsec = 0; | |
| 331 | |||
| 332 | 4 | poll->addr = dst; | |
| 333 | |||
| 334 |
2/2✓ Branch 4 taken 4 times.
✓ Branch 5 taken 4 times.
|
8 | for (size_t i = 0; i < poll->count; ++i) { |
| 335 | 4 | const Signal *s = poll->data[i].signal; | |
| 336 | 4 | std::copy(s->addr, s->addr + s->memSize, dst); | |
| 337 | 4 | dst += s->memSize; | |
| 338 | } | ||
| 339 | |||
| 340 | 4 | txPdo = ptr_align<Pdo>(dst); | |
| 341 | |||
| 342 |
1/2✗ Branch 7 not taken.
✓ Branch 8 taken 4 times.
|
4 | if (poll->addr == &txMemBegin->data) { |
| 343 | ✗ | txPdo->next = 0; | |
| 344 | ✗ | txPdo->type = Pdo::Empty; | |
| 345 | ✗ | txMemBegin->next = txPdo; | |
| 346 | } | ||
| 347 | |||
| 348 | 4 | poll->reply = poll->request; | |
| 349 | //log_debug("S(%p): poll", this); | ||
| 350 | } | ||
| 351 | |||
| 352 | 1309 | struct SignalList *sp = 0; | |
| 353 | |||
| 354 |
2/2✓ Branch 8 taken 4 times.
✓ Branch 9 taken 1309 times.
|
1317 | while (*signalListRp != *signalListWp) { |
| 355 | 4 | sp = *signalListRp + 1; | |
| 356 |
1/2✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
|
4 | if (sp == signalListEnd) |
| 357 | ✗ | sp = signalList; | |
| 358 | |||
| 359 | 4 | signalListId = sp->signalListId; | |
| 360 | 4 | const Signal *signal = sp->signal; | |
| 361 | 4 | size_t w = signal->dataTypeIndex[signal->dtype.align()]; | |
| 362 | struct CopyList *cl; | ||
| 363 | // cout << "Signal " << signal->index << " pos=" << sp->signalPosition; | ||
| 364 | |||
| 365 |
3/5✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 3 times.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
|
4 | switch (sp->action) { |
| 366 | 3 | case SignalList::Insert: | |
| 367 | // Insert the signal at list end | ||
| 368 | // log_debug("RT insert %s @ %zu", signal->path.c_str(), | ||
| 369 | // signalTypeCount[w]); | ||
| 370 | |||
| 371 | 3 | cl = copyList[w] + signalTypeCount[w]++; | |
| 372 | |||
| 373 | 3 | cl->src = signal->addr; | |
| 374 | 3 | cl->len = signal->memSize; | |
| 375 | 3 | cl->signal = signal; | |
| 376 | |||
| 377 | 3 | signalMemSize += signal->memSize; | |
| 378 | |||
| 379 | |||
| 380 | // cout << " added" << endl; | ||
| 381 | 3 | break; | |
| 382 | |||
| 383 | 1 | case SignalList::Remove: | |
| 384 | // Move signal at list end to the deleted position | ||
| 385 | 1 | cl = copyList[w] + --signalTypeCount[w]; | |
| 386 | 1 | copyList[w][sp->signalPosition] = *cl; | |
| 387 | 1 | cl->src = 0; // End of copy list indicator | |
| 388 | |||
| 389 | 1 | signalMemSize -= signal->memSize; | |
| 390 | |||
| 391 | // log_debug("RT remove %s @ %zu", signal->path.c_str(), | ||
| 392 | // signalTypeCount[w]); | ||
| 393 | |||
| 394 | // cout << " removed" << endl; | ||
| 395 | 1 | break; | |
| 396 | } | ||
| 397 | |||
| 398 | 4 | *signalListRp = sp; | |
| 399 | } | ||
| 400 | // cout << sp << endl; | ||
| 401 | |||
| 402 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 1305 times.
|
1309 | if (sp) { |
| 403 | 4 | size_t n = std::accumulate(signalTypeCount, signalTypeCount + 4, 0); | |
| 404 | // cout << "New signals " << n << ' ' << "signalMemSize=" << signalMemSize; | ||
| 405 | |||
| 406 |
1/2✗ Branch 6 not taken.
✓ Branch 7 taken 4 times.
|
4 | if ((&txPdo->signalIdx + n) >= txMemEnd) |
| 407 | ✗ | txPdo = txMemBegin; | |
| 408 | |||
| 409 | 4 | txPdo->next = 0; | |
| 410 | 4 | txPdo->type = Pdo::Empty; | |
| 411 | 4 | txPdo->signalListId = signalListId; | |
| 412 | 4 | txPdo->count = n; | |
| 413 | 4 | size_t *sp = &txPdo->signalIdx; | |
| 414 |
2/2✓ Branch 0 taken 16 times.
✓ Branch 1 taken 4 times.
|
20 | for (int i = 0; i < 4; i++) { |
| 415 |
2/2✓ Branch 5 taken 5 times.
✓ Branch 6 taken 16 times.
|
21 | for (CopyList *cl = copyList[i]; cl->src; ++cl) |
| 416 | 5 | *sp++ = cl->signal->index; | |
| 417 | } | ||
| 418 | 4 | txPdo->type = Pdo::SignalList; | |
| 419 | // cout << endl; | ||
| 420 | |||
| 421 | 4 | *nextTxPdo = txPdo; | |
| 422 | |||
| 423 | //log_debug("S(%p): TxPdo=%p (signalList)<- %p", this, txPdo, nextTxPdo); | ||
| 424 | |||
| 425 | 4 | nextTxPdo = &txPdo->next; | |
| 426 | 4 | txPdo = ptr_align<Pdo>(sp); | |
| 427 | } | ||
| 428 | |||
| 429 |
2/2✓ Branch 9 taken 5 times.
✓ Branch 10 taken 1304 times.
|
1309 | if ( &txPdo->data + signalMemSize >= txMemEnd) { |
| 430 | 5 | txPdo = txMemBegin; | |
| 431 | // cout << "wrap" << endl; | ||
| 432 | } | ||
| 433 | |||
| 434 | 1309 | txPdo->next = 0; | |
| 435 | 1309 | txPdo->type = Pdo::Empty; | |
| 436 | 1309 | txPdo->signalListId = signalListId; | |
| 437 | 1309 | txPdo->seqNo = seqNo++; | |
| 438 | |||
| 439 | 1309 | txPdo->taskStatistics = taskStatistics; | |
| 440 | |||
| 441 |
1/2✓ Branch 0 taken 1309 times.
✗ Branch 1 not taken.
|
1309 | if (t) { |
| 442 | 1309 | txPdo->time = *t; | |
| 443 | } | ||
| 444 | else | ||
| 445 | ✗ | txPdo->time.tv_sec = txPdo->time.tv_nsec = 0; | |
| 446 | |||
| 447 | 1309 | char *p = &txPdo->data; | |
| 448 |
2/2✓ Branch 0 taken 5236 times.
✓ Branch 1 taken 1309 times.
|
6545 | for (int i = 0; i < 4; ++i) { |
| 449 | // cout << i << ": "; | ||
| 450 |
2/2✓ Branch 5 taken 1328 times.
✓ Branch 6 taken 5236 times.
|
6564 | for (CopyList *cl = copyList[i]; cl->src; ++cl) { |
| 451 | 1328 | std::copy(cl->src, cl->src + cl->len, p); | |
| 452 | 1328 | p += cl->len; | |
| 453 | // cout << cl->signal->index << ' ' << cl->len << ' '; | ||
| 454 | } | ||
| 455 | } | ||
| 456 | 1309 | txPdo->type = Pdo::Data; | |
| 457 | // cout << '=' << p - txPdo->data << endl; | ||
| 458 | |||
| 459 | 1309 | txPdo->count = p - &txPdo->data; | |
| 460 | 1309 | *nextTxPdo = txPdo; | |
| 461 | |||
| 462 | //log_debug("S(%p): TxPdo=%p<-%p", this, txPdo, nextTxPdo); | ||
| 463 | 1309 | nextTxPdo = &txPdo->next; | |
| 464 | 1309 | txPdo = ptr_align<Pdo>(p); | |
| 465 | 1309 | } | |
| 466 | |||
| 467 | ///////////////////////////////////////////////////////////////////////////// | ||
| 468 | ✗ | void Task::prepare (PdServ::SessionTask *s) const | |
| 469 | { | ||
| 470 | ✗ | s->sessionTaskData = | |
| 471 | ✗ | new SessionTaskData(s, this, signalVector, txMemBegin, txMemEnd); | |
| 472 | } | ||
| 473 | |||
| 474 | ///////////////////////////////////////////////////////////////////////////// | ||
| 475 | ✗ | void Task::cleanup (const PdServ::SessionTask *s) const | |
| 476 | { | ||
| 477 | ✗ | delete s->sessionTaskData; | |
| 478 | } | ||
| 479 | |||
| 480 | ///////////////////////////////////////////////////////////////////////////// | ||
| 481 | ✗ | bool Task::rxPdo (PdServ::SessionTask *s, const struct timespec **time, | |
| 482 | const PdServ::TaskStatistics **stat) const | ||
| 483 | { | ||
| 484 | ✗ | return s->sessionTaskData->rxPdo(time, stat); | |
| 485 | 3 | } | |
| 486 |