2014-07-17 4 views
3

PIC32MX795F512L 용 부트 로더를 가져 오는 데 문제가 있습니다.Pic32 부트 로더가 메모리에 쓰는 중

마이크로 칩 웹 사이트의 예제 코드를 기반으로합니다.

다음은 메모리를 작성해야하는 코드 섹션입니다.이 시점까지는 부트 로더를 확인했습니다 (16 진수 파일을 구문 분석하고 데이터가이 지점에 도달 하나 메모리에 기록되지 않음). 로드되는 프로그램 주소

#define NVMOP_WORD_PGM   0x4001 


// Write the data into flash. 
Result = NVMemWriteWord(ProgAddress, WrData); 
// Assert on error. This must be caught during debug phase. 
if(Result != 0) 
{  
    ASSERT(Result==0); 
} 

UINT NVMemWriteWord(void* address, UINT data) 
{ 
    UINT res; 

    NVMADDR = KVA_TO_PA((unsigned int)address); 

    // Load data into NVMDATA register 
    NVMDATA = data; 

    // Unlock and Write Word 
    res = NVMemOperation(NVMOP_WORD_PGM); 

    return res; 
} 

UINT __attribute__((nomips16)) NVMemOperation(UINT nvmop) 
{ 
    int int_status; 
    int susp; 

    // Disable DMA & Disable Interrupts 
    #ifdef _DMAC 
    int_status = INTDisableInterrupts(); 
    susp = DmaSuspend(); 
    #else 
    int_status = INTDisableInterrupts(); 
    #endif // _DMAC 

    // Enable Flash Write/Erase Operations 
    NVMCON = nvmop;//NVMCON_WREN | nvmop; 
    // Data sheet prescribes 6us delay for LVD to become stable. 
    // To be on the safer side, we shall set 7us delay. 
    delay_us(7); 

    NVMKEY  = 0xAA996655; 
    NVMKEY  = 0x556699AA; 
    NVMCONSET = NVMCON_WR; 

    // Wait for WR bit to clear 
    while(NVMCON & 0x8000);//NVMCON_WR); 

    // Disable Flash Write/Erase operations 
    NVMCONCLR = NVMCON_WREN; 


    // Enable DMA & Enable Interrupts 
    #ifdef _DMAC 
    DmaResume(susp); 
    INTRestoreInterrupts(int_status); 
    #else 
    INTRestoreInterrupts(int_status); 
    #endif // _DMAC 

    // Return Error Status 
    return(NVMemIsError()); 
} 

예이다 0x9D033358 데이터는 다음과 같이 구성 비트 코드로 설정되어있다 2403000E

인 함께 :

주소

설정

1FC02FF0 FCFFFFFF

1FC02FF4 FFF8FFDF

1FC02FF8 FF69CC5B이

1FC02FFC 7FFFFFFF

이 모든 비트가 할 수 있지만 플래시 비트가 쓰기 가능으로 설정하고 코드 보호 무엇을 말할 수 없습니다 것은

사용할 수 없습니다.

+0

프로그램 단어 (쓰기) 작업을 시도하기 전에 블록 삭제 작업을 수행 했습니까? –

+0

고맙습니다. 그 문제가 해결되었습니다. 내가 +1 할 수있는 방법으로 대답을 추가하십시오. – user2076574

+1

질문에 해결책을 게시하는 것은 오류입니다. 자신의 답변으로 게시하십시오. 자신의 질문에 대답하는 것은 괜찮습니다. –

답변

4

플래시 메모리는 정상적인 RAM과 다르게 작동합니다. 쓰기를 원한다면 먼저 쓰기를 원하는 블록을 지워야합니다. 그러면 블록의 모든 비트가 1로 설정됩니다. 그런 다음 프로그램 연산을 사용하여 1 비트를 0 비트로 변경할 수 있습니다. 비트를 0 또는 1로 설정하는 쓰기 작업이 없으므로 동일한 효과를 얻으려면이 두 작업을 결합해야합니다.

먼저 지우기없이 프로그램 작업을 수행 할 수 있습니다. 그것은 1 비트를 0 비트로 바꿀 것이라는 의미에서 여전히 작동합니다. 그러나 이미 프로그래밍 된 0 비트를 1 비트로 변경할 수 없으므로 원하는 결과를 얻을 수 없습니다.

지켜야 할 한 가지 사실은 지우기 작업이 플래시 메모리를 손상시켜 서서히 착용하고 있다는 것입니다. datasheet for your controller에는 오류가 발생하기 전에 최소 1000 개의 지우기/쓰기 사이클 만 표시됩니다. 주기적인 펌웨어 업데이트 및 구성 값에는 충분하지만, 자주 업데이트되는 데이터를 저장하는 데 충분하지 않을 수 있습니다.

+0

IMO, OP가이 대답을 수락 했어야합니다.그것은 잘 편집 된 지금 "왜 이것이 메모리에 쓰지 않을 것인가에 대한 어떤 아이디어가 있는가?"라고 대답했다. – chux

2

솔루션 (로스 리지 덕분에) : 그래서 당신이 그것을 쓰기 전에 메모리를 지울 필요하다고 페이지 삭제 명령에 코멘트가 데이터 시트 노트에 묻혀 .

추가하여 문제를 해결하기 위해 다음 (메모리를하기 전에 명령이라고하는 기록이) :

다음 링크도 도움이되었다
#define FLASH_PAGE_SIZE 4096 
void StartLoad(void) 
{ 
    int Address = APP_FLASH_BASE_ADDRESS; 

    RxBuff.Len = 0; 

    while((Address + FLASH_PAGE_SIZE) <= APP_FLASH_END_ADDRESS) 
    { 
     NVMemErasePage(Address); 
     Address += FLASH_PAGE_SIZE; 
    } 
} 

UINT NVMemErasePage(void* address) 
{ 
    UINT res; 

    // Convert Address to Physical Address 
    NVMADDR = KVA_TO_PA((unsigned int)address); 

    // Unlock and Erase Page 
    res = NVMemOperation(NVMOP_PAGE_ERASE); 

    // Return WRERR state. 
    return res; 

} 

, 그것은 10 페이지에 Pic32s의 모든 플래시 페이지 크기를 나열 및 11 : http://ww1.microchip.com/downloads/en/DeviceDoc/61145K.pdf