extern size_t ciaaLibs_circBufWriteTo(ciaaLibs_CircBufType * cbuf, int32_t filDes, size_t nbytes) { size_t rawCount; /* the tail of the circular buffer my be changed, therefore it has to be * read only once */ size_t tail = cbuf->tail; /* if the users tries to read to much data, only available data will be * provided */ if (nbytes > ciaaLibs_circBufCount(cbuf, tail)) { nbytes = ciaaLibs_circBufCount(cbuf, tail); } /* check if data to be read */ if (nbytes > 0) { rawCount = ciaaLibs_circBufRawCount(cbuf, tail); /* check if all data can be read without wrapping */ if (nbytes <= rawCount) { ciaaPOSIX_write(filDes, ciaaLibs_circBufReadPos(cbuf), nbytes); } else { ciaaPOSIX_write(filDes, ciaaLibs_circBufReadPos(cbuf), rawCount); ciaaPOSIX_write(filDes, (void*)(&cbuf->buf[0]), nbytes-rawCount); } } return nbytes; } /* end ciaaLibs_circBufWriteTo */
extern void ciaaSerialDevices_txConfirmation(ciaaDevices_deviceType const * const device, uint32_t const nbyte) { /* get serial device */ ciaaSerialDevices_deviceType * serialDevice = (ciaaSerialDevices_deviceType*) device->layer; uint32_t write = 0; ciaaLibs_CircBufType * cbuf = &serialDevice->txBuf; uint32_t tail = cbuf->tail; uint32_t rawCount = ciaaLibs_circBufRawCount(cbuf, tail); uint32_t count = ciaaLibs_circBufCount(cbuf, tail); TaskType taskID = serialDevice->blocked.taskID; /* if some data have to be transmitted */ if (count > 0) { /* write data to the driver */ write = serialDevice->device->write(device->loLayer, ciaaLibs_circBufReadPos(cbuf), rawCount); /* update buffer */ ciaaLibs_circBufUpdateHead(cbuf, write); /* if all bytes were written and more data is available */ if ( (write == rawCount) && (count > rawCount ) ) { /* re calculate rawCount */ rawCount = ciaaLibs_circBufRawCount(cbuf, tail); /* write more bytes */ write = serialDevice->device->write(device->loLayer, ciaaLibs_circBufReadPos(cbuf), rawCount); if (write > 0) { /* update buffer */ ciaaLibs_circBufUpdateHead(cbuf, write); } } /* if task is blocked and waiting for reception of this device */ if ( (255 != taskID) && (serialDevice->blocked.fct == (void*) ciaaSerialDevices_write) ) { /* invalidate task id */ serialDevice->blocked.taskID = 255; /* TODO add a macro */ /* reset function */ serialDevice->blocked.fct = NULL; /* set task event */ #ifdef POSIXE SetEvent(taskID, POSIXE); #endif } } }
extern size_t ciaaLibs_circBufGet(ciaaLibs_CircBufType * cbuf, void * data, size_t nbytes) { size_t rawCount; /* the tail of the circular buffer my be changed, therefore it has to be * read only once */ size_t tail = cbuf->tail; /* if the users tries to read to much data, only available data will be * provided */ if (nbytes > ciaaLibs_circBufCount(cbuf, tail)) { nbytes = ciaaLibs_circBufCount(cbuf, tail); } /* check if data to be read */ if (nbytes > 0) { rawCount = ciaaLibs_circBufRawCount(cbuf, tail); /* check if all data can be read without wrapping */ if (nbytes <= rawCount) { ciaaPOSIX_memcpy(data, ciaaLibs_circBufReadPos(cbuf), nbytes); } else { ciaaPOSIX_memcpy(data, ciaaLibs_circBufReadPos(cbuf), rawCount); ciaaPOSIX_memcpy((void*)((intptr_t)data + rawCount), (void*)(&cbuf->buf[0]), nbytes-rawCount); } /* calculates new head position */ ciaaLibs_circBufUpdateHead(cbuf, nbytes); } return nbytes; } /* end ciaaLibs_circBufGet */