/** \brief test: ** - ciaaLibs_circBufSpace ** - ciaaLibs_circBufRawSpace ** - ciaaLibs_circBufCount ** - ciaaLibs_circBufRawCount **/ void test_ciaaLibs_circBufSpaceAndCount(void) { ciaaLibs_CircBufType * cbuf; char * data = "hallo world 123456789012345678901234567890213456789012345678901234567890"; char to[100]; size_t ret; /* use linux malloc */ ciaaPOSIX_malloc_StubWithCallback(malloc); ciaaPOSIX_memcpy_StubWithCallback(memcpy); /* try to create a buffer but no mem is available */ cbuf = ciaaLibs_circBufNew(64); TEST_ASSERT_TRUE(cbuf != NULL); /* 63 bytes shall be free */ TEST_ASSERT_EQUAL_INT(63, ciaaLibs_circBufSpace(cbuf, cbuf->head)); TEST_ASSERT_EQUAL_INT(63, ciaaLibs_circBufRawSpace(cbuf, cbuf->head)); /* 0 bytes shall be occupied */ TEST_ASSERT_EQUAL_INT(0, ciaaLibs_circBufCount(cbuf, cbuf->tail)); TEST_ASSERT_EQUAL_INT(0, ciaaLibs_circBufRawCount(cbuf, cbuf->tail)); /* put 40 bytes */ TEST_ASSERT_TRUE(40 == ciaaLibs_circBufPut(cbuf, data, 40)); /* 23 bytes shall be free */ TEST_ASSERT_EQUAL_INT(23, ciaaLibs_circBufSpace(cbuf, cbuf->head)); TEST_ASSERT_EQUAL_INT(23, ciaaLibs_circBufRawSpace(cbuf, cbuf->head)); /* 40 bytes shall be occupied */ TEST_ASSERT_EQUAL_INT(40, ciaaLibs_circBufCount(cbuf, cbuf->tail)); TEST_ASSERT_EQUAL_INT(40, ciaaLibs_circBufRawCount(cbuf, cbuf->tail)); /* get 30 bytes */ ret = ciaaLibs_circBufGet(cbuf, to, 30); TEST_ASSERT_EQUAL_INT(30, ret); /* 53 bytes shall be free */ TEST_ASSERT_EQUAL_INT(53, ciaaLibs_circBufSpace(cbuf, cbuf->head)); TEST_ASSERT_EQUAL_INT(24, ciaaLibs_circBufRawSpace(cbuf, cbuf->head)); /* 10 bytes shall be occupied */ TEST_ASSERT_EQUAL_INT(10, ciaaLibs_circBufCount(cbuf, cbuf->tail)); TEST_ASSERT_EQUAL_INT(10, ciaaLibs_circBufRawCount(cbuf, cbuf->tail)); /* put 50 */ TEST_ASSERT_EQUAL_INT(50, ciaaLibs_circBufPut(cbuf, data, 50)); /* 3 bytes shall be free */ TEST_ASSERT_EQUAL_INT(3, ciaaLibs_circBufSpace(cbuf, cbuf->head)); TEST_ASSERT_EQUAL_INT(3, ciaaLibs_circBufRawSpace(cbuf, cbuf->head)); /* 60 bytes shall be occupied */ TEST_ASSERT_EQUAL_INT(60, ciaaLibs_circBufCount(cbuf, cbuf->tail)); TEST_ASSERT_EQUAL_INT(34, ciaaLibs_circBufRawCount(cbuf, cbuf->tail)); /* free memory */ free(cbuf); }
/** \brief print debuf information of a circular buffer ** ** Print into screen: free space, raw free space, ** count of occupied bytes, raw count of occupied bytes ** position of head and tail and the buffer content. ** **/ void ciaaLibs_circBufPrint(ciaaLibs_CircBufType * cbuf) { printf("Free: %2d RFree: %2d Count: %2d RCount: %2d\n", ciaaLibs_circBufSpace(cbuf, cbuf->head), ciaaLibs_circBufRawSpace(cbuf, cbuf->head), ciaaLibs_circBufCount(cbuf, cbuf->tail), ciaaLibs_circBufRawCount(cbuf, cbuf->tail)); printf(" 0123456789012345678901234567890123456789012345678901234567890123\n"); printf("Head: %2d Tail: %2d Val:%s\n\n", cbuf->head, cbuf->tail, cbuf->buf); }
extern void ciaaSerialDevices_rxIndication(ciaaDevices_deviceType const * const device, uint32_t const nbyte) { /* get serial device */ ciaaSerialDevices_deviceType * serialDevice = (ciaaSerialDevices_deviceType*) device->layer; ciaaLibs_CircBufType * cbuf = &serialDevice->rxBuf; uint32_t head = cbuf->head; uint32_t rawSpace = ciaaLibs_circBufRawSpace(cbuf, head); uint32_t space = ciaaLibs_circBufSpace(cbuf, head); uint32_t read = 0; TaskType taskID = serialDevice->blocked.taskID; read = serialDevice->device->read(device->loLayer, ciaaLibs_circBufWritePos(cbuf), rawSpace); /* if rawSpace is full but more space is avaialble */ if ((read == rawSpace) && (space > rawSpace)) { read += serialDevice->device->read( device->loLayer, &cbuf->buf[0], space - rawSpace); } else { if ((read == rawSpace) && (space <= rawSpace)) { /* data may be lost because not place on the receive buffer */ /* TODO */ } else { /* read less bytes than provided */ /* nothing to do */ } } /* update tail */ ciaaLibs_circBufUpdateTail(cbuf, read); /* if data has been read */ if ( (0 < read) && (255 != taskID) && (serialDevice->blocked.fct == (void*) ciaaSerialDevices_read ) ) { /* invalidate task id */ serialDevice->blocked.taskID = 255; /* TODO add macro */ /* reset blocked function */ serialDevice->blocked.fct = NULL; /* set task event */ #ifdef POSIXE SetEvent(taskID, POSIXE); #endif } }
extern size_t ciaaLibs_circBufPut(ciaaLibs_CircBufType * cbuf, void const * data, size_t nbytes) { size_t ret = 0; size_t rawSpace; /* the head of the circular buffer may be changed, therefore it has to be * read only once */ size_t head = cbuf->head; /* check that is enough place */ if (ciaaLibs_circBufSpace(cbuf, head) >= nbytes) { rawSpace = ciaaLibs_circBufRawSpace(cbuf, head); /* check if wrapping is needed */ if (rawSpace >= nbytes) { ciaaPOSIX_memcpy(ciaaLibs_circBufWritePos(cbuf), data, nbytes); } else { ciaaPOSIX_memcpy((void*)(&cbuf->buf[cbuf->tail]), data, rawSpace); ciaaPOSIX_memcpy((void*)(&cbuf->buf[0]), (void*)((intptr_t)data + rawSpace), nbytes-rawSpace); } /* calculate new tail position */ ciaaLibs_circBufUpdateTail(cbuf, nbytes); /* set return value */ ret = nbytes; } return ret; } /* end ciaaLibs_circBufPut */