2013-08-13 3 views
3

SAM4S 용 부트 로더를 작성했는데 섹터 0에 앉아서 섹터 1에 응용 프로그램을로드합니다. 그러나 문제는 새로운 기능으로 이동하려고 시도 할 때 예외가 발생하는 것입니다 (디버거는 Dummy_Handler()로갑니다).부트 로더에서 점프하면 예외가 발생합니다.

.application 0x00410000  0x0 
       0x00410000    . = ALIGN (0x4) 
       0x00410000    _sappl = . 
       0x00410004    _sjump = (. + 0x4) 

응용 프로그램 이미지 맵 파일이 있습니다 :

const DeviceVectors exception_table = { 

     /* Configure Initial Stack Pointer, using linker-generated symbols */ 
     .pvStack = (void*) (&_estack), 

     .pfnReset_Handler  = (void*) Reset_Handler, 

부트 로더는 선언 다음과 같이

.vectors  0x00410000  0xd0 src/ASF/sam/utils/cmsis/sam4s/source/templates/gcc/startup_sam4s.o 
       0x00410000    exception_table 
… 
.text.Reset_Handler 
       0x0041569c  0x100 src/ASF/sam/utils/cmsis/sam4s/source/templates/gcc/startup_sam4s.o 
       0x0041569c    Reset_Handler 

예외 테이블이 정의

부트 로더는지도에서 다음 항목이 포함 응용 프로그램 점프 포인트 :

다음
extern void (*_sjump)(); 

하고 다음 호출을 : 0x00410004에서

_sjump(); 

메모리 내용이 0x0041569d이고, 나는이 단어가 정렬되지 않은 것을 알 수 있습니다. 우리가 Thumb 명령어를 사용하고 있기 때문입니까? 어느 쪽이든 0x0041569c가 아닌 이유는 무엇입니까? 아니면 더 중요한 것은 왜 이것이 예외가 될까요?

감사합니다,

데반 ​​

업데이트 :this 발견하지만 나를 위해 작동하는 것처럼하지 않습니다

void (*user_code_entry)(void); 
unsigned *p; 
p = (uint32_t)&_sappl + 4; 
user_code_entry = (void (*)(void))(*p - 1); 

if(applGood && tempGood) { 
    SCB->VTOR = &_sappl; 

    PrintHex(p); 
    PrintHex(*p); 
    PrintHex(user_code_entry); 

    user_code_entry(); 

} 

코드 인쇄 : 0041569D 0041569C

업데이트 업데이트 : C 함수 포인터를 이동하려고 시도하는 코드는 다음과 분해를 생산 :

--- D:\Zebra\PSPT_SAM4S\PSPT_SAM4S\SAM4S_PSPT\BOOTLOADER\Debug/.././BOOTLOADER.c 
user_code_entry(); 
004005BA ldr r3, [r7, #4]  
004005BC blx r3 

나는이하여 다음 작업을 얻을 수있었습니다 :

"mov r1, r0  \n" 
"ldr r0, [r1, #4] \n" 
"ldr sp, [r1]  \n" 
"blx r0" 

기반을 이것에 대한 스택 리셋이 필요한지 궁금한 점이 있다면 C에서 그렇게 할 수 있습니까?

+0

CPU의 보호 모드 일 수 있습니다. 보호 지역 외부의 메모리에 액세스 할 수 있도록 변경해야 할 수도 있습니다. – Magn3s1um

+0

@ Magn3s1um 내 부트 로더가 MPU를 구성한 것처럼 보이지 않습니다. – devanl

+0

'sjmp' 함수의 주소는 무엇입니까? 부트 로더에'jmp','b' 명령어가 보이지 않습니다. 네 라인이 모두 확실합니까? 부트 로더의 C 또는 어셈블러 코드를 게시하십시오 (그리고 어쩌면 해체 할 수도 있습니다). – RedX

답변

2

SAM4E에서도 동일한 문제가있었습니다. 나는 당신의 문제가 무엇인지 짐작할 수는 없지만 내가 가지고있는 어려움과 내가 사용한 정보를 지적 할 수있다.

내 부트 로더가 펌웨어의 몇 부분을 올바른 메모리 위치에 저장하지 못했습니다. 이것은 dummy_handler 예외로 이어졌습니다. 주소 계산에서 오류를 수정했을 때 부트 로더는 완벽하게 작동했습니다.

내 제안 :

  • 따르 ATMEL의 예 : DocumentExample Code이 충분합니다. main.c는 부트 로더가 어떻게 작동하는지 이해하기에 충분합니다.처음에는 파티션 세부 사항에 들어갈 필요가 없습니다.
  • 당신은 어떻게 읽을 수 있습니다 execute functions/ISRs from RAM
  • This webpage는 인텔 HEX 형식을 설명합니다.
  • 마지막으로 업그레이드로 부트 로더가 완료되면 플래시를 읽고 호스트 컴퓨터로 다시 보낼 수 있습니다. 그런 다음 원본 이미지와 비교하십시오 (스크립트 사용). 이것이 내가 부트 로더를 디버깅 한 방법입니다. 당신이 그것을 쓰기 전에

    • 는 각 페이지를 삭제 마십시오 도움이 될 수 있습니다

    다른 아이디어?

  • 지우기/쓰기 전에 각 메모리 공간을 잠금 해제합니까?
  • 실수로 덮어 쓰지 않도록 부트 로더 섹션을 잠글 수 있습니다.
  • 업그레이드 된 펌웨어의 섹션을 잠글 수 있습니다.

주소는 0x00410000이 아닌 0x00410004입니다. Atmel의 예제 코드 (함수 binary_exec 참조)와 Intel Hex 형식 (레코드 유형 05)을 함께 사용해야이 질문을 해결할 수 있습니다.

이 정보가 도움이되기를 바랍니다.

1

나는이 질문에 나를 데려온 SAM4S에 동일한 문제가 있었다. 그래서 누군가 다시 여기에 도착한다면, 여기 내가 찾은 것이 있습니다. ChrisB가 Atmel 예제 코드를 언급하면서 좋은 시작이지만 문제는 SAM4S에서 작동하지 않는 점프를 요청하는 실제 코드라는 것을 알았습니다. 누락 된 부분은 벡터 테이블 앞에 스택 포인터를 리베이스 한 다음 리셋 처리기 주소를로드하는 것입니다. 다음과 같이 시도하십시오.

static void ExecuteApp(void) 
{ 
    uint32_t i; 

    // Pointer to the Application Section 
    void (*application_code_entry)(void); 

    // -- Disable interrupts and system timer 

    __disable_irq(); 
    SysTick->CTRL = 0; // Disable System timer 

    // disable and clear pending IRQs 
    for (i = 0; i < 8; i++) 
    { 
     NVIC->ICER[i] = 0xFFFFFFFF; // disable IRQ 
     NVIC->ICPR[i] = 0xFFFFFFFF; // clear pending IRQ 
    } 


    // Barriers 
    __DSB(); // data synchronization barrier 
    __ISB(); // instruction synchronization barrier 

    // Rebase the Stack Pointer 
    __set_MSP(*(uint32_t *) APPCODE_START_ADDR); 

    // Rebase the vector table base address 
    SCB->VTOR = ((uint32_t) APPCODE_START_ADDR & SCB_VTOR_TBLOFF_Msk); 

    // Load the Reset Handler address of the application 
    application_code_entry = (void (*)(void))(unsigned *)(*(unsigned *) 
           (APP_START_RESET_VEC_ADDRESS)); 

    __DSB(); 
    __ISB(); 

    // -- Enable interrupts 
    __enable_irq(); 

    // Jump to user Reset Handler in the application 
    application_code_entry(); 

} 
관련 문제