Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 嵌入式系统分层通信栈的内存管理_C_Memory Management_Embedded_Osi - Fatal编程技术网

C 嵌入式系统分层通信栈的内存管理

C 嵌入式系统分层通信栈的内存管理,c,memory-management,embedded,osi,C,Memory Management,Embedded,Osi,这个问题与嵌入式系统的编程有关。 我正在嵌入式设备上做一个实验性的通信堆栈。 堆栈从底层通道接收流数据,检测离散数据包,重新组装碎片数据,等等 每个功能都在一个单独的层中实现。 某些层延迟了数据包的处理(因为数据到达了中断处理程序,并且进一步 处理被卸载到主上下文中)。 某些层将多个传入数据包合并为转发到下一上层的单个数据包(即碎片数据的重新组合)。 因此,一些层将一个传入分组分割成多个转发到下一较低层的分组。 当然,任何层都可以在任何时候丢弃数据包,而无需另行通知,因为,例如,校验和与数据不匹

这个问题与嵌入式系统的编程有关。 我正在嵌入式设备上做一个实验性的通信堆栈。 堆栈从底层通道接收流数据,检测离散数据包,重新组装碎片数据,等等

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

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

目前,我在每一层上使用malloc。具体来说,我为要转发到下一个上层的数据包分配内存, 将指针传递给下一层的处理程序,并在调用后再次释放内存。这是下一层处理程序的责任 复制所需的数据。因此,每一层都维护分配的数据的所有权,很难忘记释放分配的内存。 这很有效,但会导致大量不必要的拷贝

或者,我可以将缓冲区的所有权转发到下一层。然后下一层可以直接在缓冲区和转发区上执行其工作 将相同的缓冲区转移到下一层,依此类推。我想这是有点棘手,以获得正确的,没有内存泄漏

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


你有什么意见吗

查看LwIP数据包缓冲区(pbuf),它解决了场景中提到的情况。
为了使ISR执行的代码更加健壮,您可以实现内存池,而不是malloc。

查看LwIP数据包缓冲区(pbuf),它解决了场景中提到的情况。
为了使ISR执行的代码更加健壮,您可以实现内存池,而不是malloc。

在一个位置分配内存。因为它是一个嵌入式系统,所以必须使用静态内存池。与实现为不透明类型的经典ADT类似:

//缓冲区

typedef struct buffer_t buffer_t;

buffer_t* buffer_create (/*params*/);

/* setter & getter functions here */
//缓冲区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\u copy
功能


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

在一个位置分配内存。因为它是一个嵌入式系统,所以必须使用静态内存池。与实现为不透明类型的经典ADT类似:

//缓冲区

typedef struct buffer_t buffer_t;

buffer_t* buffer_create (/*params*/);

/* setter & getter functions here */
//缓冲区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\u copy
功能


在多进程系统的情况下,在允许多个进程同时分配缓冲器的情况下,您必须考虑重新入侵者。

我只需避免不必要的副本。但是问题太广泛了。如果处理相似大小的数据包,可以使用内存池减少碎片。如果您只是转移所有权,我看不出复制数据的原因?正如你所写的,第三种选择是使用引用计数。也许你可以试着问下去,这会被认为是离题的。我删除了你问题的最后一部分,因为工具/库的建议在这里离题了,问这样的问题可能会让你的问题结束。我只是避免不必要的拷贝。但是问题太广泛了。如果处理相似大小的数据包,可以使用内存池减少碎片。如果您只是转移所有权,我看不出复制数据的原因?正如您所写,第三种选择是使用引用计数。也许您可以尝试继续提问,这将被视为离题。我删除了您问题的最后一部分,因为工具/库建议在这里离题,询问这样的建议可能会使您的问题结束。