This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Bug in the TivaWare implementation of sys_arch.c for LwIP??

Prodigy 215 points

Replies: 15

Views: 2790

While working on an implementation of FreeRTOS with LwIP on a TI TM4C129ENCPDT processor, I've come across the sys_sem_new() and sys_sem_free() functions that are implemented by TI in the sys_arch.c file used in LwIP as part of TivaWare. These two functions are basically used for creating and destroying semaphores, but there seems to be a bug in the implementation so that semaphores are not actually cleared when calling sys_sem_free().

Consider the following code copied and pasted from TI's implementation of sys_arch.c <TivaWare>\third_party\lwip-1.4.1\ports\tiva-tm4c129\sys_arch.c


/* An array to hold the memory for the available semaphores. */ static sem_t sems[SYS_SEM_MAX]; /** * Initializes the system architecture layer. * */ void sys_init(void) { u32_t i; /* Clear out the semaphores. */ for(i = 0; i < SYS_SEM_MAX; i++) { sems[i].queue = 0; } } /** * Creates a new semaphore. * * @param count is non-zero if the semaphore should be acquired initially. * @return the handle of the created semaphore. */ 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(*(*int)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); } /** * Destroys a semaphore. * * @param sem is the semaphore to be destroyed. */ void sys_sem_free(sys_sem_t *sem) { /* Clear the queue handle. */ sem->queue = 0; /* Update the semaphore statistics. */ #if SYS_STATS STATS_DEC(sys.sem.used); #endif /* SYS_STATS */ }

It appears to me that the code in sys_sem_free() does nothing to clear the value set in the global sems array that is being checked and set when creating a new semaphore with sys_sem_new().

In my project, this quickly results in a condition where the sys_sem_new() function returns ERR_MEM because SYS_SEM_MAX has been reached, and no new semaphores can be allocated.

Please note that even if I set SYS_SEM_MAX to a very high number, I am still unable to clear semaphores, and will eventually be unable to create new semaphores.

It seems that the same create and destroy functionality is used for mailboxes in the same file, and so I would expect a similar problem here, but have not yet experienced it myself.

Is this a bug in TI's implementation of the sys_arc.c file, or am I missing something??

FYI: I'm using TivaWare version 2.1.0.12573 which includes the newest version of LwIP (version 1.4.1).

15 Replies

  • Hello Simon

    Sai from TI just posted the patch on this thread...

    http://e2e.ti.com/support/microcontrollers/tiva_arm/f/908/t/374100.aspx

    Regards

    Amit

    Regards,

    Amit Ashara

  • In reply to Amit Ashara:

    I think the referenced thread deals with netif.c, not sys_arch.c. Sys_arch is still wrong.

    Please read the sys_arch.txt for needed implementation and roll your own. I just started to implement freertos/lwip for TM4C and quick look at sys_arch.c tells me that it can not be used. The implementation is rather interesting. Deleting the mailbox/semaphore is clear bug, dealing with stack task while creating a task is also a bit strange, I must say...

    For deleting sems/mbox:
    https://code.google.com/p/stream-radio-v3/source/browse/trunk/TCPv3/lwip-1.4.0/port/FreeRTOS/arch/sys_arch.c?r=5

    But dont copy it otherwise. It has some other interesting features.

    So take the tiva-tmc129.c from the suggested thread and roll your own sys_arch.c (and check freertos examples from freertos package, they might have better solution, I will check it too) and skip anything else related to lwip from tivaware. It is a bit same thing than with stellarisware, usable for small howto example, but has to be rewritten for more serious stuff.

    BR, Madis
  • In reply to Madis:

    Hello Madis,

    I have asked Sai to look into this as well. All further updates will come from him

    Regards
    Amit

    Regards,

    Amit Ashara

  • In reply to Madis:

    Hi,

    I have a same problem now.

    As the semaphore reaches the "SYS_SEM_MAX", fail to create netconn.

    So I added vQueueDelete(sem->queue) in sys_sem_free() but it still gives me a same error.

    How could you solve this?

    Jin

  • Hi, Simon,
    i have find the same problem when ebable LWIP_SOCKET . after my analysis, the cause lies in the sys_sem_free and sys_sem_new.
    after the sys_sem_new() allocate a new queue, we use sys_sem_free to deallocate it, the problem comes out, the sems[SYS_SEM_MAX ] is global, but the sys_sem_free() won't do anything about this global variable sems[SYS_SEM_MAX ], so it won't be freed, even we add "sem->queue = 0".
    so any time we use a sem, the sems[SYS_SEM_MAX ] will consume once, when we reached SYS_SEM_MAX , we will never able to use semaphore again.
    i don't familiar with freertos, so, are we wrong about it?
  • In reply to rubin lee:

    Hi Rubin, it seem's that you have stumbled upon the same bug that I mentioned in my original post.

    I worked around the problem by using the lwIP sysarch implementation found in this .zip file attached to this post on the FreeRTOS Community Contributions forum in stead of the standard implementation found in TivaWare.

    Regards,
    Simon

  • In reply to Simon Einfeldt:

    HI Simon,

    I have asked LWIP forum, FreeRTOS, and TI but I have not got any proper responses yet.

    My application communicates with Unix using socket every 1sec and reaches to SYS_SEM_MAX without freeing the semaphore.

    I added index into sem_t and mobx_t to make sure the global sems[] is erased, but it didn't seem to work.

    I need to take a look at it,but I hope it resolve the problems!!

    Thank you for letting me know the source!

    Jin

  • In reply to Simon Einfeldt:

    HI Simon,

    Unlike sys_arch.c in TM4C1294, the sys_arch in the zip file does not use SYS_SEM_MAX and SYS_MBOX_MAX. It does not use arrays to hold them globally.

    I wonder do you keep the global arrays or just use single entry?

    Jin
  • In reply to Jin Seo:

    Hi Jin,

    Since the implementation that I am using does not limit the number of semaphores in use (at least not by software), I'm not using any global arrays to keep track of my semaphores. This means I don't need the constants SYS_SEM_MAX and SYS_MBOX_MAX defined in the TivaWare implementation.

    Regards,
    Simon

  • In reply to Simon Einfeldt:

    Hi Simon,

    What I changed is sys_arch.c and sys_arch.n which were implemented in .zip.  The example codes just use a single entry semaphore rather than put it into a global array, so definitely it is not confined by any size of arrays. It runs ok for 1~2 minutes,but it stops working since sys_sem_new() is unable to create a new semaphore by calling vSemaphoreCreateBinary() which keeps increasing the address of memory every time it is called. If the address of semaphore is reused after calling sys_sem_free(), it could run forever. But vSemaphoreCreateBinary() just keeps increasing the address so it eventually hits the max of the allowable memory.

    Have you encountered this problem?

This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.