0

过去几周我一直在尝试找出为什么这不起作用。我已尝试阅读在我的PIC32 MCU ( PIC32MX795F512L ) 和我正在使用的XC32编译器 (v1.34) 上可以找到的所有文档,但目前还没有成功。

我需要一个特殊的常量值写入物理引导闪存地址0x1FC02FEC虚拟地址:)0x9FC02FEC。这个常数是0x3BDFED92

pic32通过以下命令行(我在xc32-ld项目属性下的“附加选项”下放置),我已经成功地在我的主程序(如果我直接使用 Real ICE 编程)上做到了这一点:

--fill=0x3bdfed92@0x9FC02FEC

然后我可以检查(在我的主程序中)这个地址是否确实存储了正确的值,这也有效。我为此使用以下代码:

if(*(int *)(0x9fc02fec) == 0x3bdfed92)

我的问题如下。我不希望我的主程序十六进制文件将常量写入该位置。我希望我的引导加载程序十六进制文件执行此操作,并且我的主程序必须能够读取该位置并查看该常量是否存在。如果我在引导加载程序中使用 --fill 命令xc32-ld,它会像主程序一样成功写入常量(我已经通过在调试模式下使用相同的 --fill 命令运行引导加载程序并检查0x1FC02FEC地址来测试这一点为常数)。问题是,当我的引导加载程序通过 MicroSD 读入一个新的主程序,然后跳转到新的主程序时,一切都不起作用。似乎,在它跳转到新的主程序之前,发生了一些不好的事情,一切都崩溃了。几乎就像向1FC02FEC当程序从引导加载程序跳转到主程序时,位置是一个问题。

是否有一个原因?我希望我的解释是好的,如果不是,请让我知道,我会尝试以更容易理解的方式改写它。

我正在使用 Microchip 提供的示例代码来使用 MicroSD 卡执行引导加载程序。以下是代码:

int main(void)
{
    volatile UINT i;
    volatile BYTE led = 0;

    // Setup configuration
    (void)SYSTEMConfig(SYS_FREQ, SYS_CFG_WAIT_STATES | SYS_CFG_PCACHE);

    InitLED();
    TRISBbits.TRISB14 = 0;
    LATBbits.LATB14 = 0;

    ClrWdt();

    // Create a startup delay to resolve trigger switch bouncing issues
    unsigned char x;
    WORD ms = 500;
    DWORD dwCount = 25;

    while(ms--)
    {
        ClrWdt();
        x=4;
        while(x--)
        {
            volatile DWORD _dcnt;

            _dcnt = dwCount*((DWORD)(0.00001/(1.0/GetInstructionClock())/10));
            while(_dcnt--)
            {
                    #if defined(__C32__)
                            Nop();
                            Nop();
                            Nop();
                    #endif
            }
        }
    }


    if(!CheckTrigger() && ValidAppPresent())
    {
        // This means the switch is not pressed. Jump
        // directly to the application

        JumpToApp();        
    }
    else if(CheckTrigger() && ValidAppPresent()){

        if(MDD_MediaDetect()){
            if(FSInit()){
                myFile = FSfopen("image.hex","r");

                if(myFile == NULL){
                    JumpToApp();
                }
            }
            else{
                JumpToApp();
            }
        }
        else{
            JumpToApp();
        }

    }

    //Initialize the media
    while (!MDD_MediaDetect())
    {
        // Waiting for media to be inserted.
        BlinkLED();
    }

    // Initialize the File System
    if(!FSInit())
    {
         //Indicate error and stay in while loop.
         Error();
         while(1);
    }


    myFile = FSfopen("image.hex","r");

    if(myFile == NULL)// Make sure the file is present.
    {
        //Indicate error and stay in while loop.
         Error();
         while(1);
    }     

    // Erase Flash (Block Erase the program Flash)
    EraseFlash();
    // Initialize the state-machine to read the records.
    record.status = REC_NOT_FOUND;

     while(1)
     {
         ClrWdt();

         // For a faster read, read 512 bytes at a time and buffer it.
         readBytes = FSfread((void *)&asciiBuffer[pointer],1,512,myFile);

         if(readBytes == 0)
         {
             // Nothing to read. Come out of this loop
             // break;
             FSfclose(myFile);
             // Something fishy. The hex file has ended abruptly, looks like there was no "end of hex record".
             //Indicate error and stay in while loop.
             Error();
             while(1);             
         }

         for(i = 0; i < (readBytes + pointer); i ++)
         {

          // This state machine seperates-out the valid hex records from the read 512 bytes.
             switch(record.status)
             {
                 case REC_FLASHED:
                 case REC_NOT_FOUND:
                     if(asciiBuffer[i] == ':')
                     {
                      // We have a record found in the 512 bytes of data in the buffer.
                         record.start = &asciiBuffer[i];
                         record.len = 0;
                         record.status = REC_FOUND_BUT_NOT_FLASHED;
                     }
                     break;
                 case REC_FOUND_BUT_NOT_FLASHED:
                     if((asciiBuffer[i] == 0x0A) || (asciiBuffer[i] == 0xFF))
                     {
                      // We have got a complete record. (0x0A is new line feed and 0xFF is End of file)
                         // Start the hex conversion from element
                         // 1. This will discard the ':' which is
                         // the start of the hex record.
                         ConvertAsciiToHex(&record.start[1],hexRec);
                         WriteHexRecord2Flash(hexRec);
                         record.status = REC_FLASHED;
                     }
                     break;
             }
             // Move to next byte in the buffer.
             record.len ++;
         }

         if(record.status == REC_FOUND_BUT_NOT_FLASHED)
         {
          // We still have a half read record in the buffer. The next half part of the record is read 
          // when we read 512 bytes of data from the next file read. 
             memcpy(asciiBuffer, record.start, record.len);
             pointer = record.len;
             record.status = REC_NOT_FOUND;
         }
         else
         {
             pointer = 0;
         }
         // Blink LED at Faster rate to indicate programming is in progress.
         led += 3;
         mLED = ((led & 0x80) == 0);

     }//while(1)


    return 0;
}
4

2 回答 2

1

如果我记得很清楚(很久以前我使用过 PIC32),您可以在链接描述文件中添加:

MEMORY
{
   //... other stuff
   signature (RX) : ORIGIN = 0x9FC02FEC, length 0x4
} 

然后

SECTIONS
{
   .signature_section:
   {
      BYTE(0x3b);
      BYTE(0xdf);
      BYTE(0xed);
      BYTE(0x92);
   }>signature
}

谷歌搜索我还发现,你可以在你的源代码中做到这一点,我希望......

const int __attribute__((space(prog), address(0x9FC02FEC))) signature = 0x3bdfed92; 
于 2016-03-14T14:00:40.893 回答
0

在我的程序中,我使用属性将某个值放置在内存空间中的某个位置。我的引导加载程序和应用程序可以读取此位置。这可能是您执行此操作的更简单方法。这是使用 xc16 和较小的部分,但我也在 PIC32 上完成了它。

#define CHECK_SUM 0x45FB
#define CH_HIGH ((CHECK_SUM & 0xFF00) >> 8)
#define CH_LOW  ((CHECK_SUM & 0x00FF) >> 0)
const char __attribute__((space(prog), address(APP_CS_LOC))) CHKSUM[2] = {CH_LOW,CH_HIGH};

请注意,当您阅读它时,它将采用正确的格式:HIGH->LOW

于 2016-03-14T14:13:04.837 回答