我使用的是tm4c1294 + lwip1.4.1 + FreeRTOS。
当为netconn_alloc()
调用socket communication
时,它会分配一个未使用的信号量。信号量的数量定义为SYS_SEM_MAX,因此它不能超过SYS_SEM_MAX
。
但是,由于信号量被连续分配,它达到SYS_SEM_MAX
并停止工作,因为我猜sys_sem_free()
没有正确解除分配
这是创建在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);
}
这是另一个释放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 */
}
每当调用netconn_free()
时sys_sem_free()
取消分配信号量,但它不会释放sem[] array
中分配的信号量。
我添加了某人建议的vQueueDelete(sem->queue);
,但仍然完全相同。
不仅函数创建/释放semaphore
而且函数处理mbox
与上面的函数相同,因此处理mbox
的函数也可能是错误的。
有人已向TI报告此问题,但似乎尚未解决问题。
因此,我可能需要在semaphore/mbox
中实现我自己的函数处理sys_arch.c
,但到目前为止我还没有任何线索。
任何人都可以给我任何想法吗?还是什么?
谢谢, 金
答案 0 :(得分:2)
/ doc中的sys_arch.txt文件有点帮助。显然,查看该文档,以及lwip 1.3.2曾经做过的事情,看起来ports / tiva-tm4c129 / sys_arch.c是不正确和不完整的。
sys_sem_free()确实应该像您发现的那样执行vQueueDelete()。它不正在做&#34; sem-&gt; queue = 0&#34;。如果你在src / api / api_msg.c中查看netconn_free(),你可以看到它调用sys_sem_free()然后调用sys_sem_set_invalid()。第二个函数中将需要队列句柄,并且不应该在第一个函数中被破坏。
sys_sem_set_invalid()应该对sems []数组进行扫描,如果找到与sem-&gt;队列的匹配,它应该在sems []中将该副本清零。完成后,应将sem-&gt; queue设置为0。
我认为这最符合Dunkel的sys_arch.txt文档中的内容,并修复了我系统上的资源泄漏。
我同意邮箱的形状相同。 Fwiw,我继续修改那些与上面描述的sems相似的方式。
顺便说一句,我使用的lwip文件来自TivaWare_C_Series 2.1.0.12573 third_party文件夹。