Contiki程序中malloc的用法

3
考虑以下 contiki 程序。
#include<stdio.h>
#include"contiki.h"
#include <stdlib.h>

static char *mem;
static int x;
/*---------------------------------------------------------------------------*/
PROCESS(test, "test");
AUTOSTART_PROCESSES(&test);
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(test, ev, data)
{
  PROCESS_BEGIN();
  printf("before malloc\n");
  mem=(char*)malloc(10);
  for(x=0;x<10;x++)
     mem[x]=x+1;
  printf("after malloc\n");
  PROCESS_END();
}

当这个程序编译为native/z1/wismote/cooja时,它可以完美地执行,并且两个printf语句都会被执行,但是当编译为mbxxx目标并在硬件上执行时,只有第一个printf语句被执行,代码卡在了malloc上。任何猜测或原因可以解释这种行为吗?我也在此附上GDB跟踪信息。
(gdb) mon reset init
target state: halted
target halted due to debug-request, current mode: Thread 
xPSR: 0x01000000 pc: 0x08000efc msp: 0x20000500
(gdb) b test.c:16
Breakpoint 1 at 0x8000ec8: file test.c, line 16.
(gdb) b test.c:17
Breakpoint 2 at 0x8000ece: file test.c, line 17.
(gdb) b test.c:18
Breakpoint 3 at 0x8000ed8: file test.c, line 18.
(gdb) load
Loading section .isr_vector, size 0x84 lma 0x8000000
Loading section .text, size 0xc5c4 lma 0x8000084
Loading section .data, size 0x660 lma 0x800c648
Start address 0x8000084, load size 52392
Transfer rate: 15 KB/sec, 8732 bytes/write.
(gdb) c
Continuing.
Note: automatically using hardware breakpoints for read-only addresses.

Breakpoint 1, process_thread_test (process_pt=0x2000050c <test+12>, ev=129 '\201', data=0x0) at test.c:16
16      printf("before malloc\n");
(gdb) c
Continuing.

Breakpoint 2, process_thread_test (process_pt=0x2000050c <test+12>, ev=<optimized out>, 
    data=<optimized out>) at test.c:17
17  mem=(char*)malloc(10);
(gdb) c
Continuing.
^C
Program received signal SIGINT, Interrupt.
Default_Handler () at ../../cpu/stm32w108/hal/micro/cortexm3/stm32w108/crt-stm32w108.c:87
87  {
(gdb) bt
#0  Default_Handler () at ../../cpu/stm32w108/hal/micro/cortexm3/stm32w108/crt-stm32w108.c:87
#1  <signal handler called>
#2  0x08000440 in _malloc_r ()
#3  0x08000ed4 in process_thread_test (process_pt=0x2000050c <certificate_check+12>, ev=<optimized out>, 
    data=<optimized out>) at test.c:17
#4  0x0800272c in call_process (p=0x20000500 <test>, ev=<optimized out>, data=<optimized out>)
    at ../../core/sys/process.c:190
#5  0x080028e6 in process_post_synch (p=<optimized out>, ev=ev@entry=129 '\201', data=<optimized out>)
    at ../../core/sys/process.c:366
#6  0x0800291a in process_start (p=<optimized out>, arg=arg@entry=0x0) at ../../core/sys/process.c:120
#7  0x08002964 in autostart_start (processes=<optimized out>) at ../../core/sys/autostart.c:57
#8  0x08001134 in main () at ../../platform/mbxxx/./contiki-main.c:210
(gdb)

看起来你的系统正在使用Doug Lea的malloc实现的变体。你需要一个带有调试符号的C库版本才能找出它在malloc函数内部卡住的位置。这很可能是一个特定于系统的问题,甚至可能是特定于你的安装,因此除了特定开发社区之外的其他人几乎无法为你提供帮助。祝你好运! - jxh
@jxh 这个标签是“Contiki”,它是一个嵌入式操作系统。 - errordeveloper
@errordeveloper:对不起,这是否意味着您认为我的建议是错误的,并且问题不是特定于系统或安装的? - jxh
我相信通过修改一些链接脚本参数可以解决这个问题,但我不知道该如何操作或哪一个参数。@jxh非常感谢您关于调试符号的建议,我一直在尝试,但没有进展。 - user2668988
1个回答

2

啊哈...终于找到问题所在了。这个问题的原因是stm32w108没有配置使用动态内存。

只需要打开以下文件即可:contiki-2.7/cpu/stm32w108/hal/micro/cortexm3/stm32w108/crt-stm32w108.c,并在文件顶部或_sbrk实现之前添加#define USE_HEAP!堆大小也可以在此处修改,而不是从链接器脚本中修改,尽管栈大小也可以。

附注:在嵌入式系统中使用动态内存分配是一个非常糟糕的想法,因此请避免使用它!相信我,它很危险!最终,我也会删除任何动态内存分配引用!:)


我正在尝试为lpc1347构建Contiki端口,当我尝试运行基本的LED闪烁程序时,我也犯了类似的错误,最后不得不删除所有的“printf”语句。您能否详细说明#define USE_HEAP是如何解决您的问题的? - DarthSpeedious
你的情况可能略有不同。我从来没有遇到过printf的问题,而是动态内存分配的问题。通常在许多嵌入式平台上,C运行时不支持动态内存分配,或者简单地说,堆管理不存在。在这种情况下,调用malloc会导致运行时错误。另一个重要的事情是,C运行时与处理器架构密切相关。我使用的是stm32,它与你使用的可能不同,因此在你的代码中可能根本不存在USE_HEAP开关。 - user2668988

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接