历史上的今天
今天是:2025年04月02日(星期三)
2020年04月02日 | STM8 bootloader(boot和app皆可使用中断)
2020-04-02 来源:eefocus
STM8 In Application Programming
IAP编写的三个要点:
分析STM8启动过程和C运行时环境建立
规划bootloader和application以及各自向量表在内存中的分布
如何重定位STM8中断向量表
思路:
要编写IAP程序首先需要解决的问题是程序在运行过程中,当发生异常时,如何保证程序正常的跳转到相应的异常服务函数(不论程序是运行在bootloader还是application)。
但STM8没有类似NVIC之类的中断控制器管理中断向量的地址,STM8的向量表固定在0x008000,因此在IAP中需要重定位向量表来实现(为了bootLoader和application都可以使用中断,因此,选择将向量表重定位到RAM中)
规划内存分布
针对于STM8L052C6(2K RAM/32K FLASH)
FLASH分布

在0x8000开始的前128个字节,放置着bootloader重定位过的向量表(bootloader的真正的向量表放置在另外的地方)
在0xC000开始的前128个字节,放置着application的向量表
RAM分布

在0x000000开始的128个字节,放置着真正的向量表。(因此,不论在bootloader还是application都要在编译阶段告知链接器保留0x00~0x80这段内存空间)
利用RAM的特性(rwx),当bootloader运行时,放置bootloader的向量表,当application运行时,放置application的向量表。
详细的分布规则,请参考config目录下的lnkstm8l052c6.icf文件
链接脚本语法请参考IARforSTM8/stm8/doc目录下的EWSTM8_DevelopmentGuide.pdf文件
重定位STM8中断向量表
由于STM8的向量表固定在0x008000~0x008080的位置,想要实现重定位向量表,则必须在固定的向量表中填入真正的向量表地址,方法如下:(参考src目录下的stm8l15x_interrupt.s文件)
/*
* The interrupt vector table.
*/
SECTION `.intvec`:CONST
define_vector MACRO
DC8 0x82
DC24 _interrupt_1
ENDM
PUBLIC __intvec
EXTERN __iar_program_start
__intvec:
DC8 0x82
DC24 __iar_program_start ;; RESET 0x8000
DC8 0x82
DC24 0x0004
DC8 0x82
DC24 0x0008
DC8 0x82
DC24 0x000C
DC8 0x82
DC24 0x0010
DC8 0x82
DC24 0x0014
DC8 0x82
DC24 0x0018
DC8 0x82
DC24 0x001C
DC8 0x82
DC24 0x0020
DC8 0x82
DC24 0x0024
DC8 0x82
DC24 0x0028
DC8 0x82
DC24 0x002C
DC8 0x82
DC24 0x0030
DC8 0x82
DC24 0x0034
DC8 0x82
DC24 0x0038
DC8 0x82
DC24 0x003C
DC8 0x82
DC24 0x0040
DC8 0x82
DC24 0x0044
DC8 0x82
DC24 0x0048
DC8 0x82
DC24 0x004C
DC8 0x82
DC24 0x0050
DC8 0x82
DC24 0x0054
DC8 0x82
DC24 0x0058
DC8 0x82
DC24 0x005C
DC8 0x82
DC24 0x0060
DC8 0x82
DC24 0x0064
DC8 0x82
DC24 0x0068
DC8 0x82
DC24 0x006C
DC8 0x82
DC24 0x0070
DC8 0x82
DC24 0x0074
DC8 0x82
DC24 0x0078
DC8 0x82
DC24 0x007C
汇编语法请参考IARforSTM8/stm8/doc目录下的EWSTM8_AssemblerReference.pdf文件
说明:
以TRAP中断为例,当发送TRAP中断时,PC指针首先指向0x008004地址(FLASH/硬件自动完成)去取指,取到的指令操作码为 82 00 00 04,这段操作码对应的指令为INT 0x000004,操作为将目标地址(0x000004)加载到PC寄存器中,效果等于PC指针指向0x000004地址(RAM)去取指,同样的,在0x000004地址处(RAM)存放着指令操作码82 00 b8 db,其中在0x00b8db地址处(FLASH)存放着真正的TRAP中断服务程序,当PC指针指向0x00b8db地址后,从而执行TRAP中断服务函数。
STM8命令集及操作码请参考:
http://www.st.com/content/ccc/resource/technical/document/programming_manual/43/24/13/9a/89/df/45/ed/CD00161709.pdf/files/CD00161709.pdf/jcr:content/translations/en.CD00161709.pdf
在RAM中放置bootloader的向量表
typedef void (INTERRUPT *interrupt_handler_t)(void);
struct interrupt_vector {
unsigned char interrupt_instruction;
unsigned char reserve;
interrupt_handler_t interrupt_handler;
};
struct interrupt_vector isr_handler[32] @".memvectab" = {
{0x82, 0x00, __iar_program_start},
{0x82, 0x00, TRAP_IRQHandler},
{0x82, 0x00, NMI_IRQHandler},
{0x82, 0x00, FLASH_IRQHandler},
{0x82, 0x00, DMA1_CHANNEL0_1_IRQHandler},
{0x82, 0x00, DMA1_CHANNEL2_3_IRQHandler},
{0x82, 0x00, RTC_CSSLSE_IRQHandler},
{0x82, 0x00, EXTIE_F_PVD_IRQHandler},
{0x82, 0x00, EXTIB_G_IRQHandler},
{0x82, 0x00, EXTID_H_IRQHandler},
{0x82, 0x00, EXTI0_IRQHandler},
{0x82, 0x00, EXTI1_IRQHandler},
{0x82, 0x00, EXTI2_IRQHandler},
{0x82, 0x00, EXTI3_IRQHandler},
{0x82, 0x00, EXTI4_IRQHandler},
{0x82, 0x00, EXTI5_IRQHandler},
{0x82, 0x00, EXTI6_IRQHandler},
{0x82, 0x00, EXTI7_IRQHandler},
{0x82, 0x00, LCD_AES_IRQHandler},
{0x82, 0x00, SWITCH_CSS_BREAK_DAC_IRQHandler},
{0x82, 0x00, ADC1_COMP_IRQHandler},
{0x82, 0x00, TIM2_UPD_OVF_TRG_BRK_USART2_TX_IRQHandler},
{0x82, 0x00, TIM2_CC_USART2_RX_IRQHandler},
{0x82, 0x00, TIM3_UPD_OVF_TRG_BRK_USART3_TX_IRQHandler},
{0x82, 0x00, TIM3_CC_USART3_RX_IRQHandler},
{0x82, 0x00, TIM1_UPD_OVF_TRG_COM_IRQHandler},
{0x82, 0x00, TIM1_CC_IRQHandler},
{0x82, 0x00, TIM4_UPD_OVF_TRG_IRQHandler},
{0x82, 0x00, SPI1_IRQHandler},
{0x82, 0x00, USART1_TX_TIM5_UPD_OVF_TRG_BRK_IRQHandler},
{0x82, 0x00, USART1_RX_TIM5_CC_IRQHandler},
{0x82, 0x00, I2C1_SPI2_IRQHandler}
};
同时,在链接脚本中,将.memvectab这个section 放置在RAM的0x000000地址处。
STM8启动过程
在上面两部分中介绍的,在RAM的0x00~0x80地址处会在不同阶段时放置bootloader和application的两张向量表,因此必然涉及到两张向量表的互相覆盖。
在STM8启动时,会执行__iar_program_start这个函数(此函数由IAR提供),这个函数负责建立C运行时环境和数据的拷贝,因此,在这个阶段会将bootloader真正的向量表从FLASH拷贝到RAM的0x00 ~ 0x80地址处(由链接脚本指定),当需要跳转到application时,运行以下代码将application的向量表拷贝到RAM的0x00 ~ 0x80地址处然后跳转:
void reload_interrupr_vectortable(void)
{
uint8_t *check = (uint8_t *)APPLICATION_ADDRESS;
if(*check == 0x82) {
uint8_t *src = (uint8_t *)APPLICATION_ADDRESS;
uint8_t *dst = (uint8_t *)VECTAB_RELOAD_START;
uint16_t cnt = sizeof(isr_handler);
/* disable interrupt, interrupt will be enable in application */
sim();
platform_peripherals_deinit();
/* reload interrupt vector table(application) from flash to memory */
for(; cnt > 0; cnt--) {
*dst++ = *src++;
}
/* reset stack pointer (lower byte - because compiler decreases SP with some bytes) */
asm("LDW X, SP ");
asm("LD A, $FF");
asm("LD XL, A ");
asm("LDW SP, X ");
asm("JPF $C000 "); /* APPLICATION_ADDRESS */
}
}
通过汇编指令asm("JPF $C000")跳转到application的起始地址处,开始运行application。
当复位时,会重新执行__iar_program_start函数,将bootloader的向量表再次拷贝到RAM的0x00~0x80地址处,覆盖application的向量表。
至此,IAP编写的难点都已解决。
附连接脚本
/////////////////////////////////////////////////////////////////
// Example ILINK command file for
// STM8 IAR C/C++ Compiler and Assembler.
//
// Copyright 2017 HinsShum.
//
// $Revision: 1623 $
//
/////////////////////////////////////////////////////////////////
/*-Symbol-*/
define symbol __intvec_start__ = 0x000000;
define symbol __region_TINY_start__ = 0x000000;
define symbol __region_TINY_end__ = 0x0000FF;
define symbol __region_ROM_start__ = 0x008000;
define symbol __region_ROM_end__ = 0x00BFFF; /* 16K bootloader flash region */
define symbol __region_RAM_start__ = 0x000000;
define symbol __region_RAM_end__ = 0x000FFF; /* 4K RAM region */
define symbol __RAMCACHE_start__ = 0x000100;
/*-Memory Regions-*/
define memory mem with size = 16M;
define region TinyData = mem:[from __region_TINY_start__ to __region_TINY_end__];
define region ROM_region = mem:[from __region_ROM_start__ to __region_ROM_end__];
上一篇:STM8L151系列 (OTA) Bootloader功能的开启 和 关闭
下一篇:STM8S bootloader中断向量重定向 INTVEC exceeds maximum size 问题解决
史海拾趣
|
ppt课件的地址:http://www.top-e.org/wdxz/html/?12.html 视频地址:http://www.tudou.com/programs/view/hNl59pyEYv0/… 查看全部问答> |
|
今天写了个pli程序,编译、生成dll文件都没有问题,就是仿真装载过程中,modelsim崩溃,请大家给分析一下,这是什么病,怎么治!源码如下: top.v `timescale 1ns/1ns module top(clk,AM,AS,WRITE,IACK,LWORD,DS0,DS1,DTACK,BERR,RETRY,AB,DB,SY ...… 查看全部问答> |
|
急急急急——高分求救,可加分!串口通讯相关,打印相关,wince + vs2005 + c/c++ 配置:wince6.0 , vs2005 使用语言: c/c++ 问题背景:现在有一个类似于PDA的终端设备,使用RS232片,需要驱动其打印机来打印由磁卡扫描得到的数据,可是,使用串口COM均失败。使用GetLastError得到的错误为55,即设备不可用。首要问题,如何解 ...… 查看全部问答> |
|
HI,各位 最近在做一个WINCE5的项目,需要用到GPRS,使用SIM300模块做MODEM,设置都OK了 现在的问题是,使用我自己写的小程序,程序使用的是SOCKET,可以正常通讯,但是用IE不能上网 在CE下,所有IP都ping不通,但是用自己写的小程序连接过某个IP以后,就可 ...… 查看全部问答> |
|
如題,我要用8051讀取USB 鼠標的數據,請USB高手推荐比較好的USB HOST 開發板,要有齊全的相關資料和詳細的原代碼說明,最好是中文的.… 查看全部问答> |
|
1、连接4个串口 2、用220V供电 3、访问桌面SQL Server数据库 操作系统采用windows ce请问使用什么CPU的嵌入式主板?相应厂家的联系方式?… 查看全部问答> |
|
我刚开始学STM32,买的开发板是ALIENTEK MiniSTM32,想移植uCOSII,并实现图像采集与传输,大概思路就是这样子的,具体实现还没想好,请各位大侠给点建议!!谢谢~~~… 查看全部问答> |
|
最近刚接触FPGA,接触的第一个实验室是流水灯,我流水灯已经能跑通了,现在想在实验室里加一个按键,按一下流水灯就暂停,再按一下流水灯接着跑。下边是我的代码,流水灯每1秒钟左移1位,求高人指点上边按键的问题。 刚接触问题很多 ...… 查看全部问答> |
|
年末,论坛活跃贴: 响应号召https://bbs.eeworld.com.cn/thread-363212-1-1.html,开个贴,希望各位网友参与一下. 上一楼提问,下一楼回答并再提一个问题,依次类推; 要认真啊.不来说谎的. 我先来: 问: 你目前最大的心愿是什么?… 查看全部问答> |




