OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 2123|回复: 1

STM8L BOOT程序分享

[复制链接]

5

主题

15

帖子

0

精华

初级会员

Rank: 2

积分
161
金钱
161
注册时间
2014-12-9
在线时间
28 小时
发表于 2017-2-5 11:38:23 | 显示全部楼层 |阅读模式
/******************************************************************************
********STM8L_BOOT升级程序*****************************************************
我把FLASH分为3块,BOOT区、APP区、COPY区;升级指令的处理放在APP区里,把收到的升级包写到COPY区,接受完毕后做个CRC校验验证,通过后再跳转到BOOT区去执行BOOT升级程序。
*******************************************************************************/
#include "main.h"
#include "stm8l15x.h"
#include "sys_pro.h"
#include "stdio.h"
#include "rh_app.h"
__root const long reintvec[]@".intvec"=       //中断向量表重定向
{ 0x82008080,0x82009004,0x82009008,0x8200900c, //当应用程序地址不是0x9000时则要相应改掉除第一个0x82008080以外的数值
  0x82009010,0x82009014,0x82009018,0x8200901c,
  0x82009020,0x82009024,0x82009028,0x8200902c,
  0x82009030,0x82009034,0x82009038,0x8200903c,
  0x82009040,0x82009044,0x82009048,0x8200904c,
  0x82009050,0x82009054,0x82009058,0x8200905c,
  0x82009060,0x82009064,0x82009068,0x8200906c,
  0x82009070,0x82009074,0x82009078,0x8200907c,
};
u32 len = 0;    //升级文件包大小
u8  up_log = 0; //升级标志位
/********************************************************************
*功    能:从内部Flash某个位置写一页数据
*输入参数:无
*输出参数:无
*返 回 值:无
*修改日志:16.11.07
********************************************************************/
void FLASH_WriteDat_OnePage(u8 *GBuffer, u8 Page)
{
   FLASH_Unlock(FLASH_MemType_Program);
   while (FLASH_GetFlagStatus(FLASH_FLAG_PUL) == RESET);
   FLASH_EraseBlock(Page, FLASH_MemType_Program);
   while (FLASH_GetFlagStatus(FLASH_FLAG_HVOFF) == RESET);
   FLASH_ProgramBlock(Page, FLASH_MemType_Program, FLASH_ProgramMode_Standard, GBuffer);
   while (FLASH_GetFlagStatus(FLASH_FLAG_HVOFF) == RESET);
   FLASH_Lock(FLASH_MemType_Program);   
}
/********************************************************************
*功    能:EEPROM某个位置读出升级程序的大小4Byte
*输入参数:无
*输出参数:无
*返 回 值:无
*修改日志:16.11.07
********************************************************************/
void Get_AppSize(void)
{
   u8 i = 0;
   FLASH_Unlock(FLASH_MemType_Data);
   for (i = 0; i < 4; i++)
   {
       len = ((FLASH_ReadByte(EEPROM_StartAddr + i) & 0x000000FF) << (8 * i)) | len;
   }
   len = len - 4;
   FLASH_Lock(FLASH_MemType_Data);
}
/********************************************************************
*功    能:EEPROM某个位置读出升级标志位1Byte
*输入参数:无
*输出参数:无
*返 回 值:无
*修改日志:16.11.07
********************************************************************/
void Get_Uplog(void)
{
   FLASH_Unlock(FLASH_MemType_Data);
   up_log = FLASH_ReadByte(EEPROM_StartAddr + 4);
   FLASH_Lock(FLASH_MemType_Data);
}
/********************************************************************
*功    能:擦除EEPROM(0x1000~0x1004)
*输入参数:无
*输出参数:无
*返 回 值:无
*修改日志:16.11.07
********************************************************************/
void Erase_Eepprom(void)
{
   u8 i = 0;
   FLASH_Unlock(FLASH_MemType_Data);
   for (i = 0; i < 5; i++)
   {
       FLASH_EraseByte(EEPROM_StartAddr + i) ;
   }
   FLASH_Lock(FLASH_MemType_Data);
}
/********************************************************************
*功    能:升级流程
*输入参数:无
*输出参数:无
*返 回 值:无
*修改日志:16.11.07
********************************************************************/
void Up_Data(void)
{
   u8  block = 0;           //整页数
   u8  sized = 0;           //剩余字节数
   u16 t     = 0;
   u8  m     = 0;
   u16 fade  = 0;
   u8  DAT   = 0;
   u8 _buf[FLASH_BLOCK_SIZE] = {0};
   block = len / FLASH_BLOCK_SIZE;
   sized = len % FLASH_BLOCK_SIZE;
   for (t = 0; t < block; t++)
   {
        for (m = 0; m < FLASH_BLOCK_SIZE; m++)
        {
            FLASH_Unlock(FLASH_MemType_Program);
            while (FLASH_GetFlagStatus(FLASH_FLAG_PUL) == RESET);
            _buf[m] = FLASH_ReadByte(APP_COPY_START_ADDR + m + t * FLASH_BLOCK_SIZE);
            while (FLASH_GetFlagStatus(FLASH_FLAG_HVOFF) == RESET);
            FLASH_Lock(FLASH_MemType_Program);
        }
        FLASH_WriteDat_OnePage(_buf, t + 32);
        IWDG_ReloadCounter();
   }
   fade = len + 0x9000;
   t = fade - sized;
   for (m = 0; m < sized; m++)
   {
      FLASH_Unlock(FLASH_MemType_Program);
      while (FLASH_GetFlagStatus(FLASH_FLAG_PUL) == RESET);
      FLASH_EraseOptionByte(t + m);
      while (FLASH_GetFlagStatus(FLASH_FLAG_HVOFF) == RESET);
      DAT = FLASH_ReadByte(APP_COPY_START_ADDR + m + block  * FLASH_BLOCK_SIZE);
      FLASH_ProgramOptionByte(t + m, DAT);
      while (FLASH_GetFlagStatus(FLASH_FLAG_HVOFF) == RESET);
      FLASH_Lock(FLASH_MemType_Program);
   }
   LED1_OFF;
   asm("LDW X,  SP ");       //跳转指令
   asm("LD  A,  $FF");
   asm("LD  XL, A  ");
   asm("LDW SP, X  ");
   asm("JPF $9000");
}
void main( void )
{                              
    Bsp_Int();
    sim();                    //关闭所有中断,BOOT里禁止开中断
    while (1)
    {
        IWDG_ReloadCounter();
        Get_AppSize();
        Get_Uplog();
        Erase_Eepprom();
        if (up_log == Up_ok)  //判断升级标志位
        {
           LED1_ON;
           Up_Data();
        }
        else
        {
           asm("LDW X,  SP "); //跳转指令
           asm("LD  A,  $FF");
           asm("LD  XL, A  ");
           asm("LDW SP, X  ");
           asm("JPF $9000");  
        }
    }
}
/*******************************************************************************/


正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

27

主题

118

帖子

0

精华

高级会员

Rank: 4

积分
850
金钱
850
注册时间
2015-12-8
在线时间
176 小时
发表于 2018-8-22 19:47:59 | 显示全部楼层
为自己掌握新的知识感到快乐
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-7-12 02:58

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表