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 + -
显示快捷键?