Exemplo n.º 1
0
/** \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);
}
Exemplo n.º 2
0
/** \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);
}
Exemplo n.º 3
0
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
   }
}
Exemplo n.º 4
0
extern int32_t ciaaSerialDevices_write(ciaaDevices_deviceType const * const device, uint8_t const * buf, uint32_t nbyte)
{
   /* get serial device */
   ciaaSerialDevices_deviceType * serialDevice =
      (ciaaSerialDevices_deviceType*) device->layer;
   int32_t ret = 0;
   int32_t total = 0;
   ciaaLibs_CircBufType * cbuf = &serialDevice->txBuf;
   int32_t head;
   uint32_t space;

   do
   {
      /* read head and space */
      head = cbuf->head;
      space = ciaaLibs_circBufSpace(cbuf, head);

      /* put bytes in the queue */
      ret = ciaaLibs_circBufPut(cbuf, buf, ciaaLibs_min(nbyte-total, space));
      /* update total of written bytes */
      total += ret;

      /* starts the transmission if not already ongoing */
      serialDevice->device->ioctl(
            device->loLayer,
            ciaaPOSIX_IOCTL_STARTTX,
            NULL);

      /* if not all bytes could be stored in the buffer */
      if (total < nbyte)
      {
         /* increment buffer */
         buf += ret;

         /* set the task to sleep until some data have been send */

         /* TODO improve this: https://github.com/ciaa/Firmware/issues/88 */
         serialDevice->device->ioctl(device->loLayer, ciaaPOSIX_IOCTL_SET_ENABLE_TX_INTERRUPT, (void*)false);
         /* get task id and function for waking up the task later */
         GetTaskID(&serialDevice->blocked.taskID);
         serialDevice->blocked.fct = (void*) ciaaSerialDevices_write;

         /* TODO improve this: https://github.com/ciaa/Firmware/issues/88 */
         serialDevice->device->ioctl(device->loLayer, ciaaPOSIX_IOCTL_SET_ENABLE_TX_INTERRUPT, (void*)true);
         /* wait to write all data or for the txConfirmation */
#ifdef POSIXE
         WaitEvent(POSIXE);
         ClearEvent(POSIXE);
#endif
      }
   }
   while (total < nbyte);

   return total;
}
Exemplo n.º 5
0
extern int32_t ciaaSerialDevices_ioctl(ciaaDevices_deviceType const * const device, int32_t request, void* param)
{
   int32_t ret = 0;

   ciaaSerialDevices_deviceType * serialDevice = (ciaaSerialDevices_deviceType *) device->layer;
   ciaaLibs_CircBufType * cbuf;
   uint32_t tail, head;

   switch(request)
   {
      case ciaaPOSIX_IOCTL_GET_RX_COUNT:
         cbuf = &serialDevice->rxBuf;
         tail = cbuf->tail;
         *(uint32_t *)param = ciaaLibs_circBufCount(cbuf, tail);
         ret = 0;
         break;

      case ciaaPOSIX_IOCTL_GET_TX_SPACE:
         cbuf = &serialDevice->txBuf;
         head = cbuf->head;
         *(uint32_t *)param = ciaaLibs_circBufSpace(cbuf, head);
         ret = 0;
         break;

      case ciaaPOSIX_IOCTL_RXINDICATION:
         break;

      case ciaaPOSIX_IOCTL_SET_NONBLOCK_MODE:
         if((bool)(intptr_t)param == false)
         {
            /* Blocking mode */
            serialDevice->flags &= ~ciaaSerialDevices_NONBLOCK_MODE;
         }
         else
         {
            /* NonBlocking Mode */
            serialDevice->flags |= ciaaSerialDevices_NONBLOCK_MODE;
         }
         ret = 0;
         break;

      default:
         ret = serialDevice->device->ioctl(device->loLayer, request, param);
         break;
   }
   return ret;
}
Exemplo n.º 6
0
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 */