AnsweredAssumed Answered

STM32Cube FreeRTOS cmsis_os.c osPoolAlloc bug

Question asked by w.rob.001 on Nov 11, 2015
Latest reply on Nov 12, 2015 by Fischer.Thomas.004
Hi,


This code generated by STM32Cube with FreeRTOS looks like it has a bug. 
To reproduce, create a small pool. Allocate a single item that is not free'd then, allocate and deallocate sucessive items. The pool will stop allocating, even though there are free slots.


The code at fault is,


    index = pool_id->currentIndex + i;
    if (index >= pool_id->pool_sz) {
      index = 0;
    }


currentIndex is never reset, and so for a queue size of say 8, if currentIndex = 7, then for all i (1,2,3..) in the loop, currentindex + i will be greater than pool_sz. and index will be set to 0, so only markers[0]  gets checked continiously. If index 0 is not free, then the pool will not allocate, and will break in this condition


The above section should be something like 


index = (pool_id->currentIndex + i) % pool_id->pool_sz;






FULL FUNCTION:




void *osPoolAlloc (osPoolId pool_id)
{
  int dummy = 0;
  void *p = NULL;
  uint32_t i;
  uint32_t index;




  if (inHandlerMode()) {
    dummy = portSET_INTERRUPT_MASK_FROM_ISR();
  }
  else {
    vPortEnterCritical();
  }


  for (i = 0; i < pool_id->pool_sz; i++) {
    index = pool_id->currentIndex + i;
    if (index >= pool_id->pool_sz) {
      index = 0;
    }




    if (pool_id->markers[index] == 0) {
      pool_id->markers[index] = 1;
      p = (void *)((uint32_t)(pool_id->pool) + (index * pool_id->item_sz));
      pool_id->currentIndex = index;
      break;
    }
  }




  if (inHandlerMode()) {
    portCLEAR_INTERRUPT_MASK_FROM_ISR(dummy);
  }
  else {
    vPortExitCritical();
  }




  return p;
}

Outcomes