嵌入式系统上分层通信堆栈的内存管理[关闭]

问题描述 投票:0回答:2

这个问题涉及嵌入式系统的编程。我正在嵌入式设备上进行实验性通信栈。堆栈从底层通道接收流数据,检测离散数据包,重新组合碎片数据等...

每个功能都在一个单独的层中实现。某些层延迟了数据包的处理(因为数据到达中断处理程序并进一步处理被卸载到主上下文中)。一些层将多个输入分组合并到转发到下一个上层的单个分组中(即,分段数据的重组)。因此,一些层将一个输入分组分成转发到下一个较低层的多个分组。当然,任何层都可以在任何时候丢弃数据包而不另行通知,因为例如校验和与数据不匹配。

我的问题是关于这些数据包的内存分配。

目前,我在每一层都使用malloc。具体来说,我为要转发到下一个上层的数据包分配内存,将指针传递给下一层的处理程序,并在调用后再次释放内存。下一层的处理程序负责复制所需的数据。因此,每个层都保持分配数据的所有权,并且很难忘记释放分配的内存。这非常有效,但会导致许多不必要的副本。

或者,我可以将缓冲区的所有权转发到下一层。然后,下一层可以直接在缓冲区上完成工作,并将相同的缓冲区转发到下一层,依此类推。我想,没有内存泄露,这样做有点棘手。

最终,因为它是一个嵌入式设备,我想找到一个没有动态内存分配的解决方案。如果每个层都保留了自己内存的所有权,那么没有malloc的实现应该很容易。但如果所有权转移,那么它似乎更复杂。

你有任何意见吗?

c memory-management embedded osi
2个回答
1
投票

查看LwIP数据包缓冲区(pbuf),它可以解决您的方案中提到的情况。 http://www.nongnu.org/lwip/2_0_x/group__pbuf.html为了增强ISR执行的代码,而不是malloc,您可以实现内存池。


0
投票

在一个地方分配内存。由于它是嵌入式系统,因此您必须使用静态内存池。就像以opaque类型实现的经典ADT一样:

// buffer.h

typedef struct buffer_t buffer_t;

buffer_t* buffer_create (/*params*/);

/* setter & getter functions here */

// buffer.c

#include "buffer.h"

struct buffer_t
{
  /* private contents */
};


static buffer_t mempool [MEMPOOL_SIZE];
static size_t mempool_size = 0;

buffer_t* buffer_create (/*params*/)
{
  if(mempool_size == MEMPOOL_SIZE)
  { /* out of memory, handle error */ }

  buffer_t* obj = &mempool[mempool_size]; 
  mempool_size++;

  /* initialize obj here */

  return obj;
}

/* setter & getter functions here */

现在,您所有的各种应用程序层和进程只能传递指针的副本。如果您确实需要实际进行硬拷贝,请在上面的ADT中实现buffer_copy函数。

在多进程系统的情况下,如果允许多个进程同时分配缓冲区,则必须考虑重入。

© www.soinside.com 2019 - 2024. All rights reserved.