【问题标题】:Need an example of using mmem in Contiki需要一个在 Contiki 中使用 mmem 的示例
【发布时间】:2019-07-20 10:47:21
【问题描述】:

我正在开发在 COOJA 模拟器中使用的代码。我使用malloc() 进行所有动态内存分配。在模拟运行时,COOJA 微粒会定期重启,最后我收到一个错误,告诉我原因是我正在使用malloc()

我正在考虑使用名为“mmem”的 Contiki 的特定内存分配类。我找不到任何使用它的例子。这是一个示例,其中我使用malloc() 为名为@9​​87654325@ 的字符串分配内存。

如何将 malloc() 替换为 mmem 而不是 malloc()

   char *sent;
   sent = (char*)malloc(120);
   strncpy(sent , "example" , 7);
   strncat(sent , "|", 1);

【问题讨论】:

  • 为什么不在堆栈上分配 120 字节?
  • 就我而言,字符和字符串之间会有很多转换,我对此不感兴趣。
  • 我想我不明白。如果您预先知道分配大小(您的示例代码建议),为什么不直接在堆栈上分配呢?低资源设备上的嵌入式开发和动态分配通常以碎片化结束,导致耗尽,这可能是导致崩溃的原因。甚至 Contiki 的文档也提到了这一点。尽管如此,我假设您已经阅读了本指南:github.com/contiki-os/contiki/wiki/…?
  • 我不确定我是否完全理解您所指的解决方案。你能解释一下我如何在堆栈上分配吗?老实说,我不明白您所说的“堆栈”是什么意思。
  • 栈 vs 堆是 C 编程的核心概念,我很难在这里用 600 个字符来解释它。基本上不是char* sent = malloc(120);,而是char sent[120];等。

标签: c heap-memory contiki cooja


【解决方案1】:

来自Contiki’s github Wiki

这是一个如何使用托管内存分配器的示例:

 #include "contiki.h"
 #include "lib/mmem.h"

 static struct mmem mmem;

 static void
 test_mmem(void)
 {
   struct my_struct {
     int a;
   } my_data, *my_data_ptr;

   if(mmem_alloc(&mmem, sizeof(my_data)) == 0) {
     printf("memory allocation failed\n");
   } else {
     printf("memory allocation succeeded\n");
     my_data.a = 0xaa;
     memcpy(MMEM_PTR(&mmem), &my_data, sizeof(my_data));
     /* The cast below is safe only if the struct is packed */
     my_data_ptr = (struct my_struct *)MMEM_PTR(&mmem);
     printf("Value a equals 0x%x\n", my_data_ptr->a);
     mmem_free(&mmem);
   }
 }

上面的示例显示了托管内存的基本示例 可以使用库。在第 4 行,我们分配了一个变量 mmem,它 标识我们将要分配的托管内存对象。在 第 13 行,我们使用 mmem 变量作为 mmem_alloc() 的参数 为 sizeof(my_data) 字节的结构分配空间。如果 分配成功,我们从现有结构中复制值 进入分配的结构,由 MMEM_PTR(&mmem) 指向。 然后,分配结构的各个成员可以通过 将 MMEM_PTR(&mmem) 类型转换为 struct my_struct *,如在线所示 20. 请注意,只有结构被打包时,强制转换才是安全的。托管内存最终在第 21 行通过调用释放 mmem_free().

.

编辑:

根据您粘贴在 cmets 中的代码,无需使用 mallocmmem 模块。只需在堆栈上分配。也许可以尝试这样的事情:

/* Allocate memory on the stack */
char sent[120];

/* Manipulate strings */
strncpy(sent , "reqid" , 5); 
strncat(sent, "|", 1); 

/* Send UDP packet */
uip_udp_packet_send(mcast_conn, sent, strlen(sent)); 

/* Print out string sent */
printf(" (msg: %s)\n", sent); 

编辑 2:

Here is a page on heap vs stack.here is a stackoverflow question about dynamic allocation on embedded devices and the problems it involves

【讨论】:

  • 其实我看到了这个例子。为了澄清问题,我在此处插入代码:` struct my_struct { char * sent; } 我的数据,*我的数据_ptr; strncpy(my_data.sent , "reqid" , 5); strncat(my_data.sent, "|", 1); memcpy(MMEM_PTR(&mmem), &my_data, sizeof(my_data)); my_data_ptr = (struct my_struct *)MMEM_PTR(&mmem); uip_udp_packet_send(mcast_conn, my_data_ptr->sent, strlen(my_data_ptr->sent)); printf(" (msg: %s)\n", my_data_ptr->sent); mmem_free(&mmem);` 我希望看到“mg : reqid|”在输出中,但输出为 NULL。我想知道我哪里做错了。
  • @mahshid 您能否编辑您的问题以包含您尝试过的代码?你错过了对mmem_init()mmem_alloc(...) 的电话,我想......?我再次建议您尝试使用静态分配而不是动态分配,原因在我的其他 cmets 中提到(碎片导致内存耗尽)。
  • 很抱歉表示不好,我试了几次,但我不明白它是如何工作的。我添加了 mmem_init() 和 mmem_allocate() 但它仍然是一样的。 C struct my_struct { char * sent; } my_data, *my_data_ptr; mmem_init(); mmem_alloc(&mmem, 120); strncpy(my_data.sent , "reqid" , 5); strncat(my_data.sent, "|", 1); memcpy(MMEM_PTR(&mmem), &my_data, sizeof(my_data)); my_data_ptr = (struct my_struct *)MMEM_PTR(&mmem); uip_udp_packet_send(mcast_conn, my_data_ptr->sent, strlen(my_data_ptr->sent)); printf(" (msg: %s)\n", my_data_ptr->sent); mmem_free(&mmem);
  • @mahshid 我已经用一些我认为可以代替的代码更新了我的答案。我没有运行 Contiki 的任何东西,所以我无法自己测试它,但我认为您不需要您发布的 mmem-module。
猜你喜欢
  • 1970-01-01
  • 2019-02-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-03
  • 1970-01-01
相关资源
最近更新 更多