第一次尝试写博文,写的不好,请多多指教。
1、本Bootloader适用范围:
STM8S 和STM8A
2、Bootloader和APP的标志位
在EEPROM中的0x4000地址存放一个标志位
Bootloader 的标志位: 0x11;
APP的标志位: 0x39;
3、Bootloader 和APP的地址分配
Bootloader 的存储空间为: 0x8000~ 0x9FFF;
APP 的存储空间为: 0xA000~0x27FFF;
地址 | 空间名称 |
0x8000 | bootloader_start |
| bootloader |
0x9FFF | bootloader_end |
0xA000 | app_start |
| app |
0x27FFF | app_end |
在0x8000开始的前128个字节,放置着bootloader重定位过的向量表(bootloader的真正的向量表放置在另外的地方)
在0xA000开始的前128个字节,放置着application的向量表
在0x001000开始的128个字节,放置着真正的向量表。(因此,不论在bootloader还是application都要在编译阶段告知链接器保留0x00~0x80这段内存空间)
详细的分布规则,请参考ICF 目录下的stm8af52a6_xxxx.ICF
4、更新程序的流程
5、ICF文件说明
Bootloader ICF 请查看 stm8af52a6_Boot.ICF 在项目文件夹的ICF文件夹中;
1)、define region VectData = [from 0x1000 to 0x107F];//重定向的中断向量表的存放位置
//为真实的中断向量标在RAM中申请一个空间;
2)、place at start of VectData { rw section .vector };
//定义中断向量表的存放位置。
3)、do not initialize { section .vector };
//因为中断向量表放在RAM中,防止上电初始化,会将此段数据清零,定义为上电不初始化。
4)、define region NearFuncCode = [from 0x8000 to 0x9FFF];
define region AppFuncCode = [from 0xA000 to 0xFFFF];
define region FarFuncCode = [from 0x8000 to 0x9FFF]
| [from 0x10000 to 0x1FFFF]
| [from 0x20000 to 0x27FFF];
//定义Bootloader的存储空间。
APP ICF 请查看 stm8af52a6_APP.ICF 在项目文件夹的ICF文件夹中;
define region NearFuncCode = [from 0xA000 to 0xFFFF];
define region FarFuncCode = [from 0xA000 to 0xFFFF]
|[from 0x10000 to 0x1FFFF]
|[from 0x20000 to 0x27FFF];
define region HugeFuncCode = [from 0xA000 to 0xFFFF]
|[from 0x10000 to 0x1FFFF]
|[from 0x20000 to 0x27FFF];
APP的定义空间不同,其余与Bootloader相同;
6、APP的跳转
1)、当APP收到上位机通过CAN总线发送过来的数据
d[0] == 0xAA && d[1] == 0x55 && d[2] == 0xA5 同时成立时;
进行程序更新;
2)、先进行中断向量表的初始化,将RAM 0x1000~0x107F中的中断向量表存放为Bootloader的中断向量表,此时一定要关闭中断。
void STM8_BootLoardHanderIqr_Init(void)
{
ubyte *dst = (ubyte *)VECTAB_RELOAD_START;
word cnt = 32;//sizeof(ReVector);
word i;
disableInterrupts(); //关闭总中断
for(i = 0; i < cnt; i++)
{
//*dst++ = *src++;
*dst++ = 0x82;
*dst++ = 0x00;
*dst++ = 0x80;
*dst++ = 0x80+i*4;
}
}
3)、将EEPROM中的标志位更改为Bootloader的标志位 0x11;
4)、在进行EEPROM操作后必须延时,我之前不实现会出现EEPROM写入失败,最后导致程序不能正常跳转到Bootloader;
5)、产生软件复位,不需要跳转
void SoftReset(void)
{
WWDG->CR |= 0x80;
WWDG->CR &= ~0x40;
}
6)、硬件复位后,程序会先进入Bootloader,进行EEPROM中标志位的判断,当读取到标志位为0x11,程序停留在Bootloader中等待程序更新;
7、Bootloader的跳转
由于STM8的向量表固定在0x008000~0x008080的位置,想要实现重定位向量表,则必须在固定的向量表中填入真正的向量表地址,方法如下:
1)、在APP烧写到0xA000的地址空间后,先进行程序看门狗产生软件复位;
2)、程序重新开始,判断EEPROM中0x4000地址内数据的标志位,如果是0x39就跳转到APP,否则留在Bootloader中;
3)、重新初始化STM8的中断向量表 把它重新定义到Bootloader的中断向量中 放在0x1000 –> VECTAB_RELOAD_START
void STM8_AppHanderIqr_Init(void)
{
ubyte *dst = (ubyte *)VECTAB_RELOAD_START;
word cnt = 32;//sizeof(ReVector);
word i;
disableInterrupts(); //关闭总中断
for(i = 0; i < cnt; i++)
{
//*dst++ = *src++;
*dst++ = 0x82;
*dst++ = 0x00;
*dst++ = 0xA0;
*dst++ = i*4;
}
}
4)、跳转到APP
void goto_app(void)
{
//重定义STM8的中断向量
STM8_AppHanderIqr_Init();
//跳转至APP
asm("LDW X, SP ");
asm("LD A, $FF");
asm("LD XL, A ");
asm("LDW SP, X ");
asm("JPF $A000");
}
8、PC界面:
9、USB-CAN 通讯工具
10、Bootloader APP PC(VS)源代码文件列表
源代码链接:https://download.csdn.net/download/zijidewo123/13907488