打印
[信息]

【实战经验】STM8L IAP 应用程序中编程指导

[复制链接]
7981|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 香水城 于 2017-8-16 14:54 编辑

STM8L IAP 使用说明

前言
本篇主要介绍STM8Lxxxx 如何实现在应用程序中编程(In-application programming)。

1. IAP user Flash 分配框图及中断向量表重定向

图1:IAP 代码在User Flash 中的空间分配

注意:
1 和2 为IAP 代码空间。为客户自己的bootloader 代码,应用程序中更新Flash 的代码。
3 和4 为客户应用程序代码,实现产品具体操作功能。
中断向量表1 中除了Reset,其他存放的是指向中断向量表2 的地址;中断向量表2 中放的是具体的APP 中断处理程序入口
地址。发生中断后PC 指针先指向中断向量表1,然后再指向中断向量表2,最后到具体的中断处理函数处。
客户应用程序起始位置(上图是0x9000)可以根据客户需要设置,比如可以改0x9000 为0xA000(如果客户的
bootloader 程序超过0x9000 但没有超过0xA000 可以这样设置)。

图2:IAP 代码的中断处理流程

2. IAP 对中断向量表重定向的说明
STM8 的中断向量位置是固定的,大部分是0x8000 开始处。IAP 程序中需要手工处理中断向量表。并且boot 程序不能使用任何中断(IAP 程序中的中断跳转(中断向量表1)会使PC 指到0x900x 处,如果此时APP 没有程序,程序就会出错。),程序中的所有中断(向量表1)的处理最终都要跳转到用户程序的中断向量表2 处。

IAP bootloader 参考程序为STSW-STM8006。可以在www.st.com 或是www.stmcu.com.cn 上下载。

下面以STVD 工程 Cosmic 为例进行说明。

…\STSW-STM8006\AN2659-IAP_using_user-bootloader\Project\STM8L_User-Bootloader_example\STVD\Cosmic
Stm8_interrupt_vector.c: 下面的中断向量表1 位于0x8000 到0x8080 地址空间。

假设发生了0x8001 中断,指针经硬件定向到了0x8001,在0x8001 里存储的是跳转到0x9001 代码,然后程序跳转到0x9001 位置去执行,而0x9001 中的代码是跳转到具体的中断函数处。(具体代码中使用函数指针来实现)

0x82 为操作码,意思是跳转到后面的地址去执行。如下例:


对 0x82 的描述在文件PM0044 有如下描述: 0x82 为内部指令:

在main.h 里有下面的代码: MAIN_USER_RESET_ADDR 的地址为0x9000。所以APP 代码开始的位置在0x9000,开始存放第二个中断向量表(中断向量表2),此处为中断处理函数入口地址的重定向表。

3. STVD 软件中,下图Project/Settings 中对中断向量表位置的处理可以看到。中断向量表1 是从0x8000 开始存放(Vector file name and Vector addr.)。

对“Vector file name”的定义为“stm8_interrupt_vector.c”;“Vector address”定义为“0x8000”地址。如下图。

…\STSW-STM8006\AN2659-IAP_using_user-bootloader\Project\STM8L_User-Bootloader_example\STVD\Cosmic\Debug
有文件“userbootloader.lkf”,有代码如下:(当这个文件中的设置同STVD Project/Settings/Linker 对画框中的设置不一样时,优先使用对话框中的设置


4. User Flash 空间烧写方式
Bootloader 程序可以烧写内部Flash、EEPROM、RAM。适用于产品软件的更新。

5.对 _fctcpy 的说明,对Flash 的大块区域编程的代码在RAM 中运行的问题解决。
对Flash 进行大块区域的编程的代码需要在RAM 中运行,为了实现这个,需要一个自定义代码段,并将这个代码段放在RAM 中。在例程中定义了一“.FLASH_CODE”段。请查看下面代码红色区域。


_fctcpy 功能:
COSMIC 中的函数_fctcpy 是将Flash 中的代码拷贝到RAM 中并运行。_fctcpy 寻找linker 定义的描述符(此描述符是在RAM中定义段的第一个字符),在STSW-STM8006 中定义了一个段FLASH_CODE (#pragma section (FLASH_CODE))。因此第一个字符是‘F’.
在mian 函数中调用_fctcpy('F')的作用是把FLASH_CODE 段拷贝到RAM 中并运行。
FLASH_CODE 是一个可以移动的段,需要在IAP “boot 程序链接配置”的RAM 区添加。
在 RAM 中创建一个“.FLASH_CODE”段,并在Option 中输入“-ic”;“.FLASH_CODE”表示在RAM 中定义一个FLASH_CODE 的段,程序可以从此地址运行。“-ic”表示标记这个段为可移动的段,可将Flash 中的代码移植到此。

可以在生成的*.map 文件中检查生成的段是否正确,示例代码中有如下的map 文件


“from”为存放代码的部分。“initialized”为执行代码的部分。

IAP 的bootloader 和APP 分开为两个独立的工程文件。上面的内容是针对IAP 的bootloader 的程序工程的处理说明(属于图1 中的“1.中断变量表1,复位后硬件PC 指针从这里开始”和“2.客户程序中的bootloader 代码” 段),下面来说说APP 工程段(图1 中的3 和4 代码段)。

6. APP 工程说明。
在APP 工程里,设置中断向量地址为0x9000(上面以0x9000 为例。如果从0xA000 开始,就设置为0xA000)。代码段的起始地址为0x9080. 编译后生成的二进制文件就是需要通过bootloader 烧写到Flash 0x9000 之后地址的APP 程序。

对应PDF:STM8L_IAP_应用程序中编程指导
更多实战经验请看:【ST MCU实战经验汇总贴】





沙发
LiangSir_21| | 2015-12-28 15:20 | 只看该作者
版主,您有用过STM8L101系列做DS18B20温度采集吗

使用特权

评论回复
板凳
arccosine| | 2015-12-29 10:24 | 只看该作者
如何下载呢?

使用特权

评论回复
地板
狐零三| | 2016-1-14 13:24 | 只看该作者
作为初学者,一直没有理解stm8l的iap程序,感谢香版分享经验,我得好好看看

使用特权

评论回复
5
wsl_5631| | 2016-1-14 15:18 | 只看该作者

香主你好,对于STM8我有个疑惑。例如STM8L052,它有专门的EEROM区。但是用户自己做IAP时,FLASH又可以划出一部分做BOOT,比如0x8000-0x9000, 然后去更新0X9000后面的程序。问题来了,既然FLASH是可以写的,能否在EEROM不够用时,把不用的FLASH都用作EEROM呢,如果可以,为什么又设计专用的EEROM呢?

使用特权

评论回复
6
z00| | 2016-1-14 16:49 | 只看该作者
有点复杂 最后生成的有好几段的bin文件

使用特权

评论回复
7
sakura0| | 2018-12-24 17:24 | 只看该作者
版主大大,有个问题请教下,源码中出现的PD2管脚是干啥用的啊?我的单片机里没有用到这个脚该怎么办呢?
void main(void){
  sim();               // disable interrupts
  RoutinesInRAM = 0;

  // Set GPIO for bootloader Pin status detection
  GPIOD->DDR &= ~0x04;           // PD2 as Input
        GPIOD->CR1 |= 0x04;                 // PD2 as Pull Up
        GPIOD->CR2 &= ~0x04;          // no external interrupt
       
        // Detect if bootloader is enabled (pin in high state)
        if( (GPIOD->IDR & 0x04) == 0x04 )
  {
    //if user application is not virgin - valid reset vector jump
    if((*((u8 FAR*)MainUserApplication)==0x82) || (*((u8 FAR*)MainUserApplication)==0xAC))
    {
      //De-init PortD bootloader detection
                        GPIOD->ODR=0x00;
                        GPIOD->DDR=0x00;
                        GPIOD->CR1=0x00;
                        GPIOD->CR2=0x00;
      //reset stack pointer (lower byte - because compiler decreases SP with some bytes)

使用特权

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

本版积分规则

认证:意法半导体(中国)投资有限公司
简介:STM32技术专家

596

主题

17108

帖子

289

粉丝