我正在研究需要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,但这可能会导致系统不稳定。还有其他有效处理内存溢出的建议吗?
可以遵循什么方法来有效地管理嵌入式系统中的内存。
答案 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