binload.c
来自「完整的基于Xmodem协议的嵌入式系统侧FLASH Loader程序。该程序是基」· C语言 代码 · 共 973 行 · 第 1/3 页
C
973 行
ONSF |= 0x10; /*/ OneShort开始。 /*/
c = 0; /*/ 在NAKTimer的Count中使用。 /*/
bStatus = 2; /*/ XModem的开始等待状态。 /*/
} else if (c == 'R' || c == 'r') { /*/ Reset时 /*/
PRCR |= 0x02; /*/ ProtectRegister的Bit1设为1。 /*/
PM0 |= 0x08; /*/ SoftwareReset。 /*/
}
break;
}
}
} /*/ 无限Loop的中止。 /*/
}
/////////////////////////////////////////////////////////////////////////////
/*/// StartProgram : Flash写入的开始 /*/
BOOL StartProgram(BYTE* info)
{
BYTE i;
DWORD tmpaddress;
P9 &= ~0x40; /*/ 开始下载,熄灭红指示灯 /*/
P9 |= 0x80; /*/ 开始下载,点亮绿指示灯 /*/
if(BinFileHeader.Struct.Flag ==0xffff) /*/新的处理模式下计算机侧没有找到匹配的FLASH类型/*/
{
return FALSE;
}
else if(BinFileHeader.Struct.Flag ==0) /*/新的处理模式/*/
{
lpabFlashMemory = (BYTE far*)BinFileHeader.Struct.StartAddress;
lpabFlashMemoryEnd = (BYTE far*)BinFileHeader.Struct.StopAddress;
for(i=0;i<112;i++)
{
tmpaddress = ((DWORD)BinFileHeader.Struct.SectorStartAddress[i])<<8;
if(tmpaddress== (DWORD)lpabFlashMemory)
{
SectorStartAddressIndex = i;
break;
}
else if(tmpaddress> (DWORD)lpabFlashMemory) /*/大于则意味着没有找到正确的地址或已经到了边界表的最后了/*/
{
return FALSE;
}
}
}
else
{
return FALSE; /*/不支持超级终端下载了/*/
}
FlashReset(); //Reset to exit read Manufacture ID mode.
P9 |= 0x02; /*/ Flash的WriteProtect的解除。 /*/
return TRUE; /*/ 写入开始OK。/*/
}
/////////////////////////////////////////////////////////////////////////////
/*/ WritePage : Flash的Page写入 /*/
BOOL WritePage(BYTE* src)
{
UINT i; //counter
BYTE toggle1, toggle2;
asm("BNOT 7, 03F1h"); /*/ 绿指示灯闪烁 /*/
/*/新的处理模式/*/
if ( lpabFlashMemoryEnd < lpabFlashMemory)
{ /*/ Memory空间的最终Address超过的话、写入终了Address超过的话,/*/
return TRUE; /*/ 什么也不作。/*/
}
if((DWORD)lpabFlashMemory == (((DWORD)BinFileHeader.Struct.SectorStartAddress[SectorStartAddressIndex])<<8))
{
SectorStartAddressIndex++;
if(FlashEraseSector((DWORD)lpabFlashMemory) == FALSE) //failed
{
return FALSE;
}
}
switch(BinFileHeader.Struct.WriteMode)
{
case 0:
for (i = 0; i <= 0xFF; i ++)
{ /*/ 从00到FF进行重复。/*/
/*/FLASH write. 没有定义成函数主要考虑效率原因 /*/
BANKREG &= 0x40;
*((BYTE far*)(0x28aaa)) = 0xAA;
*((BYTE far*)(0x28555)) = 0x55;
*((BYTE far*)(0x28aaa)) = 0xa0;
if((DWORD)lpabFlashMemory < 0x130000)
{
//BANKREG |= 0x3f;
BANKREG = (BYTE)((DWORD)lpabFlashMemory >> 15);
WriteAddress = ((DWORD)lpabFlashMemory & 0x00007fff) + 0x28000;
}
else
{
WriteAddress = (DWORD)lpabFlashMemory & 0xfffff;
}
*((BYTE far*)(WriteAddress)) = src[i];
//toggle check
do
{
toggle1 = *((BYTE far*)(WriteAddress));
toggle1 &= 0x40;
toggle2 = *((BYTE far*)(WriteAddress));
toggle2 &= 0x40;
}while(toggle1 != toggle2);
lpabFlashMemory ++; /*/地址增加 /*/
}
break;
case 1:
for (i = 0; i <= 0xFF; i ++)
{ /*/ 从00到FF进行重复。/*/
/*/FLASH write. 没有定义成函数主要考虑效率原因 /*/
BANKREG = 1;
*((BYTE far*)(0x2aaaa)) = 0xAA; //(* 0xaaaa = 0xaa);
BANKREG = 0;
*((BYTE far*)(0x2d555)) = 0x55; //(* 0x5555 = 0x55);
BANKREG = 1;
*((BYTE far*)(0x2aaaa)) = 0xa0; //(*0xaaaa = 0xa0);
if((DWORD)lpabFlashMemory < 0x130000)
{
// BANKREG |= 0x3f;
BANKREG = (BYTE)((DWORD)lpabFlashMemory >> 15);
WriteAddress = ((DWORD)lpabFlashMemory & 0x00007fff) + 0x28000;
}
else
{
WriteAddress = (DWORD)lpabFlashMemory & 0xfffff;
}
*((BYTE far*)(WriteAddress)) = src[i];
//toggle check
do
{
toggle1 = *((BYTE far*)(WriteAddress));
toggle1 &= 0x40;
toggle2 = *((BYTE far*)(WriteAddress));
toggle2 &= 0x40;
}while(toggle1 != toggle2);
lpabFlashMemory ++; /*/地址增加 /*/
}
break;
case 2:
for (i = 0; i <= 0xFF; i ++)
{ /*/ 从00到FF进行重复。/*/
/*/FLASH write. 没有定义成函数主要考虑效率原因 /*/
if((DWORD)lpabFlashMemory < 0x130000)
{
// BANKREG |= 0x3f;
BANKREG = (BYTE)((DWORD)lpabFlashMemory >> 15);
WriteAddress = ((DWORD)lpabFlashMemory & 0x00007fff) + 0x28000;
}
else
{
WriteAddress = (DWORD)lpabFlashMemory & 0xfffff;
}
*((BYTE far*)(WriteAddress)) = 0x70; //0x70:read status, addr : don't care
do{
toggle1 = *((BYTE far*)(WriteAddress));
}while ( (toggle1 & 0x80) == 0 ); // read status, while busy , waiting
*((BYTE far*)(WriteAddress)) = 0x40; //write byte set up
*((BYTE far*)(WriteAddress)) = src[i];
do{
toggle1 = *((BYTE far*)(WriteAddress));
}while ( (toggle1 & 0x80) == 0 ); // read status, while busy , waiting
lpabFlashMemory ++; /*/地址增加 /*/
}
*((BYTE far*)(WriteAddress)) = 0xff; //0xff:reset
break;
}
return TRUE; /*/ 正常终了。/*/
}
/////////////////////////////////////////////////////////////////////////////
/*/ StopProgram : Flash写入的终了 /*/
void StopProgram(void)
{
P9 &= (~0x2); /*/ Flash设为LockBit有效。/*/
P9 |= 0x40; /*/ 下载完毕,点亮红指示灯 /*/
P9 &= 0x7f; /*/ 下载完毕,熄灭绿指示灯 /*/
FlashReset();
return;
}
/////////////////////////////////////////////////////////////////////////////
/*/ OnRxXModem : XModem的Data受信 /*/
BYTE OnRxXModem(void)
{
BYTE c; /*/ 为了数据的发送的变量。 /*/
BYTE result = 5; /*/ 返回值。5=受信中、4=XModem的终了、0,1,2,3=受信完了的Buffer的Block /*/
ReadUART(&c, 1); /*/ Data的受信。 /*/
cbXModemRxCharacter ++; /*/ XModem的DataBlock受信Byte数的增加。 /*/
switch (cbXModemRxCharacter) { /*/ 受信Byte数。 /*/
case 1 : /*/ Header受信 /*/
if (c == EOT) { /*/ EOT的受信时 /*/
c = ACK; /*/ ACK的装入。 /*/
WriteUART(&c, 1); /*/ ACK的送信。 /*/
return 4; /*/ 处理的中止。 /*/
} else {
szDial[0] = c; /*/ DialBuffer中,装入Header。 /*/
}
break;
case 2 : /*/ Block号码受信 /*/
szDial[1] = c; /*/ DialBuffer中,装入Block号码。 /*/
break;
case 3 : /*/ Block号码的补数受信 /*/
szDial[2] = c; /*/ DialBuffer中,Block号码的补数的装入。 /*/
szDial[3] = 0; /*/ XModem的DataBlock的CheckSum的清除。 /*/
break;
case 132 : /*/ CheckSum受信 /*/
if (szDial[0] != SOH) { /*/ Header和SOH不一样时 /*/
c = NAK; /*/ NAK的装入。 /*/
WriteUART(&c, 1); /*/ NAK的送信。 /*/
cbXModemRxCharacter = 0; /*/ 受信Byte数进行初始化。 /*/
} else if (szDial[1] != ~szDial[2]) { /*/ 受信的Block号码和其补数不一致时 /*/
c = NAK; /*/ NAK的装入。 /*/
WriteUART(&c, 1); /*/ NAK的送信。 /*/
cbXModemRxCharacter = 0; /*/ 受信Byte数进行初始化。 /*/
} else if (szDial[1] == bXModemSequenceBlockNumber) { /*/ 和受信的Block号码一样时 /*/
c = ACK; /*/ ACK的装入。 /*/
WriteUART(&c, 1); /*/ ACK的送信。 /*/
cbXModemRxCharacter = 0; /*/ 受信Byte数进行初始化。 /*/
} else if (!((szDial[1] == (char)(bXModemSequenceBlockNumber + 1)) || (bXModemSequenceBlockNumber == 0xFF && szDial[1] == 1))){ /*/ 和受信的Block号码的下一个的号码不一样时 /*/
c = CAN; /*/ CAN的装入。 /*/
WriteUART(&c, 1); /*/ CAN的送信。 /*/
} else if (szDial[3] != c) { /*/ CheckSum不一样时 /*/
c = NAK; /*/ NAK的装入。 /*/
WriteUART(&c, 1); /*/ NAK的送信。 /*/
cbXModemRxCharacter = 0; /*/ 受信Byte数进行初始化。 /*/
} else {
result = bXModemWritingBlock; /*/ 返回值的受信完了的Block号码偵。 /*/
abXModemFreeBlock[bXModemWritingBlock] = 1; /*/ Block设为使用中。 /*/
bXModemWritingBlock = (bXModemWritingBlock + 1) & 0x03; /*/ Block号码的增加。(因为是0-3,仅仅下位2Bit有效) /*/
npabXModemFileWrite = abXModemFileWrite + 128 * bXModemWritingBlock; /*/ 受信Data的写入Pointer的更新。 /*/
/*/ Block受信完了时的ACK在写入终了后返回。 /*/
/*/ c = ACK; ACK的装入。 /*/
/*/ WriteUART(&c, 1); ACK的送信。 /*/
cbXModemRxCharacter = 0; /*/ 受信Byte数进行初始化。 /*/
bXModemSequenceBlockNumber = szDial[1]; /*/ 受信的Block号码的更新 /*/
}
break;
default : /*/ Text受信 /*/
if (abXModemFreeBlock[bXModemWritingBlock] == 0) { /*/ Block为空时 /*/
* (npabXModemFileWrite + cbXModemRxCharacter - 4) = c; /*/ 受信Data写入。 /*/
szDial[3] += c; /*/ CheckSum的计算。 /*/
}
break;
}
return result;
}
/////////////////////////////////////////////////////////////////////////////
/*/ ReadUART : 从UART读入Data。(Buffer的Data的读出。) /*/
BYTE ReadUART(BYTE* buffer, BYTE size)
{
BYTE i; /*/ Counter。 /*/
for (i = 0; i < size; i ++) {
if (!PopRingBuffer(&UARTRx, &buffer[i])) { //
return i; /*/ 返回取出的数据。 /*/
}
}
return i; /*/ 返回取出的数据。 /*/
}
/////////////////////////////////////////////////////////////////////////////
/*/ WriteUART : 向UART写入Data时。(Buffer中,Data的写入。) /*/
BYTE WriteUART(BYTE far * buffer, BYTE size)
{
BYTE i; /*/// Counter。 /*/
for (i = 0; i < size; i ++) {
if (!PushRingBuffer(&UARTTx, buffer[i])) {
UARTTxOn(); /*/ Data送信的开始。 /*/
return i; /*/ 返回写入的数据。 /*/
}
}
UARTTxOn(); /*/ Data送信的开始。 /*/
return i; /*/ 返回写入的数据。 /*/
}
////////////////////////////////////////////////////////////////////////////
/*/ FlashUART : UART的送受信Buffer设为空。 /*/
void FlashUART(void)
{
UARTTx.cbData = 0; /*/ Data数的清除。 /*/
UARTTx.bWriteIndex = 0; /*/ 写入位置设为先头。 /*/
UARTTx.bReadIndex = 0; /*/ 读入位置设为先头。 /*/
UARTRx.cbData = 0; /*/ Data数的清除。 /*/
UARTRx.bWriteIndex = 0; /*/ 写入位置设为先头。 /*/
UARTRx.bReadIndex = 0; /*/ 读入位置设为先头。 /*/
}
/////////////////////////////////////////////////////////////////////////////
/*/ PushRingBuffer : RingBuffer中,Data的装入。 /*/
BOOL PushRingBuffer(PRINGBUFF buffer, BYTE data)
{
if (buffer->cbData == buffer->bSize) { /*/ Data数和BufferSize一样时 /*/
return FALSE; /*/ 返回:不能向Buffer中追加。 /*/
}
asm("fclr I"); /*/ 中断禁止。 /*/
buffer->abData[buffer->bWriteIndex] = data; /*/ Buffer的写入位置中,Data的装入。 /*/
buffer->cbData ++; /*/ Data数的增加。 /*/
asm("fset I"); /*/ 中断许可。 /*/
buffer->bWriteIndex ++; /*/ 写入位置的增加。 /*/
if (buffer->bWriteIndex >= buffer->bSize) { /*/ 写入位置为BufferSize以上时 /*/
buffer->bWriteIndex = 0; /*/ 写入位置设为先头。 /*/
}
return TRUE; //
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?