?? 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 + -