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

📄 +

📁 基于Luminary远程在线升级解决方案
💻
字号:
/****************************************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 + -