历史上的今天
返回首页

历史上的今天

今天是:2025年04月04日(星期五)

2020年04月04日 | 关于自制 STM8 Bootloader

2020-04-04 来源:eefocus

由于本人项目需要,要做STM8L052R8的bootloader,用于远程程序升级功能,为了安全考虑,不使用ST自带的bootloader,而是自制bootloader。


基本的功能是这样的,首先程序运行在一个V1.0的版本上,且带了BOOT,当程序收到一条命令后,程序跑入死循环,等待硬件看门狗复位;程序复位后进入bootload区,等待第二条命令的接收,接收到正确的数据帧后,bootloader开始擦除FLASH,并接收数据包,直到最后一个数据包接收完毕,通过指示灯以2HZ的频率闪烁,指示升级完成。


第一步:boot区程序设计,首先修改link文件,

define region NearFuncCode = [from 0x8000 to 0xAFFF];

define region FarFuncCode = [from 0x8000 to 0xAFFF];

define region HugeFuncCode = [from 0x8000 to 0xAFFF];

place at start of NearFuncCode  { block INTVEC };


以上是link文件部分,可以看出flash地址为0x8000开始,结束于0x17FFF; 长度为64kB,中断向量地址为0x8000,这样,知道了这个我们就可以修改BOOT程序的link和主程序的link了,这里我把BOOTLOAD区划分为8K,应用区为48K设置link文件如下,这样把boot区和APP区分开,互不干扰,你也可以根据需要调整他们的大小。

          program:

          define region NearFuncCode = [from 0xB000 to 0xFFFF];

          define region FarFuncCode = [from 0xB000 to 0xFFFF]| [from 0x10000 to 0x17FFF];

          define region HugeFuncCode = [from 0xB000 to 0x17FFF];

          place at start of NearFuncCode  { block INTVEC };

         bootload:

          define region NearFuncCode = [from 0x8000 to 0xAFFF];

          define region FarFuncCode =    [from 0x8000 to 0xAFFF];

          define region HugeFuncCode = [from 0x8000 to 0xAFFF];

          place at start of NearFuncCode  { block INTVEC };

 

像STM32这样的芯片中断向量地址可以任意定,所有boot区和APP区都可以使用中断,且互不干扰,但是STM8的中断向量表固定在0X8000地址,不能修改,所以BOOT区不能开中断,否则会和APP区的中断打架,但是APP区的一但开启中断后就会跳转到0x8000地址,这样就跳到了BOOT区,因此需要使用跳转指令将中断跳回到APP区,


__root const long reintvec[]@".intvec"=

{ 0x82008080,0x8200b004,0x8200b008,0x8200b00c, //当应用程序地址不是0xB000时则要相应改掉除第一个

        0x8200b010,0x8200b014,0x8200b018,0x8200b01c, //0x82008080以外的数值

        0x8200b020,0x8200b024,0x8200b028,0x8200b02c,

        0x8200b030,0x8200b034,0x8200b038,0x8200b03c,

        0x8200b040,0x8200b044,0x8200b048,0x8200b04c,

        0x8200b050,0x8200b054,0x8200b058,0x8200b05c,

        0x8200b060,0x8200b064,0x8200b068,0x8200b06c,

        0x8200b070,0x8200b074,0x8200b078,0x8200b07c,

}; 

 

这里大概的含义就是重定义STM8的中断,STM8中断向量重定义,至于这里为什么这样写,请网上自己去看,我也不是很清楚。

    

第二步:芯片上电后,从bootload start 跳转到 program start


当我们上电时,我们往往不需要用到bootload ,但是程序起来就先跑到ROM的起始地址,因此需要做一个跳转从bootload start 跳转到 program start。设计如下


asm("LDW X,  SP ");

asm("LD  A,  $FF");

asm("LD  XL, A ");

asm("LDW SP, X ");

asm("JPF $B000");

 

这里我们用B000,表示上电以后BOOT区没有接收到升级请求则直接跳转到APP区,0XB000是我的APP的起始地址,你可以根据自己的要求定义。


第三步:在线擦写flash

 

 void Boot_EraseChip(void)

{

  U16 usCnt;

  /* Define flash programming Time*/

  FLASH_SetProgrammingTime(FLASH_ProgramTime_Standard);

  Boot_UnLock();

  /*擦除FLASH*/

  LED_ALARM_H();

  LED_RUN_L();

  for(usCnt = USER_FLASE_ALL_OF_BLOCK;usCnt >0;usCnt-- )

  {

    HD_Clear_WDT();


    FLASH_EraseBlock(USER_FLASH_START_BLOCK+(usCnt-1), FLASH_MemType_Program);

    /* Wait until End of high voltage flag is set*/

    while (FLASH_GetFlagStatus(FLASH_FLAG_HVOFF) == RESET)

    {}

  }

  LED_ALARM_L();

  LED_RUN_H();

  Boot_Lock();

}


这个函数里面我的BOOT程序一旦接收到升级命令后,先将FLASH擦除,这里用到了一个库函数,STM8 的lib 库里面有stm8l15x_flash.h stm8l15x_flash.c

这个文件里面有一段注释,如下所示,意思是要使用flash的擦写,必须要在stm8l15x.h里面定义


#define RAM_EXECUTION  (1)  ,flash 擦写的函数都是定义在ram地址中的,所以在这些函数前都有个in_ram


  * To enable execution from RAM you can either uncomment the following define

  * in the stm8l15x.h file or define it in your toolchain compiler preprocessor

  * - #define RAM_EXECUTION  (1) 


并且由于 stm8的库对不同芯片处理不同,还需要定义你使用的芯片型号,这里我用的芯片是

STM8L052,因此使用的宏为 :


#define STM8L05X_HD_VL


这样就可以调用擦写函数去升级APP程序了,其他的工做就是在BOOT 区进行数据的收发等待,数据校验等工做了,没什么特别的东西。不管用什么芯片,只要是FLASH是分块的,都可以做boot,去加载APP。

推荐阅读

史海拾趣

Dielectric Laboratories公司的发展小趣事

随着电子行业的不断发展,市场对电子元件的需求也在不断变化。为了适应这一变化,DLI不断调整产品战略,推出了更多符合市场需求的新产品。例如,针对商业和工业领域的需求,DLI研发了具有高性能、高可靠性特点的MLCC产品,并成功打开了市场。此外,公司还不断加大研发投入,探索新的技术领域,以保持其在行业中的领先地位。

Fujitsu America公司的发展小趣事

在计算机技术发展的早期阶段,Fujitsu就展现出了强大的研发实力。1954年,Fujitsu成功研制出日本第一台电脑FACOM 100,这一里程碑式的成就不仅标志着Fujitsu在计算机领域的正式起步,也为其后续在ICT领域的发展奠定了坚实基础。Fujitsu America作为Fujitsu在全球的重要分支机构,积极将这一创新成果引入北美市场,推动了当地计算机技术的普及和应用。

CTS公司的发展小趣事

CTS公司,全称CTS Corporation,于1896年在美国印第安那州创立。在创立初期,公司主要生产和销售电器元件,凭借对技术的深入理解和市场需求的敏锐洞察,逐渐在行业中崭露头角。随着业务的扩展,CTS的产品线逐渐丰富,涵盖了汽车及电脑配件、通讯产品、精密仪器及装置等多个领域。

DURABLE公司的发展小趣事

面对电子行业的快速变化和技术更新,DURABLE公司始终保持着敏锐的洞察力和创新精神。公司不断加大对新技术和新产品的研发力度,积极探索物联网、人工智能等前沿技术在电子行业的应用。通过一系列的技术创新和产品升级,DURABLE成功实现了从传统电子材料供应商向智能电子解决方案提供商的转型升级。这一转型不仅提升了公司的核心竞争力,还为公司的未来发展奠定了坚实基础。

南晶电子(DGNJDZ)公司的发展小趣事

随着市场竞争的加剧,南晶电子意识到技术创新是企业发展的核心动力。公司投入大量研发资金,与多所高校和科研机构建立合作关系,共同研发新型半导体器件。经过不懈努力,南晶电子成功推出了一系列具有自主知识产权的高性能产品,赢得了市场的广泛认可。

Akustica(Bosch)公司的发展小趣事

随着市场竞争的加剧,南晶电子意识到技术创新是企业发展的核心动力。公司投入大量研发资金,与多所高校和科研机构建立合作关系,共同研发新型半导体器件。经过不懈努力,南晶电子成功推出了一系列具有自主知识产权的高性能产品,赢得了市场的广泛认可。

问答坊 | AI 解惑

高质量C 编程指南

如题,对写好代码很有帮助。…

查看全部问答>

后PC时代,高校纷纷转向嵌入式专业

作为后PC时代及后网络时代的新秀,嵌入式系统凭借其在网络安全、智能家电、车载电子、消费类电子、工业控制、医疗电子等领域内日益广泛地应用和发展,已无疑成为后PC时代的擎天之柱,现在的电子技术俨然已成为嵌入式系统技术的天下。 2010年 ...…

查看全部问答>

[请问]怎样在EVC4.0SP4中引用miracl库函数?

我在工程的Header Files里添加了miracl.h和mirdef.h两个头文件,还添加了ms32.lib文件,但在编程中使用otnum()等等miracl库中的函数时仍提示错误。 Repw.obj : error LNK2019: unresolved external symbol \"int __cdecl otnum(struct bigtype *,v ...…

查看全部问答>

关于对嵌入式开发了解的问题

  小弟由于想转入到嵌入式开发的领域中来,所以需要一些最基本的了解,以便有一个更清晰的学习开端,请多多指教:      问题1:在网上查了下嵌入式开发的理解,但越看越晕,一会儿是嵌入式开发,一会儿是linux嵌入 ...…

查看全部问答>

VC开发驱动怎么设置环境啊。急。

想在VC里面写驱动 但是搭建环境完全不会  哪个好心人给我详细说明。。…

查看全部问答>

MSP430中断嵌套机制

(1)430默认的是关闭中断嵌套的,除非你在一个中断程序中再次开总中断EINT。(2)当进入中断程序时,只要不在中断中再次开中断,刚总中断是关闭的,此时来中断不管是比当前中断的优先级高还是低都不执行。(3)若在中断A中开了总中断,刚可以响应 ...…

查看全部问答>

这个IAR调试问题怎么解决啊

本人菜鸟。今天在使用IAR出现了这个问题,以前都好好的。。怎么会出现头文件加载错误的…

查看全部问答>

LPC800 开发板 电路图

我下载到了电路图,可是没看懂如何在面包板上接线。 请高手帮忙介绍一下。这几排孔哪些已经定义好了。谢谢。…

查看全部问答>

论坛被侵略了……

真不知道怎么说好 …

查看全部问答>

你问我答——FPGA布线时需要注意哪些?

大家好:         我在布FPGA板子,是四层还是二层的呢,希望大家给点建议。         电源线,时钟线,低线有什麽讲究的! 谢谢大家了!…

查看全部问答>