初级会员

- 积分
- 161
- 金钱
- 161
- 注册时间
- 2014-12-9
- 在线时间
- 28 小时
|
/******************************************************************************
********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");
}
}
}
/*******************************************************************************/
|
|