1

我正在开发一个需要 msp430 数学函数的应用程序。在使用这些函数时,例如 powf、sqrt 等,会发生内存溢出 (ROM)。一种这样的情况是,当我使用这个 float i 变量而不使用静态时,我的代码可以工作。 在此处输入图像描述

#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,但这可能会导致系统不稳定。还有其他有效处理内存溢出的建议吗?

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

4

2 回答 2

2

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

优化器看不到它没有被主进程外部的一些其他代码修改。因此,它不会优化powf离开,并且您最终会尝试与浮点功能链接。由于 msp430 在硬件中不支持浮点,因此链接器最终会尝试将大量二进制代码添加到可执行文件中。可执行文件太大,链接失败。

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

于 2019-04-17T10:33:51.137 回答
1

如果需要节省 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 上回答:George Oikonomou 的 RAM 和 ROM 使用

于 2019-04-17T12:00:42.937 回答