1

我正在将 CHibiOS RTOS 移植到 lm32 微处理器。

我在为设置新线程而编写的第一行代码中存在内存地址未对齐的问题。当他们试图写入内存时,其他三行已经给我一个类似的问题,但我解决了它对齐intctxcontextstruct put __attribute__((packed));

代码如下:

tp->p_ctx.sp = (struct intctx*)((uint32_t *)wsp + size - sizeof(struct intctx));
tp->p_ctx.sp->r1 = (uint32_t)arg;
tp->p_ctx.sp->r2 = (uint32_t)pf;
tp->p_ctx.sp->ra = (uint32_t)port_thread_start;

这些结构在我实现的头文件中定义:

struct intctx {
uint32_t r1;
uint32_t r2;
uint32_t r3;
uint32_t r4;
uint32_t r5;
uint32_t r6;
uint32_t r7;
uint32_t r8;
uint32_t r9;
uint32_t r10;
uint32_t r11;
uint32_t r12;
uint32_t r13;
uint32_t r14;
uint32_t r15;
uint32_t r16;
uint32_t r17;
uint32_t r18;
uint32_t r19;
uint32_t r20;
uint32_t r21;
uint32_t r22;
uint32_t r23;
uint32_t r24;
uint32_t r25;
uint32_t gp;
uint32_t fp;
uint32_t sp;
uint32_t ra;
uint32_t ea;
uint32_t ba;
} __attribute__((packed));

struct context {
struct intctx *sp;
} __attribute__((packed));

我使用 gdb 进行调试,当它尝试执行该行时:

tp->p_ctx.sp = (struct intctx*)((uint32_t *)wsp + size - sizeof(struct intctx)); 

它给出了以下问题:

core: 4 byte misaligned write to address 0x107409 at 0x100b20

Program received signal SIGBUS, Bus error.
0x00000080 in ?? ()

谁能帮我?谢谢你。


wsp 通过引用作为这些代码行所在函数的参数传递。wsp 的类型为 void *:但这是一个 Thread * 类型,wsp 指向空闲线程结构。

这行代码在 ChibiOS 支持的其他架构中以相同的功能实现,我只做了同样的事情:

tp->p_ctx.sp =  (struct intctx*)((uint32_t *)wsp + size - sizeof(struct intctx));

这是完整的功能:

Thread *chThdCreateI(void *wsp, size_t size,
                 tprio_t prio, tfunc_t pf, void *arg) {
/* Thread structure is laid out in the lower part of the thread workspace.*/
Thread *tp = wsp;

chDbgCheckClassI();

chDbgCheck((wsp != NULL) && (size >= THD_WA_SIZE(0)) &&
         (prio <= HIGHPRIO) && (pf != NULL),
         "chThdCreateI");
tp->p_ctx.sp =  (struct intctx*)((uint32_t *)wsp + size - sizeof(struct intctx));
tp->p_ctx.sp->r1 = (uint32_t)arg;
tp->p_ctx.sp->r2 = (uint32_t)pf;
tp->p_ctx.sp->ra = (uint32_t)port_thread_start;
//SETUP_CONTEXT(wsp, size, pf, arg);
return _thread_init(tp, prio);
}
4

1 回答 1

1

wsp的类型是什么?我建议不需要与存储int32_t类型适当对齐的字符数组或您定义的任何其他字符。考虑总线是如何按常规对齐以检索int32_t以 32 位为一组对齐的值的。现在考虑一下“总线错误”在架构级别上的实际含义:

  1. 需要多次获取才能检索该值(在性能方面不受欢迎),或者
  2. 您的程序出现故障(甚至更糟)

在常见的 Intel 实现中,它使用第一个选项,除非您或您的调试器向您的程序注入一些疯狂的汇编(例如,请参阅此 wikipedia 文章)。在 C 中,这只是简单的未定义行为。确保 wsp 适当对齐以指向int32_t类型。您可以通过确保它指向以下之一来做到这一点:

  1. 一个int32_t变量,或
  2. int32_t数组中的任何对象,或:
  3. malloc、calloc 或 realloc 的返回值,或者:
  4. int32_t“将 malloc/calloc/realloc 返回值视为指向“的指针的任何对象int32_t

我认为您对指针算术感到困惑。你在看哪本书?

于 2013-04-11T05:50:22.043 回答