过去几周我一直在尝试找出为什么这不起作用。我已尝试阅读在我的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;
}