Fail to free sem/mbox using tm4c1294

I am using tm4c1294+lwip1.4.1+FreeRTOS. As netconnalloc() is called for socket communication, it allocates an unused semaphore. the number of semaphore is defined as SYSSEMMAX, so it can not be over SYSSEMMAX. However, as semaphores are allocated continuously it reaches SYSSEMMAX and stop working since I gues syssem_free() does not deallocate it properly Here is function that creates a semaphore implemented in sys_arch.c
err_t
sys_sem_new(sys_sem_t *sem, u8_t count)
{

  void *temp;
  u32_t i;

  /* Find a semaphore that is not in use. */
  for(i = 0; i < SYS_SEM_MAX; i++) {
    if(sems[i].queue == 0) {
      break;
    }
  }

if(i == SYS_SEM_MAX) {
#if SYS_STATS
    STATS_INC(sys.sem.err);
#endif /* SYS_STATS */
    return ERR_MEM;
  }

  /* Create a single-entry queue to act as a semaphore. */
#if RTOS_FREERTOS
  sem->queue = xQueueCreate(1, sizeof(void *));
  if(sem->queue == NULL) {
#endif /* RTOS_FREERTOS */

#if SYS_STATS
    STATS_INC(sys.sem.err);
#endif /* SYS_STATS */
    return ERR_MEM;
  }
/* Acquired the semaphore if necessary. */ if(count == 0) { temp = 0; xQueueSend(sem->queue, &temp, 0); }
 /* Update the semaphore statistics. */
#if SYS_STATS
  STATS_INC(sys.sem.used);
#if LWIP_STATS
  if(lwip_stats.sys.sem.max < lwip_stats.sys.sem.used) {
    lwip_stats.sys.sem.max = lwip_stats.sys.sem.used;
  }
#endif
#endif /* SYS_STATS */

  /* Save the queue handle. */
  sems[i].queue = sem->queue;

  /* Return this semaphore. */
  return (ERR_OK);
}
Here is another function that frees semaphore implemented in sys_arch.c
void
sys_sem_free(sys_sem_t *sem)
{

  /* Delete Sem , By Jin */
  vQueueDelete(sem->queue);
/* Clear the queue handle. */
  sem->queue = 0;

 /* Update the semaphore statistics. */
#if SYS_STATS
  STATS_DEC(sys.sem.used);
#endif /* SYS_STATS */

}
Whenever netconnfree() is called syssem_free() deallocates the semaphore, but it does not free the semaphore assigned in sem[] array. I added vQueueDelete(sem->queue); that was suggested by someone, but still all same. Not only functions creates/frees semaphore but also functions handling mbox are same as functions above, so functions handling mbox could be wrong as well. Someone already reported this issue to TI, but it seems they have not solved the problems yet. Therefore, I may need to implement my own functions handling semaphore/mbox in sys_arch.c, but I don’t have any clues so far. Can anyone give me any ideas? or anything? Thanks, Jin

Fail to free sem/mbox using tm4c1294

I’m afraid we cannot provide direct support for lwIP – which is one of the reasons we created our own TCP/IP. However there is a reference lwIP integration in the FreeRTOS Interactive site. Note it is quite old though, and the CLI included in the project is not the same as the FreeRTOS+CLI project. Maybe it will help: http://interactive.freertos.org/entries/20290712-FreeRTOS-Win32-project-with-lwIP-web-server Regards.

Fail to free sem/mbox using tm4c1294

Thanks for replying. I am looking at source codes that you linked,but it’s quite different. I edited my question that is different from the last time I posted. If you have any ideas please let me know. Thanks, Jin

Fail to free sem/mbox using tm4c1294

Well, we have a reference implementation, you can choose to use it, or you can choose to ignore it. In the latter case I’m afraid we cannot look through your code and make suggestions for you as lwIP is not our product. That said: Are you sure the function that deletes the semaphore is ever being called? Mistakes in the porting or usage may just mean the stack is not being used correctly. The reason I ask is that, if you have read the FAQ pages you will have by now defined configASSERT() to assist with your debugging….and if you have defined configASSERT than your syssemfree() function will trigger two asserts because you are first wiping over the pointer to the require memory by setting it to 0 (and in so doing leaking the memory – which could well be the route cause of your problem), then second pass the pointer which is now set to 0 (NULL) into a function that will try and free it. Regards.

Fail to free sem/mbox using tm4c1294

Sorry, I didn’t update syssemfree() in my source codes and it does call this function.
  vQueueDelete(sem->queue);
  sem->queue = 0;
This is not working either. sysarch.c is implemented by TI and I am suspicious about mismatch between sems[] used as a global array to hold the memory for the available semaphores and *sem in syssemfree(syssemt *sem);therefore, even if *sem is set to NULL in syssem_free() the semaphores in sems[] are not deleted synchronously. I have not used configASSERT() since freeRTOS is new to me, so I need to take a look at how to use it. Thank you for answering. Jin

Fail to free sem/mbox using tm4c1294

I have hit compile errors as I add configASSERT() in FreeRTOSConfig.h So I directly use the function in two places of codes instead of the macro
if(sem->queue == 0)
{
    //UARTprintf("Assert 1 called !!~~n");
    taskDISABLE_INTERRUPTS();
    for( ;; )
    {

    }
}
Well, nothing goes into the above assert function. the application still stops as semaphores hit the max. Thanks, Jin

Fail to free sem/mbox using tm4c1294

What were the compiler errors?

Fail to free sem/mbox using tm4c1294

HI, There are a couple of undefined symbol(configMAXSYSCALLINTERRUPT_PRIORITY) errors in portasm.asm and other files that use configASSERT() However, I can directly use codes instead of the macro. It could be nice to use the macro but my issue is not this but allocating/deallocating semaphore like I said above. Thanks, Jin

Fail to free sem/mbox using tm4c1294

You are using a Cortex-M4, right? So what is portasm.asm? Its not a file from the FreeRTOS download.

Fail to free sem/mbox using tm4c1294

Hi, I am using Cortex M4,and portasm.asm is in the TM4C1294 package (FreeRTOS/Source/portable/CCS/ARM_CM4F/portasm.asm) I don’t get “it’s not a file from the FreeRTOS download” Thanks,

Fail to free sem/mbox using tm4c1294

I don’t get “it’s not a file from the FreeRTOS download”
There is no CCS port for the M4 in the FreeRTOS download, so it is not an official FreeRTOS file. There may well be a CCS port in the coming months though. Regards.

Fail to free sem/mbox using tm4c1294

I changed mainly sysarch.c/.h implemented in the linked source codes to see how that goes. The problem was not to free semaphores stored in global array as a result it reached the maximum size of array (SYSSEM_MAX) and stop allocating a new semaphore. the linked source codes are not using a global array containing semaphores. It just uses a single binary semaphore.
err_t sys_sem_new( sys_sem_t *pxSemaphore, u8_t ucCount )
{
err_t xReturn = ERR_MEM;

//  vSemaphoreCreateBinary( ( *pxSemaphore ) );
    *pxSemaphore = xSemaphoreCreateBinary();

    if( *pxSemaphore != NULL )
    {
        if( ucCount == 0U )
        {
            xSemaphoreTake( *pxSemaphore, 1UL );
        }

        xReturn = ERR_OK;
        SYS_STATS_INC_USED( sem );
    }
    else
    {
        SYS_STATS_INC( sem.err );
    }

    return xReturn;
}
Free used semaphores:
void sys_mutex_free( sys_mutex_t *pxMutex )
{
    SYS_STATS_DEC( mutex.used );
    vQueueDelete( *pxMutex );

}
The tasks running on the TM4C1294 keep on socket communicating with a server in every a second and less than that. However every time calling xSemaphoreCreateBinary() keeps increasing the address of memory up to allowable usage of memory, and then fail to allocate a new one, although syssemfree() is called at the end of socket communication. I feel like need to rewind/reuse semaphores instead of increasing the address of memory, which leads me back to the global array containing semaphores implemented in Tiva C. Any advices or ideas? Regards, Jin

Fail to free sem/mbox using tm4c1294

Let me try and simplify and take lwIP out of the equation. Are you saying that vQueueDelete() is called the same number of times as xSemaphoreCreateBinary(), so every semaphore that is created is also deleted, but you are running out of heap space anyway? Please remember you are using third party code, a third party port and a third party demo – we are happy to provide ‘generic’ FreeRTOS help, but cannot vouch for or research any of the code you are using. Regards.

Fail to free sem/mbox using tm4c1294

That’s correct. As I used safeRTOS, it did not happen. I asked if xSemaphoreCreateBinary() keeps increasing the address of memory every time it is called, so without rewinding/reusing the memory allocation of xQueueHandler it will eventually run out of heap. Thanks,

Fail to free sem/mbox using tm4c1294

Hi Jin, I’m having the exact same problem. I found the root of the problem and a solution using original code. As you said “Whenever netconnfree() is called syssem_free() deallocates the semaphore, but it does not free the semaphore assigned in sem[] array.” So, what I did was that: ~~~ /** * Destroys a semaphore. * * @param sem is the semaphore to be destroyed. */ void sys_sem_free(sys_sem_t *sem) { u32_t i;
      /* Find a semaphore that is in use. */
      for(i = 0; i < SYS_SEM_MAX; i++) {
        if(sems[i].queue == sem->queue) {
          break;
        }
      }

    /* Delete Sem , By Jin */
      vQueueDelete(sem->queue);

      /* Clear the queue handle. */
      sem->queue = 0;
      /* Clear the queue handle in global array. */
      sems[i].queue = 0;

      /* Update the semaphore statistics. */
    #if SYS_STATS
      STATS_DEC(sys.sem.used);
    #endif /* SYS_STATS */
} ~~~ And the same thing to mbox: ~~~ /** * Destroys a mailbox. * * @param mbox is the mailbox to be destroyed. / void sys_mbox_free(sys_mbox_t *mbox) { u32_t i; / There should not be any messages waiting (if there are it is a bug). If any are waiting, increment the mailbox error count. */

if RTOS_FREERTOS

if(uxQueueMessagesWaiting(mbox->queue) != 0) {

endif /* RTOS_FREERTOS */

if SYS_STATS

STATS_INC(sys.mbox.err);

endif /* SYS_STATS */

}
    /* Find a mailbox that is in use. */
    for(i = 0; i < SYS_MBOX_MAX; i++) {
      if(mboxes[i].queue == mbox->queue) {
            break;
      }
    }
/* Delete Sem , By Jin / vQueueDelete(mbox->queue); / Clear the queue handle. / mbox->queue = 0; / Clear the queue handle in global array. */ mboxes[i].queue = 0; /* Update the mailbox statistics. */

if SYS_STATS

STATS_DEC(sys.mbox.used);

endif /* SYS_STATS */

} ~~~ This solved the problem. Now I can connect as many times as necessary.