历史上的今天
返回首页

历史上的今天

今天是: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分布

image.png?imageView2/2/w/550

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

在0xC000开始的前128个字节,放置着application的向量表

RAM分布

image.png?imageView2/2/w/550

在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__];

推荐阅读

史海拾趣

Hanghsing Enterprise Co Ltd公司的发展小趣事

HANA Micron公司在电子行业的五个发展故事

故事一:2.5D封装技术的突破

HANA Micron,作为韩国顶尖的后端工艺和外包半导体组装测试(OSAT)公司,近年来在2.5D封装技术领域取得了显著进展。随着高性能人工智能(AI)芯片需求的急剧增长,该公司致力于开发一种能够水平组装不同类型AI芯片的封装技术,如高带宽内存(HBM)。这一技术对于生产像英伟达H100这样的顶级AI加速器至关重要。公司CEO Lee Dong-cheol表示,他们已将未来寄托在HBM和其他AI芯片的先进2.5D封装技术上,并透露公司已生产出原型,尽管全面商业化尚需时日。HANA Micron的这一努力不仅提升了其技术实力,也为公司在全球芯片封装市场的竞争中占据了有利位置。

故事二:越南市场的扩张

为了进一步扩大业务版图,HANA Micron在越南进行了大规模的投资。自2016年在越南北宁省成立公司进军东南亚市场以来,该公司已累计投资高达7000亿韩元(约合5.25亿美元)。其北江省云中工业园的2号制造工厂于2023年正式落成,标志着公司在越南半导体封装和测试领域迈出了重要一步。这一投资不仅提升了公司的产能,还为公司带来了更多的业务机会和市场份额。HANA Micron计划到2025年将月产量提高到2亿个,并预计越南业务的销售额将很快达到万亿韩元。

故事三:多元化产品线的拓展

除了在传统存储芯片封装领域保持领先地位外,HANA Micron还积极拓展多元化产品线。公司目前正在开发针对可穿戴设备和医疗设备的封装技术,以提高这些设备的灵活性和可靠性。这一项目的第一个成果是去年年底开发的针对医疗贴片的心电图传感器模块,该模块允许传感器的功率低于1mA,延迟低于5ms。这一创新不仅展示了公司在封装技术上的深厚积累,也为其在未来医疗和可穿戴设备市场中的发展奠定了坚实基础。

故事四:与国际巨头的合作与竞争

在电子行业的激烈竞争中,HANA Micron不仅与国内同行如三星、SK海力士等展开合作与竞争,还与国际巨头如台积电、英特尔等保持着紧密的联系。公司CEO Lee Dong-cheol透露,台积电已成功研发出英伟达H100的2.5D封装技术,而三星和SK海力士也在积极跟进。在这种背景下,HANA Micron不断加大研发投入,以确保自己在封装技术上的领先地位。同时,公司还通过与国际巨头的合作与交流,不断提升自身的技术水平和市场竞争力。

故事五:应对市场波动与未来展望

面对全球电子市场的波动和不确定性,HANA Micron展现出了较强的抗风险能力和市场适应能力。公司CEO Lee Dong-cheol表示,尽管过去几年存储市场有所放缓,但随着电子产品制造商和AI设备制造商对先进芯片需求的不断增长,预计2024年的业绩将有所改善。为了实现这一目标,公司将继续加大在研发、生产和市场拓展等方面的投入力度。同时,公司还计划将系统芯片的比例提高到50%以上,以降低市场波动对公司业绩的影响。这一战略调整不仅体现了公司对未来的信心和决心,也为公司的可持续发展奠定了坚实基础。

高通(GENITOP)公司的发展小趣事

随着全球市场的不断拓展,超霸电池的销售网络遍布亚洲、欧洲和北美等多个国家和地区。公司始终坚持绿色环保的生产理念,研发出无汞无镉的电池产品,可随生活垃圾丢弃而不会对环境造成影响。此外,超霸电池还积极参与环保事业,旗下多家工厂获得了UL美国安全试验所废弃物零填埋认证。这些举措不仅彰显了超霸电池的社会责任感,也为其在国际市场上树立了良好的品牌形象。

上海晶岳(AFSEMI)公司的发展小趣事

随着市场的不断变化和技术的不断进步,晶岳电子意识到单一的产品线已无法满足市场需求。于是,在2012年,公司开始拓展产品线,研发并推出了LDO、DCDC、复位IC等电源管理芯片。这一举措不仅丰富了公司的产品线,也进一步提升了公司在电源管理领域的竞争力。同时,晶岳电子还加大了对研发团队的投入,引进了一批具有丰富经验的研发人员,为公司的技术创新提供了有力保障。

A/D Electronics Inc公司的发展小趣事

随着产品线的不断丰富,A/D Electronics Inc开始积极拓展国内外市场。公司通过与全球知名电子品牌建立战略合作关系,成功将产品打入国际市场。同时,公司还积极参加国际电子展会,展示其最新技术成果和产品,进一步提升了品牌知名度和市场影响力。

DENWIRE公司的发展小趣事

A/D Electronics Inc在创立初期,以其卓越的技术研发团队在模拟到数字转换器(ADC)领域取得了重大突破。公司研发出一款高精度、低噪声的ADC芯片,这一创新产品迅速在市场中获得认可,为公司的初步发展奠定了坚实基础。随着技术的不断迭代,A/D Electronics Inc陆续推出了一系列高性能的电子产品,满足了市场对于高效、稳定电子元件的日益增长需求。

Hifn Inc公司的发展小趣事

在快速发展的过程中,A/D Electronics Inc始终坚守品质至上的原则。公司建立了严格的质量管理体系,从原材料采购到产品生产、检验、出货等各个环节都严格把关。此外,公司还不断引入先进的生产设备和工艺,提高生产效率和产品质量。通过持续改进和创新,A/D Electronics Inc在激烈的市场竞争中始终保持领先地位。

问答坊 | AI 解惑

十分钟学会Xilinx_FPGA_应用

十分钟学会Xilinx_FPGA_应用…

查看全部问答>

嵌入式驱动开发资料和视频

ppt课件的地址:http://www.top-e.org/wdxz/html/?12.html 视频地址:http://www.tudou.com/programs/view/hNl59pyEYv0/…

查看全部问答>

大家来找茬儿之——PLI程序编译装载后modelsim崩溃

今天写了个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,即设备不可用。首要问题,如何解 ...…

查看全部问答>

GPRS拨号,SOCKET能连通,IE及其它程序无法上网

HI,各位 最近在做一个WINCE5的项目,需要用到GPRS,使用SIM300模块做MODEM,设置都OK了 现在的问题是,使用我自己写的小程序,程序使用的是SOCKET,可以正常通讯,但是用IE不能上网 在CE下,所有IP都ping不通,但是用自己写的小程序连接过某个IP以后,就可 ...…

查看全部问答>

請USB高手推荐比較好的USB HOST 開發板

如題,我要用8051讀取USB 鼠標的數據,請USB高手推荐比較好的USB HOST 開發板,要有齊全的相關資料和詳細的原代碼說明,最好是中文的.…

查看全部问答>

请教完成如下的功能使用什么CPU

1、连接4个串口 2、用220V供电 3、访问桌面SQL Server数据库 操作系统采用windows ce请问使用什么CPU的嵌入式主板?相应厂家的联系方式?…

查看全部问答>

STM32 图像采集与传输

我刚开始学STM32,买的开发板是ALIENTEK MiniSTM32,想移植uCOSII,并实现图像采集与传输,大概思路就是这样子的,具体实现还没想好,请各位大侠给点建议!!谢谢~~~…

查看全部问答>

新手提问跑马灯按键问题

最近刚接触FPGA,接触的第一个实验室是流水灯,我流水灯已经能跑通了,现在想在实验室里加一个按键,按一下流水灯就暂停,再按一下流水灯接着跑。下边是我的代码,流水灯每1秒钟左移1位,求高人指点上边按键的问题。     刚接触问题很多 ...…

查看全部问答>

元旦互动贴:真心话接龙.

年末,论坛活跃贴: 响应号召https://bbs.eeworld.com.cn/thread-363212-1-1.html,开个贴,希望各位网友参与一下. 上一楼提问,下一楼回答并再提一个问题,依次类推; 要认真啊.不来说谎的. 我先来: 问: 你目前最大的心愿是什么?…

查看全部问答>