⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 upgrade.c

📁 C语言源代码及相关资料
💻 C
字号:
/****************************************Copyright (c)**************************************************
**                               Guangzou ZLG-MCU Development Co.,LTD.
**                                      graduate school
**                                 http://www.zlgmcu.com
**
**--------------File Info-------------------------------------------------------------------------------
** File name:			main.c
** Last modified Date:  2004-09-16
** Last Version:		1.0
** Descriptions:		The main() function example template
**
**------------------------------------------------------------------------------------------------------
** Created by:			LinEnQiang
** Created date:		2007-3-26
** Version:				1.0
** Descriptions:		IAP升级 
**------------------------------------------------------------------------------------------------------
** Modified by:			wuzhijian
** Modified date:		2007-09-02
** Version:				
** Descriptions:		对程序的风格以及注释略作调整,并检查代码。
**
** Rechecked by:		Litiantian
********************************************************************************************************/
#include "config.h"


#define	LOW				0x00010000		// LOW区首地址
#define	HIGH			0x00030000		// HIGH区首地址
//#define	Flag			0x00003000		// 用户程序标志区,0x55-运行LOW区代码,0xaa-运行HIGH区代码
#define	LED1			(1 << 15)		// P0.15控制LED1
#define	UserISP			(1 <<  6)		// 用户ISP跳线,P0.6。上电为低时,进入用户ISP代码区域

#define	RxHardFIFO_Size	8
#define	User_Flag		0x00078000		// 用户程序标志区
										// 0x10000	 -HIGH区,0x10000
										// 0xffffffff-LOW区 ,0x8000
										// 0x8000    -LOW区 ,0x8000
#define	Ethernet_RAM	0x7FE00000		// 16K 以太网SRAM起始地址
#define	User_LOW		0x00010000		// 用户程序低区入口
#define	User_HIGH		0x00030000		// 用户程序高区入口

__align(4)	uint8	*IAP_Tmp=NULL;//[4096];		// 定义4K空间,编程Flash时使用
uint8   *RcvData   = (uint8 *)Ethernet_RAM;		// 接收数据缓冲区
uint32	*FlagPoint = (uint32 *)User_Flag;		// 用户程序标志指针

volatile uint32 RcvCount;				// 接收字节数
volatile uint8  RcvOver;				// 接收完成标志 1:表示完成


/*
void SendMessage(void)
{
	
	if (*FlagPoint == HIGH)					// 当前程序运行在HIGH区,需要对LOW区进行升级
	{ 							
		uartWrite(UART0,(uint8 *)("当前程序运行在HIGH区,只能对LOW区进行升级 "), strlen("当前程序运行在HIGH区,只能对LOW区进行升级 "),NULL);				
	}
	else 
	{
		if (*FlagPoint == LOW)				// 当前程序运行在LOW区,需要对HIGH区进行升级
		{
			uartWrite(UART0,(uint8 *)("当前程序运行在LOW区,只能对HIGH区进行升级 "), strlen("当前程序运行在LOW区,只能对HIGH区进行升级 "),NULL);
		}
		else									// 当前程序运行在固件区,需要对HIGH区进行升级
		{
			uartWrite(UART0,(uint8 *)("当前程序运行在固件区,只能对HIGH区进行升级 "), strlen("当前程序运行在固件区,只能对固件区进行升级 "),NULL);
		}
	}
	
}
*/
/*********************************************************************************************************
** 函数名称: ProgramUserData
** 功能描述: 编程用户代码区。
** 入口参数: 无
** 出口参数: 无
********************************************************************************************************/
void ProgramUserData(void)
{
	uint32  Addr;					// Addr:字节偏移量
	uint32  ProgramCount;			// ProgramCount:编程到Flash扇区的字节数
	if (*FlagPoint == HIGH)		// 当前程序运行在HIGH区,需要对LOW区进行升级
	{ 	
		SelSector  (9, 12);			// 选择LOW扇区
		EraseSector(9, 12);			// 擦除LOW扇区				
	}
	else							// 当前程序运行在LOW区或者固件区,需要对HIGH区进行升级
	{
		SelSector  (13, 16);			// 选择HIGH扇区
		EraseSector(13, 16);			// 擦除HIGH扇区
	}
	
	Addr = 0;						// 字节偏移量清0
	while (RcvCount != 0)
	{			
		if (RcvCount > (1024 * 4))	// 一次最多写入4K代码量
		{
			memcpy(IAP_Tmp, RcvData + Addr, 1024 * 4);
			RcvCount 	-= (1024 * 4);
			ProgramCount = 1024 * 4;
		}		
		else
		{
			memcpy(IAP_Tmp, RcvData + Addr, RcvCount);
			ProgramCount = RcvCount;	
			RcvCount = 0;
			if ((ProgramCount == 256) || (ProgramCount == 512) || (ProgramCount == 1024) || (ProgramCount == 4096))
			{
				goto ProgramFlash;
			}
			/* 满足编程字节数的要求,256、512、1024等 */
			if (ProgramCount < 256)
			{
				ProgramCount = 256;					
				goto ProgramFlash;
			}
			if (ProgramCount < 512)
			{
				ProgramCount = 512;
				goto ProgramFlash;
			}
			if (ProgramCount < 1024)
			{
				ProgramCount = 1024;
				goto ProgramFlash;
			}
			if (ProgramCount < 4096)
			{
				ProgramCount = 4096;
				goto ProgramFlash;
			}
		}
ProgramFlash:
		/* 升级用户程序空间 */
		if (*FlagPoint == HIGH)			// 当前程序运行在HIGH区,需要对LOW区进行升级
		{
			SelSector(9, 12);				// 选择LOW扇区
			RamToFlash(User_LOW + Addr, (uint32)IAP_Tmp, ProgramCount);	// 写数据到FLASH
			Addr += ProgramCount;
		}
		else								// 当前程序运行在LOW区,需要对HIGH区进行升级
		{
			SelSector(13, 16);				// 选择HIGH扇区
			RamToFlash(User_HIGH + Addr, (uint32)IAP_Tmp, ProgramCount);// 写数据到FLASH
			Addr += ProgramCount;
		}
	}
}

/*********************************************************************************************************
** 函数名称: UpdateUserFlag
** 功能描述: 更新用户程序标志区。
** 入口参数: 无
** 出口参数: 无
********************************************************************************************************/
void UpdateUserFlag(void)
{
	uint32  *Data32Point;
	/* 更新用户程序标志空间0x4000 */
	memset(IAP_Tmp, 0xff, 256);					// 临时缓冲区清空
	Data32Point = (uint32 *)IAP_Tmp;
	if (*FlagPoint == HIGH)
	{
		*Data32Point = LOW;
	}
	else
	{
	
	 	*Data32Point = HIGH;
	  
	}
	SelSector  (22, 22);							// 选择扇区
	EraseSector(22, 22);							// 擦除扇区
	SelSector  (22, 22);							// 选择扇区
	RamToFlash(User_Flag, (uint32)IAP_Tmp, 256);// 编程FLASH
}

/*********************************************************************************************************
** 函数名称:main
** 函数功能:在线升级函数Boot代码。
********************************************************************************************************/
uint8 upgrade (void)
{	
	void (*UserProgram)();   					//函数指针
	uint32  dly;
	
	OSMemQuery(IntBuffer_Big,&MemInfo);
	if(MemInfo.OSNFree > (uint8)(0x1000/BlockSize_Big))
	{
		IAP_Tmp=(INT8U *)OSMemGet(IntBuffer_Big,&err);								// 发送提示信息
		//使用获得的内存块
		memset(IAP_Tmp, 0, 4096);					// 缓冲区清零
		memset((char *)RcvData, 0, 1024 * 8);		
	   	//if ((Read_P0() & UserISP) == 0)		
		{	
			/* 进入升级阶段 */
			//T0MAT_Init(Fpclk * 30, 0, 1, 0, 0, 1);	// 30秒钟定时
			RcvOver  = 0;
			RcvCount = 0;
			while (RcvOver == 0)
			{	
				if ((T0IR & 0x01) != 0)
				{
					T0IR     = 0x01;				// 清除中断标志					
					RcvCount = 0;
					break;							// 时间到,退出接收程序
				}			
			}
			if (RcvCount != 0)						// 升级用户代码
			{
				
				ProgramUserData();					// 编程用户代码区
				UpdateUserFlag();					// 更新用户程序标志区
				
			}
		}
		
		//释放获得的内存块
		OSMemPut(IntBuffer_Big,IAP_Tmp);
		
	}
	/* 运行用户程序 */
	
	UserProgram = (void (*)()) 0;			// 避免编译警告
	if (*FlagPoint == HIGH)
	{
		UserProgram = (void (*)()) (HIGH);
	}
	else 
	{
		if (*FlagPoint == LOW)
		{
			UserProgram = (void (*)()) (LOW);
		}
		else
		{
			//while (1)
			//{
				//P0_GPIOClr(LED1);
				for(dly = 5000000; dly != 0; dly--);
				//P0_GPIOSet(LED1);
				for(dly = 5000000; dly != 0; dly--);
			//}		
		}
	}
	(*UserProgram)();							// 启动程序
    return (0);
}
/*********************************************************************************************************
**                            End Of File
********************************************************************************************************/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -