分散加载, 链接脚本实现函数、变量的重定位.boot、app代码合并

一.背景介绍

常见的单片机IAP方案是使用两个工程. 一个boot工程,编译链接到内部flash前N(假定16K)地址, app工程代码编译链接到16K之后的地址. 应用程序通过某种方式(串口、网络等).将待升级的app代码拷贝到外部存储器. 然后设定好相应的标志位.重启,boot代码从外部存储器的 指定地址拷贝待升级的app到内部flash的相应地址.实现app的升级. 在IC短缺,供货紧张的大背景下,我们拿到的芯片的flash大小可能并不如我们所愿.比如你需要256Kflash大小的IC,而供应商暂时只能提供 128K flash大小的IC. 此时需要裁减应用大小到128K以下.应用的裁减依据产品业务功能各有不同,本文着重讲解一下boot的裁减.

二.整体方案

boot工程和app工程独立.则boot代码中必然需要包含中断向量表,时钟初始化函数,库函数等. 这部分代码是app和boot可以共享的代码 屏弃传统的IAP方案, 在app代码中编写从外部flash向内部flash拷贝的函数, 并将这些函数已以及它们调用的函数通过链接脚本重定位的方式 链接到指定地址. 这样就不用再使用一个单独的boot. 将大量节省boot代码占据的存储空间.

三.思路实现

以一款国产IC,芯旺微KF32A系列单片机讲述此方案的整体流程. 在此方案中,将中断向量表放置在第0-1K的位置. boot相关代码链接到1-3K位置(boot相关代码编译后大小1.8K).其他代码链接到3K之后的位置.

此IC链接脚本遵循gcc规范,截取部分链接脚本讲解思路.

SECTIONS
{ 
    .text : 
    { 
    . = 0x0000;
    KEEP (*vector.o(.text*))   /* 中断向量表 */

    . = (. + 3) & (-4); /* align 4 */
    __vec_end__ = .;

    /*将当前地址定位到0x400 即1K的地址处.*/
    . = 0x0400;         

    /* 表示所有__attribute__((section(".boottext")))属性的代码都链接到
        0x400开始的地址处. 在程序内部把需要链接到此处的boot相关的代码都加上
        __attribute__((section(".boottext")))属性*/
    *(.boottext*)          /* reserved for custom */    

    . = 0x0000C000;     /* 2K boot 结束*/
    KEEP (*version.o(.constdata*))  
    . = (. + 3) & (-4); /* align 4 */
    __version_end__ = .;

    . = 0x00004400;   

    *(.text*)            /* default function code space */  

注意事项:boot相关的代码操作流程为从外部flash的地址拷贝数据到内部flash指定地址.所以boot相关的代码要单独实现一份内部falsh和外部flash的读写操作函数.注意此部分相关函数必须与应用的其他代码无调用关系.编译后必须完全单独的链接到1-3K地址上去.目的是保证从外部flash向内部flash拷贝的过程中,这部分代码的链接地址完全独立.调用过程中不会调用到1-3K之外的flash地址.拷贝过程中一定要关中断.否则在拷贝过程中如果产生中断,而内部flash已经在被改写了.可能会导致中断处理函数无法获取到正确的入口地址.导致变砖.

四.总结

本文主要目的是通过分散加载的方式,实现项目需求.读者可依据此思路,实现自己的涉及到分散加载的需求.整体思路是相通的. 
调试过程思路:
1.调试过程中主要结合map文件,分析指定函数是否链接到了指定地址.
2.确保指定的函数及其调用的其他函数,都要链接到指定地址.

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值