打印
[STM8]

STM8 如何自制BootLoader并实现在线升级

[复制链接]
1636|32
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
BootLoader升级数据从哪里来?
要实现在线升级就必须要有数据端口去接收新的升级文件的数据,本博文以串口为数据接收端口接收数据。关于串口部分代码如下:

/******************************************
串口部分,不使用中断 9600波特率
*******************************************/
void UARTInit(void){
  UART1_CR1=0x00;
  UART1_CR2=0x00;
  UART1_CR3=0x00;

  UART1_BRR2 = 0x02;
  UART1_BRR1 = 0x68;

  UART1_CR2 =0x0C;  //使能收发  
}
//串口发送函数
void UART1_SendB(unsigned char udDat)
{
    while (!(UART1_SR & 0x80));
    UART1_DR = udDat;   
}
//串口接收函数
unsigned char UART1_RcvB(void)
{
     while(!(UART1_SR & 0x20));
     return ((unsigned char)UART1_DR);
}

关于串口部分代码,不做详细解释,请查相关型号的用户手册。为避免和APP发生冲突,在BootLoader中不能开中断,所以这里的串口接收是循环等待接收,只在需要接收新数据时接收串口消息。


使用特权

评论回复
沙发
木木guainv|  楼主 | 2020-2-6 08:28 | 只看该作者
如何将接收到的程序写入到FLASH程序存储器中?
需要注意的是对FLASH的写操作必须按页进行,对于博主使用的STM8S003F3属于小容量STM8S器件,每页64个字节,即每次写FLASH都必须写入64个字节,而对于中容量和大容量的STM8S器件每页的字节数为512个字节。关于写FLASH的代码如下:

/******************************************
写FLASH
*******************************************/
//reg definition
#define FLASH_RASS_KEY1 ((unsigned char)0x56) /*!< First RASS key */
#define FLASH_RASS_KEY2 ((unsigned char)0xAE) /*!< Second RASS key */
#define BLOCK_BYTES     64
__ramfunc void FLASHBlock_Write(unsigned char* ucAddr,unsigned char* ucBuf){
    unsigned char ucIndex=0;

    FLASH_PUKR = FLASH_RASS_KEY1;
    FLASH_PUKR = FLASH_RASS_KEY2;

    FLASH_CR2   |= 0x01;
    FLASH_NCR2  &= ~0x01;
    for(ucIndex=0;ucIndex<BLOCK_BYTES;ucIndex++){
      *((__near unsigned char*)((unsigned short)ucAddr+ucIndex))=(unsigned char)ucBuf[ucIndex];
    }

    FLASH_IAPSR &= 0xFD;
}


使用特权

评论回复
板凳
木木guainv|  楼主 | 2020-2-6 08:30 | 只看该作者
如何配置APP应用程序的起始地址以及如何跳转到应用程序?
STM8S003F3的程序存储区从地址0x8000开始,总共有8K的空间可供使用,博主这里将BootLoader大小限制为1K,即设定应用程序的起始地址为0x84


如何设置BootLoader以及APP应用程序的起始地址和结束地址?
右键项目选择Option单击Linker在Config选项页中,可以看到Override default复选框并没有被勾选上,即此时工程使用的是默认的Linker文件,我们要做的就是使用我们自己自定义的Linker以覆盖该Linker文件。

使用特权

评论回复
地板
木木guainv|  楼主 | 2020-2-6 08:32 | 只看该作者

我们在IAR的安装目录STM8\config(我的就是D:\IAR Systems\Embedded Workbench 7.3\stm8\config)下面找到lnkstm8s003f3.icf,然后将其复制到BootLoader工程目录下,以文本方式打开该链接文件,


使用特权

评论回复
5
木木guainv|  楼主 | 2020-2-6 08:32 | 只看该作者
对于APP应用程序需要将其中的NearFuncCode、FarFuncCode和HugeFuncCode的起始地址均从0x8000修改为0x8400,如下图:

使用特权

评论回复
6
木木guainv|  楼主 | 2020-2-6 08:33 | 只看该作者
对于BootLoader程序,链接文件可不做修改,但修改的好处是,当BootLoader程序大小超过设定值(我这里设定的是1KB)时,IAR在编译链接时,可以检测出来,具体修改如下图:

然后我们回到工程选项Linker分支下的Config页面中,勾选选中复选框Override default,在下方的编辑框中输入修改好的*.icf文件(若修改BootLoader工程的链接文件,则BootLoader工程也需要修改这里)。


使用特权

评论回复
7
木木guainv|  楼主 | 2020-2-6 08:33 | 只看该作者
如何从BootLoader程序跳转到APP应用程序
STM8 提供汇编跳转指令,只需要执行汇编代码即可,在IAR中的跳转代码如下:

asm("JP $8400");

如何得到可直接写入FLASH的应用程序代码?
使用的IAR环境可以直接生成hex文件,设置如下:


使用特权

评论回复
8
木木guainv|  楼主 | 2020-2-6 08:34 | 只看该作者
我们便可以在工程的Debug\Exe目录下得到该Hex文件,但是该文件中的内容并不是可以直接写入到FLASH中,我们需要从中提取有效的数据,以文本格式打开该文件,可以看到:


该Hex文件是以行为单位,以冒号开头的十六进制文件,其具体格式如下:

1. 每行的第一个字符固定为冒号,从第二个字符开始,每两个字符表示一个字节。

2. 每行的第一个字节表示本行的数据长度,只是指定数据部分的长度,以字节为单位

3. 每行的第二、三个字节表示表示本行数据的起始地址,即第一行数据的起始地址为0x8400

4. 每行的第四个字节表示数据类型,数据类型有0x00,0x01,0x02,0x03,0x04,x05;

0x00表示当前行是用来记录数据的,即可以写入FLASH中的数据从该数据类型中获得。

0x01表示文件结尾,用来表示Hex文件的结束。

我们主要用到的就是这两个类型,其他类型可自行查阅相关资料。


5 最后一个字节为校验字节,校验算法为计算本行除校验字节外的所有数据的累加和,不计进位,得到的字节数据即为校验字节。





使用特权

评论回复
9
木木guainv|  楼主 | 2020-2-6 08:35 | 只看该作者
如何重定义STM8中断向量?
如果我们不重定义STM8的中断向量将会导致APP应用程序无法使用中断,导致程序出错。在IAR中重定义中断向量只要在BootLoader程序中添加如下代码即可:


__root const long reintvec[]@".intvec"=
{   
    0x82008080,0x82008404,0x82008408,0x8200840c,
    0x82008410,0x82008414,0x82008418,0x8200841c,
    0x82008420,0x82008424,0x82008428,0x8200842c,
    0x82008430,0x82008434,0x82008438,0x8200843c,
    0x82008440,0x82008444,0x82008448,0x8200844c,
    0x82008450,0x82008454,0x82008458,0x8200845c,
    0x82008460,0x82008464,0x82008468,0x8200846c,
    0x82008470,0x82008474,0x82008478,0x8200847c,
};


如果将BootLoader的大小设置为2K,即应用程序的起始地址为0x8800,则该数组应该是这样:

__root const long reintvec[]@".intvec"=
{   
    0x82008080,0x82008804,0x82008808,0x8200880c,
    0x82008810,0x82008814,0x82008818,0x8200881c,
    0x82008820,0x82008824,0x82008828,0x8200882c,
    0x82008830,0x82008834,0x82008838,0x8200883c,
    0x82008840,0x82008844,0x82008848,0x8200884c,
    0x82008850,0x82008854,0x82008858,0x8200885c,
    0x82008860,0x82008864,0x82008868,0x8200886c,
    0x82008870,0x82008874,0x82008878,0x8200887c,
};



请仔细对比如果两个地址设置不一样其中的差别。


使用特权

评论回复
10
香水城| | 2020-2-6 10:04 | 只看该作者
辛苦了!

使用特权

评论回复
11
木木guainv|  楼主 | 2020-2-6 10:05 | 只看该作者
城主客气啦 呵呵

使用特权

评论回复
12
usysm| | 2020-2-7 22:35 | 只看该作者
需要烧写bootloader?  

使用特权

评论回复
13
typeof| | 2020-2-7 22:35 | 只看该作者
  怎么进入Bootloader  

使用特权

评论回复
14
yujielun| | 2020-2-7 22:36 | 只看该作者
自制 STM8 Bootloader   

使用特权

评论回复
15
htmlme| | 2020-2-7 22:36 | 只看该作者
           

使用特权

评论回复
16
pklong| | 2020-2-7 22:37 | 只看该作者
这个是成熟的方案吗   

使用特权

评论回复
17
touser| | 2020-2-7 22:37 | 只看该作者
BootLoader升级数据从哪里来

使用特权

评论回复
18
myiclife| | 2020-2-7 22:37 | 只看该作者
这种在线升级比较难。   

使用特权

评论回复
19
uytyu| | 2020-2-7 22:37 | 只看该作者
不错的资料。   

使用特权

评论回复
20
iyoum| | 2020-2-7 22:38 | 只看该作者
数据端口去接收?  

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

146

主题

4098

帖子

5

粉丝