3

我正在使用 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/mboxsys_arch.c但到目前为止我没有任何线索。

谁能给我任何想法?还是什么?

谢谢,晋

4

1 回答 1

2

/doc 中的 sys_arch.txt 文件有些帮助。显然,查看该文档以及 lwip 1.3.2 过去所做的事情,ports/tiva-tm4c129/sys_arch.c 看起来不正确且不完整。

sys_sem_free() 确实应该像您发现的那样执行 vQueueDelete() 。它应该做“sem->queue = 0”。如果您查看 src/api/api_msg.c 中的 netconn_free(),您可以看到它调用了 sys_sem_free(),然后调用了 sys_sem_set_invalid()。在第二个函数中将需要队列句柄,并且不应该在第一个函数中被破坏。

sys_sem_set_invalid() 应该对 sems[] 数组进行扫描,如果它找到与 sem->queue 的匹配项,它应该将 sems[] 中的副本清零。一旦完成,它应该将 sem->queue 设置为 0。

我认为,这与 Dunkel 的 sys_arch.txt 文档中的内容最匹配,并修复了我系统上的资源泄漏。

我同意邮箱的形状相同。Fwiw,我继续以与刚刚描述的 sem 类似的方式修改了这些。

顺便说一句,我使用的 lwip 文件来自 TivaWare_C_Series 2.1.0.12573 third_party 文件夹。

于 2015-04-17T19:25:14.467 回答