📄 +
字号:
/****************************************Copyright (c)****************************************************
** Guangzhou ZHIYUAN electronics Co.,LTD.
**
** http://www.embedtools.com
**
**--------------File Info---------------------------------------------------------------------------------
** File Name: Main.c
** Last modified Date: 2008.08.20
** Last Version: v1.0
** Description: 远程升级BootLoader
**
**--------------------------------------------------------------------------------------------------------
** Created By: Weng Heiwei
** Created date: 2008.08.20
** Version: v1.0
** Descriptions:
**
********************************************************************************************************/
#include "config.h"
/*********************************************************************************************************
** 函数名称: SendMessage
** 功能描述: 发送提示信息。
** 入口参数: 无
** 出口参数: 无
*********************************************************************************************************/
void SendMessage(void)
{
if(HWREG(LOW_Addr) == 0xFFFFFFFF) { /* 判断LOW区的程序是否有效 */
Uart0Send("有效程序在HIGH区,请选择更新LOW区文件。\r\n");
} else if(HWREG(HIGH_Addr) == 0xFFFFFFFF) {
Uart0Send("有效程序在LOW区,请选择更新HIGH区文件。\r\n"); /* 判断HIGH区的程序是否有效 */
}
}
/*********************************************************************************************************
** 函数名称: SysInit
** 功能描述: 系统初始化
** 入口参数: 无
** 出口参数: 无
********************************************************************************************************/
void SysInit(void)
{
SysCtlClockSet(SYSCTL_SYSDIV_10 | SYSCTL_USE_PLL |
SYSCTL_XTAL_6MHZ | SYSCTL_OSC_MAIN); /* 配置系统时钟 */
FlashUsecSet(SysCtlClockGet() / (1000000UL)); /* 设置Flash编程的时序参数 */
Uart0Init(115200,1); /* 初始化串口 */
SendMessage(); /* 发送BOOT提示信息 */
memset(RcvBuffer,0,BufferSize);
}
/*********************************************************************************************************
** 函数名称: Timer0Init
** 功能描述: 初始化超时时间
** 入口参数: time 超时时间
** 出口参数: 无
********************************************************************************************************/
void Timer0Init(uint32 time)
{
SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
TimerConfigure(TIMER0_BASE,TIMER_CFG_32_BIT_PER); /* 32BIT周期触发模式 */
TimerLoadSet(TIMER0_BASE, TIMER_A, SysCtlClockGet()*time); /* 配置超时时间 */
TimerControlStall(TIMER0_BASE,TIMER_A,true); /* 配置调试过程中定时器停止计数 */
IntEnable(INT_TIMER0A); /* 使能定时器中断 */
TimerIntEnable(TIMER0_BASE,TIMER_TIMA_TIMEOUT); /* 使能定时器超时中断 */
IntMasterEnable(); /* 使能内核中断 */
TimerEnable(TIMER0_BASE,TIMER_A); /* 启动定时器0 */
}
/*********************************************************************************************************
** 函数名称: VerifyData
** 功能描述: 校验写入FLASH的数据
** 入口参数: pulData 源数据
** ulAddress FLASH的起始地址
** ulCount 校验的字节数
** 出口参数: true 校验成功
** false 校验失败
********************************************************************************************************/
uint8 VerifyData(uint8 *pulData,unsigned long ulAddress,unsigned long ulCount)
{
unsigned long ReData;
ulCount += (4 - ulCount % 4); /* 调整校验的字节个数为4的倍数 */
while(ulCount) {
ReData = HWREG(ulAddress); /* 读取指定Flash地址的字数据 */
if(*pulData != (ReData &0xff)) { /* 校验字节数据 */
return false;
}
if(*(++pulData) != ((ReData >> 8) &0xff)) { /* 校验字节数据 */
return false;
}
if(*(++pulData) != ((ReData >> 16) &0xff)) { /* 校验字节数据 */
return false;
}
if(*(++pulData) != ((ReData >> 24) &0xff)) { /* 校验字节数据 */
return false;
}
ulAddress += 4; /* 调整指定的Flash地址 */
ulCount -= 4; /* 调整待校验的字节个数 */
pulData++; /* 调整源数据指针 */
}
return true;
}
/*********************************************************************************************************
** 函数名称: FlashProgramU8
** 功能描述: 对Flash进行字节编程
** 入口参数: pulData 写入的源数据
** ulAddress FLASH的目标起始地址
** ulCount 写入的字节数
** 出口参数: true 写入成功
** false 写入失败
********************************************************************************************************/
uint8 FlashProgramU8(uint8 *pulData,unsigned long ulAddress,unsigned long ulCount)
{
unsigned long Wrdata;
HWREG(FLASH_FCMISC) = FLASH_FCMISC_AMISC; /* 清除访问错误中断 */
ulCount += (4 - ulCount % 4); /* 调整字节个数为4的倍数 */
while(ulCount) {
Wrdata = *pulData;
Wrdata |= (*(++pulData)) << 8;
Wrdata |= (*(++pulData)) << 16;
Wrdata |= (*(++pulData)) << 24; /* 将4个字节组合成一个字数据 */
HWREG(FLASH_FMA) = ulAddress; /* 写入Flash的地址 */
HWREG(FLASH_FMD) = Wrdata; /* 写入Flash的字数据 */
HWREG(FLASH_FMC) = FLASH_FMC_WRKEY | FLASH_FMC_WRITE; /* 启动写入命令 */
while(HWREG(FLASH_FMC) & FLASH_FMC_WRITE); /* 等待写结束 */
pulData++;
ulAddress += 4;
ulCount -= 4;
}
if(HWREG(FLASH_FCRIS) & FLASH_FCRIS_ARIS) { /* 产生访问错误原始中断 */
return(false);
}
return(true);
}
/*********************************************************************************************************
** 函数名称: UpdateUserCode
** 功能描述: 程序升级
** 入口参数: WtoAddr 更新的程序区首地址
** 出口参数: true 更新成功
** false 更新失败
********************************************************************************************************/
uint8 UpdateUserCode(unsigned long WtoAddr)
{
uint8 n = 0;
for(n=0;n<SectionNum;n++) {
if( FlashErase(WtoAddr+1024*n) ) { /* 擦除Flash扇区 */
Uart0Send("擦除扇区失败!\r\n");
}
}
if (FlashProgramU8(RcvBuffer,WtoAddr,RcvNum) == false) { /* 对Flash写入数据 */
Uart0Send("写入发生错误。\r\n");
} else {
Uart0Send("写入成功!\r\n");
}
if (VerifyData(RcvBuffer,WtoAddr,RcvNum) == false) { /* 对写入Flash的数据进行校验 */
Uart0Send("数据校验失败!\r\n");
return false;
} else {
Uart0Send("数据校验成功!\r\n");
return true;
}
}
/*********************************************************************************************************
** 函数名称: main
** 功能描述: 主程序
** 入口参数: 无
** 出口参数: 无
********************************************************************************************************/
int main(void)
{
uint8 i;
SysInit(); /* 系统初始化 */
Timer0Init(60); /* 超时时间为60S */
RcvNum = 0;
XmodemRun(RcvBuffer); /* 运行Xmodem接收数据 */
TimerDisable(TIMER0_BASE,TIMER_A); /* 关闭定时器0 */
IntMasterDisable(); /* 关内核中断 */
if(HWREG(LOW_Addr) == 0xFFFFFFFF) { /* 判断更新哪个区 */
if( UpdateUserCode(LOW_Addr) ) { /* 启动更新代码 */
Uart0Send("更新LOW区成功!\r\n");
HWREG(UpdateFlag) = Low_Flag; /* 更新程序标志区 */
for(i=0;i<SectionNum;i++) {
if( FlashErase(HIGH_Addr+1024*i) ) { /* 擦除备份程序 */
Uart0Send("擦除扇区失败!\r\n");
}
}
} else {
HWREG(UpdateFlag) = High_Flag; /* 更新程序标志区 */
}
} else if(HWREG(HIGH_Addr) == 0xFFFFFFFF) {
if( UpdateUserCode(HIGH_Addr) ) {
Uart0Send("更新HIGH区成功!\r\n");
HWREG(UpdateFlag) = High_Flag;
for(i=0;i<SectionNum;i++) {
if( FlashErase(LOW_Addr+1024*i) ) {
Uart0Send("擦除扇区失败!\r\n");
}
}
} else {
HWREG(UpdateFlag) = Low_Flag;
}
}
IntMasterEnable(); /* 使能内核中断 */
SysCtlReset(); /* 系统软件复位 */
}
/*********************************************************************************************************
** 函数名称: Timer0A_ISR
** 功能描述: 定时器0的中断服务程序
** 入口参数: 无
** 出口参数: 无
********************************************************************************************************/
void Timer0A_ISR(void)
{
uint32 IntStatus;
IntStatus = TimerIntStatus(TIMER0_BASE,true); /* 超时中断 */
TimerIntClear(TIMER0_BASE,IntStatus);
if(HWREG(LOW_Addr) == 0xFFFFFFFF) {
HWREG(UpdateFlag) = High_Flag; /* 更新程序标志区 */
} else if(HWREG(HIGH_Addr) == 0xFFFFFFFF) {
HWREG(UpdateFlag) = Low_Flag;
}
SysCtlReset(); /* 系统软件复位 */
}
/*********************************************************************************************************
** End Of File
********************************************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -