OD function for accessing _OD_trace_ (index 0x2400+) from SDO server. * For more information see file CO_SDOserver.h. */
| 243 | /* OD function for accessing _OD_trace_ (index 0x2400+) from SDO server. |
| 244 | * For more information see file CO_SDOserver.h. */ |
| 245 | static CO_SDO_abortCode_t CO_ODF_trace(CO_ODF_arg_t *ODF_arg) { |
| 246 | CO_trace_t *trace; |
| 247 | CO_SDO_abortCode_t ret = CO_SDO_AB_NONE; |
| 248 | |
| 249 | trace = (CO_trace_t*) ODF_arg->object; |
| 250 | |
| 251 | switch(ODF_arg->subIndex) { |
| 252 | case 1: /* size */ |
| 253 | if(ODF_arg->reading) { |
| 254 | uint32_t size = trace->bufferSize; |
| 255 | uint32_t wp = trace->writePtr; |
| 256 | uint32_t rp = trace->readPtr; |
| 257 | |
| 258 | if(wp >= rp) { |
| 259 | CO_setUint32(ODF_arg->data, wp - rp); |
| 260 | } |
| 261 | else { |
| 262 | CO_setUint32(ODF_arg->data, size - rp + wp); |
| 263 | } |
| 264 | } |
| 265 | else { |
| 266 | if(CO_getUint32(ODF_arg->data) == 0) { |
| 267 | /* clear buffer, handle race conditions */ |
| 268 | while(trace->readPtr != 0 || trace->writePtr != 0) { |
| 269 | trace->readPtr = 0; |
| 270 | trace->writePtr = 0; |
| 271 | *trace->triggerTime = 0; |
| 272 | } |
| 273 | } |
| 274 | else { |
| 275 | ret = CO_SDO_AB_INVALID_VALUE; |
| 276 | } |
| 277 | } |
| 278 | break; |
| 279 | |
| 280 | case 5: /* plot */ |
| 281 | if(ODF_arg->reading) { |
| 282 | /* This plot will be transmitted as domain data type. String data |
| 283 | * will be printed directly to SDO buffer. If there is more data |
| 284 | * to print, than is the size of SDO buffer, then this function |
| 285 | * will be called multiple times until internal trace buffer is |
| 286 | * empty. Internal trace buffer is circular buffer. It is accessed |
| 287 | * by this function and by higher priority thread. If this buffer |
| 288 | * is full, there is a danger for race condition. First records |
| 289 | * from trace buffer may be overwritten somewhere between. If this |
| 290 | * is detected, then do{}while() loop tries printing again. */ |
| 291 | if(trace->bufferSize == 0 || ODF_arg->dataLength < 100) { |
| 292 | ret = CO_SDO_AB_OUT_OF_MEM; |
| 293 | } |
| 294 | else if(trace->readPtr == trace->writePtr) { |
| 295 | ret = CO_SDO_AB_NO_DATA; |
| 296 | } |
| 297 | else { |
| 298 | uint32_t rp, t, v, len, freeLen; |
| 299 | char *s; |
| 300 | bool_t readPtrOverflowed; /* for handling race conditions */ |
| 301 | |
| 302 | /* repeat everything, if trace->readPtr was overflowed in CO_trace_process */ |
nothing calls this directly
no test coverage detected