Contiki中的内存溢出

时间:2019-04-16 07:08:09

标签: c++ c contiki cooja

我正在研究需要msp430数学函数的应用程序。使用powf,sqrt等功能时,会发生内存溢出(ROM)。一种这样的情况是,当我使用此float i变量而不使用静态变量时,我的代码有效。 enter image description here

#include "contiki.h"

#include <stdio.h> /* For printf() */
#include <math.h>
#define DEBUG DEBUG_NONE
/*---------------------------------------------------------------------------*/
PROCESS(hello_world_process, "Hello world process");
AUTOSTART_PROCESSES(&hello_world_process);
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(hello_world_process, ev, data)
{
  PROCESS_BEGIN();
  float i;
  i = 2.1;
  printf("Hello, world\n");
  printf("%i\n", (int)powf(10,i));
  PROCESS_END();
}
/*---------------------------------------------------------------------------*/

但是在第二种情况下它不起作用...

#include "contiki.h"

#include <stdio.h> /* For printf() */
#include <math.h>
#define DEBUG DEBUG_NONE
static float i;
/*---------------------------------------------------------------------------*/
PROCESS(hello_world_process, "Hello world process");
AUTOSTART_PROCESSES(&hello_world_process);
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(hello_world_process, ev, data)
{
  PROCESS_BEGIN();
  i = 2.1;
  printf("Hello, world\n");
  printf("%i\n", (int)powf(10,i));
  PROCESS_END();
}
/*---------------------------------------------------------------------------*/

建议的答案是升级msp430-gcc,但这可能会导致系统不稳定。还有其他有效处理内存溢出的建议吗?

可以遵循什么方法来有效地管理嵌入式系统中的内存。

2 个答案:

答案 0 :(得分:2)

在第一种情况下,符号i是局部的(在函数的堆栈框架上),因此编译器能够优化函数调用并在编译时计算powf(10, 2.1)的值时间。在第二种情况下,符号i是在函数外部定义的。

优化器看不到它没有被主进程外部的其他代码修改。因此,它无法优化powf,最终导致您尝试与浮点功能链接。由于msp430在硬件中不支持浮点,因此链接器最终尝试向可执行文件中添加许多二进制代码。可执行文件太大,无法链接。

升级编译器不会神奇地解决问题。您需要释放一些内存。请遵循Contiki配置准则:https://github.com/contiki-os/contiki/wiki/Reducing-Contiki-OS-firmware-size

答案 1 :(得分:0)

如果需要节省RAM,则可以考虑减少:

QUEUEBUF_CONF_NUM:链路层队列中的包数。 4可能是合理操作的下限。随着流量的增加,例如更频繁的流量或更大的数据报,则需要增加此参数。

NBR_TABLE_CONF_MAX_NEIGHBORS:邻居表中的条目数。大于最大网络密度的值是安全的。小于该值的值也将起作用,因为邻居表将自动关注相关邻居。但是值太低会导致性能下降。

NETSTACK_MAX_ROUTE_ENTRIES:路由条目的数量,即在RPL非存储模式下,路由图中的链接数,在存储模式下,路由表元素的数量。在网络根目录,必须将其设置为最大网络大小。在非存储模式下,其他节点可以将此参数设置为0。在存储模式下,建议所有节点也为网络中的每个节点提供足够的条目。 UIP_CONF_BUFFER_SIZE:IPv6缓冲区的大小。互操作性的最小值为1280。在不使用大数据报的封闭系统中,将其降低至例如。 140可能是明智的。

SICSLOWPAN_CONF_FRAG:启用/禁用6LoWPAN碎片。如果您的所有流量都适合单个链路层数据包,请禁用此功能。请注意,这还将节省一些重要的ROM。 如果需要保存ROM,可以考虑以下几点:

UIP_CONF_TCP:启用/禁用TCP。确保在未使用TCP时将其禁用。

UIP_CONF_UDP:启用/禁用UDP。确保在未使用UDP时将其禁用。

SICSLOWPAN_CONF_FRAG:如上所述。如果不需要碎片,请禁用。

LOG_CONF_LEVEL_ *:日志占用大量ROM。降低日志级别以节省更多。

还有许多其他参数会影响RAM / ROM的使用。您可以检查os / contiki-default-conf.h以及特定于平台的contiki-conf.h文件以获得灵感。或使用.flashprof和.ramprof来确定热点。

*在Contiki Wiki上的答案中:由RAM和ROM使用 乔治·奥科nomou