newlib init_array 仅包含 0xffffffff 和 RTEMS
newlib init_array contains only 0xffffffff with RTEMS
我正在尝试在 SAME54P20A 上移植 RTEMS。我设法制作了一个可编译的基本 BSP 和一个基本应用程序。
我使用
编译应用程序
./waf configure --rtems=$HOME/rtems/5 --rtems-bsp=arm/same54p20a
./waf
但是当运行目标上的应用程序时,它似乎永远不会到达应用程序任务。
我通过逐步执行汇编代码确定了问题。 __libc_init_array
.
期间未调用任何现有函数
这是函数的程序集:
00006ae4 <__libc_init_array>:
6ae4: b570 push {r4, r5, r6, lr}
6ae6: 4e0d ldr r6, [pc, #52] ; (6b1c <__libc_init_array+0x38>)
6ae8: 4d0d ldr r5, [pc, #52] ; (6b20 <__libc_init_array+0x3c>)
6aea: 1b76 subs r6, r6, r5
6aec: 10b6 asrs r6, r6, #2
6aee: d006 beq.n 6afe <__libc_init_array+0x1a>
6af0: 2400 movs r4, #0
6af2: 3401 adds r4, #1
6af4: f855 3b04 ldr.w r3, [r5], #4
6af8: 4798 blx r3
6afa: 42a6 cmp r6, r4
6afc: d1f9 bne.n 6af2 <__libc_init_array+0xe>
6afe: 4e09 ldr r6, [pc, #36] ; (6b24 <__libc_init_array+0x40>)
6b00: 4d09 ldr r5, [pc, #36] ; (6b28 <__libc_init_array+0x44>)
6b02: 1b76 subs r6, r6, r5
6b04: f000 fe46 bl 7794 <_init>
6b08: 10b6 asrs r6, r6, #2
6b0a: d006 beq.n 6b1a <__libc_init_array+0x36>
6b0c: 2400 movs r4, #0
6b0e: 3401 adds r4, #1
6b10: f855 3b04 ldr.w r3, [r5], #4
6b14: 4798 blx r3
6b16: 42a6 cmp r6, r4
6b18: d1f9 bne.n 6b0e <__libc_init_array+0x2a>
6b1a: bd70 pop {r4, r5, r6, pc}
6b1c: 00008914 andeq r8, r0, r4, lsl r9
6b20: 00008914 andeq r8, r0, r4, lsl r9
6b24: 00008918 andeq r8, r0, r8, lsl r9
6b28: 00008914 andeq r8, r0, r4, lsl r9
当到达地址 0x6b14 时,寄存器 r3 包含 0xffffffff,最终触发电路板复位。
这是寄存器状态:
r0 0x200016c8 536876744 r1 0xa010001 167837697 │
│r2 0x0 0 r3 0xffffffff -1 │
│r4 0x1 1 r5 0x8918 35096 │
│r6 0x1 1 r7 0x0 0 │
│r8 0x0 0 r9 0x0 0 │
│r10 0x0 0 r11 0x0 0 │
│r12 0x20000400 536871936 sp 0x20005888 0x20005888 │
│lr 0x6b09 27401 pc 0x6b14 0x6b14 <__libc_init_array+48> │
│xPSR 0x1000000 16777216 fpscr 0x0 0 │
│msp 0x20004888 0x20004888 <_ISR_Stack_area_begin+4072> psp 0x20005888 0x20005888 │
│primask 0x0 0 basepri 0x0 0 │
│faultmask 0x0 0 control 0x2 2
我想不通这是什么原因。
这是应用程序代码:
/*
* app.c
*/
#include <rtems.h>
#include <stdlib.h>
#include "bsp/same54p20a.h"
#include "bsp/port.h"
rtems_task Init(
rtems_task_argument ignored
)
{
/* Set pin PC21 as output to control LED1 */
PORT_REGS->GROUP[2].PORT_DIR |= PORT_PC21;
/* Turn on the led */
PORT_REGS->GROUP[2].PORT_OUTCLR |= PORT_PC21;
exit( 0 );
}
/*
* init.c
*/
#define CONFIGURE_APPLICATION_NEEDS_ZERO_DRIVER
#define CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER
#define CONFIGURE_MAXIMUM_TASKS 1
#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
#define CONFIGURE_INIT
#include <rtems/confdefs.h>
编辑(在 Tom V 评论之后)
寄存器 r3 由行
加载
6b10: f855 3b04 ldr.w r3, [r5], #4
所以它在地址 0x8914 处加载了垃圾(来自转储):
00008914 <__frame_dummy_init_array_entry>:
8914: 000003e9 andeq r0, r0, r9, ror #7
如果我没记错的话,r3不应该取值0x3e9
吗?
r3的值是从字面值0x6b28处的地址加载的。
文字是地址0x00008914。在反汇编中地址 0x00008914 处的是单词 0x000003e9。这意味着r3的值应该是0x000003e9,它应该调用0x000003e8处的函数(1的区别是因为这是一个互通地址,LSB中的1表示目标使用thumb指令集)。
如果您的调试器显示被调用的 r3 的值为 0xffffffff,则内存中的值与您的反汇编转储不匹配。
如果此内存是闪存 ROM,那么您的静态 linking 进程或您的 link 脚本有问题。重定位可能尚未应用于您编程的图像,但不知何故确实应用于您的转储。
如果这个内存是 RAM,那么可能有什么东西覆盖了那个值。如果您使用的是运行时 linker(在微控制器上不常见),那么它可能一开始就没有应用重定位。
除了 Tom V 分析:
问题是在创建 .hex
文件时保留了一些不需要的部分。
解决方案是在命令 objcopy
.
中添加开关 --strip-unneeded
我正在尝试在 SAME54P20A 上移植 RTEMS。我设法制作了一个可编译的基本 BSP 和一个基本应用程序。 我使用
编译应用程序./waf configure --rtems=$HOME/rtems/5 --rtems-bsp=arm/same54p20a
./waf
但是当运行目标上的应用程序时,它似乎永远不会到达应用程序任务。
我通过逐步执行汇编代码确定了问题。 __libc_init_array
.
这是函数的程序集:
00006ae4 <__libc_init_array>:
6ae4: b570 push {r4, r5, r6, lr}
6ae6: 4e0d ldr r6, [pc, #52] ; (6b1c <__libc_init_array+0x38>)
6ae8: 4d0d ldr r5, [pc, #52] ; (6b20 <__libc_init_array+0x3c>)
6aea: 1b76 subs r6, r6, r5
6aec: 10b6 asrs r6, r6, #2
6aee: d006 beq.n 6afe <__libc_init_array+0x1a>
6af0: 2400 movs r4, #0
6af2: 3401 adds r4, #1
6af4: f855 3b04 ldr.w r3, [r5], #4
6af8: 4798 blx r3
6afa: 42a6 cmp r6, r4
6afc: d1f9 bne.n 6af2 <__libc_init_array+0xe>
6afe: 4e09 ldr r6, [pc, #36] ; (6b24 <__libc_init_array+0x40>)
6b00: 4d09 ldr r5, [pc, #36] ; (6b28 <__libc_init_array+0x44>)
6b02: 1b76 subs r6, r6, r5
6b04: f000 fe46 bl 7794 <_init>
6b08: 10b6 asrs r6, r6, #2
6b0a: d006 beq.n 6b1a <__libc_init_array+0x36>
6b0c: 2400 movs r4, #0
6b0e: 3401 adds r4, #1
6b10: f855 3b04 ldr.w r3, [r5], #4
6b14: 4798 blx r3
6b16: 42a6 cmp r6, r4
6b18: d1f9 bne.n 6b0e <__libc_init_array+0x2a>
6b1a: bd70 pop {r4, r5, r6, pc}
6b1c: 00008914 andeq r8, r0, r4, lsl r9
6b20: 00008914 andeq r8, r0, r4, lsl r9
6b24: 00008918 andeq r8, r0, r8, lsl r9
6b28: 00008914 andeq r8, r0, r4, lsl r9
当到达地址 0x6b14 时,寄存器 r3 包含 0xffffffff,最终触发电路板复位。
这是寄存器状态:
r0 0x200016c8 536876744 r1 0xa010001 167837697 │
│r2 0x0 0 r3 0xffffffff -1 │
│r4 0x1 1 r5 0x8918 35096 │
│r6 0x1 1 r7 0x0 0 │
│r8 0x0 0 r9 0x0 0 │
│r10 0x0 0 r11 0x0 0 │
│r12 0x20000400 536871936 sp 0x20005888 0x20005888 │
│lr 0x6b09 27401 pc 0x6b14 0x6b14 <__libc_init_array+48> │
│xPSR 0x1000000 16777216 fpscr 0x0 0 │
│msp 0x20004888 0x20004888 <_ISR_Stack_area_begin+4072> psp 0x20005888 0x20005888 │
│primask 0x0 0 basepri 0x0 0 │
│faultmask 0x0 0 control 0x2 2
我想不通这是什么原因。
这是应用程序代码:
/*
* app.c
*/
#include <rtems.h>
#include <stdlib.h>
#include "bsp/same54p20a.h"
#include "bsp/port.h"
rtems_task Init(
rtems_task_argument ignored
)
{
/* Set pin PC21 as output to control LED1 */
PORT_REGS->GROUP[2].PORT_DIR |= PORT_PC21;
/* Turn on the led */
PORT_REGS->GROUP[2].PORT_OUTCLR |= PORT_PC21;
exit( 0 );
}
/*
* init.c
*/
#define CONFIGURE_APPLICATION_NEEDS_ZERO_DRIVER
#define CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER
#define CONFIGURE_MAXIMUM_TASKS 1
#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
#define CONFIGURE_INIT
#include <rtems/confdefs.h>
编辑(在 Tom V 评论之后) 寄存器 r3 由行
加载 6b10: f855 3b04 ldr.w r3, [r5], #4
所以它在地址 0x8914 处加载了垃圾(来自转储):
00008914 <__frame_dummy_init_array_entry>:
8914: 000003e9 andeq r0, r0, r9, ror #7
如果我没记错的话,r3不应该取值0x3e9
吗?
r3的值是从字面值0x6b28处的地址加载的。
文字是地址0x00008914。在反汇编中地址 0x00008914 处的是单词 0x000003e9。这意味着r3的值应该是0x000003e9,它应该调用0x000003e8处的函数(1的区别是因为这是一个互通地址,LSB中的1表示目标使用thumb指令集)。
如果您的调试器显示被调用的 r3 的值为 0xffffffff,则内存中的值与您的反汇编转储不匹配。
如果此内存是闪存 ROM,那么您的静态 linking 进程或您的 link 脚本有问题。重定位可能尚未应用于您编程的图像,但不知何故确实应用于您的转储。
如果这个内存是 RAM,那么可能有什么东西覆盖了那个值。如果您使用的是运行时 linker(在微控制器上不常见),那么它可能一开始就没有应用重定位。
除了 Tom V 分析:
问题是在创建 .hex
文件时保留了一些不需要的部分。
解决方案是在命令 objcopy
.
--strip-unneeded