2013-04-10 2 views
1

저는 lm32 마이크로 프로세서에 대한 CHibiOS RTOS 포트를 사용하고 있습니다.주소에 4 바이트 정렬되지 않았습니다.

새 스레드를 설정하기 위해 코드화 된 첫 번째 코드 줄에 메모리 주소가 잘못 정렬되는 문제가 있습니다. 다른 세 줄은 이미 메모리에 쓰려고 할 때 비슷한 문제를주었습니다. 그러나 나는 intctxcontext을 두는 구조를 __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; 

구조체

날에 의해 구현 된 헤더 파일에 정의되어 있습니다 : 내가 디버그 GDB를 사용

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)); 

가 줄을 실행하려고 할 때 :

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 * : 입니다. 그러나 이것은 스레드 * 유형이며, 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); 
} 
+3

어떻게 포장이 불일치 문제를 해결할 수 있습니까? –

+2

디버거에서 토론중인 줄을 실행하기 전에'wsp'와'size'의 값을 확인하려 했습니까? – Ganesh

답변

1

무엇 인 wsp의 유형? char 배열이나 다른 것으로 정의하는 것이 무엇이든간에 int32_t 유형을 저장하기 위해 적절히 정렬 할 필요는 없다고 제안합니다. 버스가 32 비트 그룹으로 정렬 된 int32_t 값을 검색하기 위해 일반적으로 정렬되는 방법을 고려하십시오. 이제 "버스 오류가"실제로 아키텍처 수준에서 의미 할 것을 고려하십시오

  1. 하나는 (성능면에서 바람직하지 않은) 값 또는
  2. 귀하의 프로그램 오작동을 (더 나쁜) 검색하는 데 필요한 페치보다 더

일반 인텔 구현에서 사용자 또는 디버거가 프로그램에 일부 어셈블리 광기를 주입하지 않는 한 첫 번째 옵션을 사용합니다 (예 : this wikipedia article 참조). C에서는 정의되지 않은 동작 일뿐입니다. wsp가 int32_t 유형을 가리 키도록 적절하게 정렬되어 있는지 확인하십시오.malloc에,은 calloc realloc에의

  • 반환 값 :

    1. int32_t 변수 또는
    2. 모든 int32_t 객체 배열 내에서, 또는 : 당신은 이들 중 하나를 가리키는 것을 보장하여이 작업을 수행 할 수 있습니다 또는 :
    3. int32_t의 객체는 "int32_t에 대한 포인터로 처리되는 malloc/calloc/realloc 반환 값"의 객체입니다.

    나는 포인터 연산과 관련하여 혼란 스럽다고 생각합니다. 어느 책을 읽고 있니?

  • +0

    wsp는 코드 라인이있는 함수의 매개 변수로 참조로 전달됩니다. – user2268131

    관련 문제