Contiki 中的内存溢出
Memory overflow in Contiki
我正在开发一个需要 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,但可能会导致系统不稳定。还有其他有效处理内存溢出的建议吗?
可以遵循哪些方法来有效管理嵌入式系统中的内存。
在第一种情况下,符号 i
是局部的(在函数的堆栈帧上),因此编译器能够优化函数调用并计算 powf(10, 2.1)
的值在编译时。第二种情况,符号i
定义在函数外。
优化器没有看到它没有被主进程外部的一些其他代码修改。因此它不会优化 powf
,你最终会尝试 link 具有浮点功能。由于 msp430 不支持硬件中的浮点数,linker 最终尝试向可执行文件中添加大量二进制代码。可执行文件太大,linking 失败。
升级编译器并不能神奇地解决问题。你需要释放一些内存。遵循 Contiki 配置指南:https://github.com/contiki-os/contiki/wiki/Reducing-Contiki-OS-firmware-size
如果您需要节省 RAM,您可以考虑减少:
QUEUEBUF_CONF_NUM:link层队列的包数。 4 可能是合理操作的下限。随着交通负荷的增加,例如更频繁的流量或更大的数据报,您将需要增加此参数。
NBR_TABLE_CONF_MAX_NEIGHBORS:邻居中的条目数table。大于最大网络密度的值是安全的。低于该值的值也有效,因为邻居 table 将自动关注相关邻居。但是太低的值会导致性能下降。
NETSTACK_MAX_ROUTE_ENTRIES:路由表项的个数,即在RPL非存储模式下,路由图中的link个数,在存储模式下,路由table元素。在网络根,这必须设置为最大网络大小。在非存储模式下,其他节点可以将此参数设置为0。在存储模式下,建议所有节点也为网络中的每个节点提供足够的条目。
UIP_CONF_BUFFER_SIZE:IPv6 缓冲区的大小。互操作性的最小值为 1280。在不使用大数据报的封闭系统中,将其降低到例如140可能是明智的。
SICSLOWPAN_CONF_FRAG: Enables/disables 6LoWPAN 碎片。如果您的所有流量都适合单个 link 层数据包,请禁用此选项。请注意,这也会节省一些重要的 ROM。
如果需要保存ROM,可以考虑以下:
UIP_CONF_TCP: Enables/disables TCP。确保在未使用 TCP 时禁用此功能。
UIP_CONF_UDP: Enables/disables 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 的使用
乔治·奥科诺穆
我正在开发一个需要 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,但可能会导致系统不稳定。还有其他有效处理内存溢出的建议吗?
可以遵循哪些方法来有效管理嵌入式系统中的内存。
在第一种情况下,符号 i
是局部的(在函数的堆栈帧上),因此编译器能够优化函数调用并计算 powf(10, 2.1)
的值在编译时。第二种情况,符号i
定义在函数外。
优化器没有看到它没有被主进程外部的一些其他代码修改。因此它不会优化 powf
,你最终会尝试 link 具有浮点功能。由于 msp430 不支持硬件中的浮点数,linker 最终尝试向可执行文件中添加大量二进制代码。可执行文件太大,linking 失败。
升级编译器并不能神奇地解决问题。你需要释放一些内存。遵循 Contiki 配置指南:https://github.com/contiki-os/contiki/wiki/Reducing-Contiki-OS-firmware-size
如果您需要节省 RAM,您可以考虑减少:
QUEUEBUF_CONF_NUM:link层队列的包数。 4 可能是合理操作的下限。随着交通负荷的增加,例如更频繁的流量或更大的数据报,您将需要增加此参数。
NBR_TABLE_CONF_MAX_NEIGHBORS:邻居中的条目数table。大于最大网络密度的值是安全的。低于该值的值也有效,因为邻居 table 将自动关注相关邻居。但是太低的值会导致性能下降。
NETSTACK_MAX_ROUTE_ENTRIES:路由表项的个数,即在RPL非存储模式下,路由图中的link个数,在存储模式下,路由table元素。在网络根,这必须设置为最大网络大小。在非存储模式下,其他节点可以将此参数设置为0。在存储模式下,建议所有节点也为网络中的每个节点提供足够的条目。 UIP_CONF_BUFFER_SIZE:IPv6 缓冲区的大小。互操作性的最小值为 1280。在不使用大数据报的封闭系统中,将其降低到例如140可能是明智的。
SICSLOWPAN_CONF_FRAG: Enables/disables 6LoWPAN 碎片。如果您的所有流量都适合单个 link 层数据包,请禁用此选项。请注意,这也会节省一些重要的 ROM。 如果需要保存ROM,可以考虑以下:
UIP_CONF_TCP: Enables/disables TCP。确保在未使用 TCP 时禁用此功能。
UIP_CONF_UDP: Enables/disables 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 的使用 乔治·奥科诺穆