📄 upgrade.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 + -