痞子衡嵌入式(深扒IAR启动函数流程之段初始化实现中可用的压缩选项)

大家好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给大家分享的是IAR启动函数流程里段初始化实现中可用的压缩选项。
【痞子衡嵌入式(深扒IAR启动函数流程之段初始化实现中可用的压缩选项)】接着 《IAR启动函数流程之段初始化函数__iar_data_init3实现》 一文,咱们再深入一步。对于 .bss 段的初始化,其实没什么好说的,就是简单的清零操作,但是 .data/.textrw 段的初始化工作是可以做一点文章的,尤其是当这些段数据量非常大的时候,可以增加一些压缩处理(链接阶段做压缩,并且自动插入相应解压函数进镜像文件,启动初始化时做解压),以减小最终程序镜像文件的长度(代码优化选项 High - Size 之外的新手段),这也是 IAR 这种商业性软件区别于标准 GCC 工具链的地方之一。今天我们就仔细说说 IAR 工具下支持的 RW 段压缩选项:

  • Note 1: 阅读本文前需要对 《IAR链接文件(.icf)》 有所了解。
  • Note 2: 本文使用的 IAR EWARM 软件版本是 v9.10.2。
一、在链接文件中设置压缩选项
我们还是结合一个具体应用程序工程来讲解,痞子衡选择的是 \SDK_2.11.0_MIMXRT1170-EVK\boards\evkmimxrt1170\demo_apps\hello_world\cm7\iar 例程(切到 flexspi_nor_debug build),这个工程的链接文件是 MIMXRT1176xxxxx_cm7_flexspi_nor.icf,在链接文件里我们使用了如下 initialize by copy 语句来指定 IAR 链接器去做 RW/ZI 段初始化工作:
initialize by copy { readwrite, section .textrw };

其实上述语句是不完整的,其中包含了一些默认参数省略,我们翻看 \IAR Systems\Embedded Workbench 9.10.2\arm\doc\EWARM_DevelopmentGuide.ENU.pdf 文档可以找到如下 initialize 完整语法:
痞子衡嵌入式(深扒IAR启动函数流程之段初始化实现中可用的压缩选项)
文章图片

with packing = auto或smallest 是默认压缩设置,这个选项的意思是 IAR 链接器在链接时会综合比较全部支持的压缩算法,取最终生成代码尺寸最小的那种压缩算法(注意,解压函数本身也会被计算进代码尺寸):
initialize by copy with packing = auto{ readwrite, section .textrw }; initialize by copy with packing = smallest { readwrite, section .textrw };

我们在 IAR 工程选项 Linker / Extra Options 里加入 --log initialization 命令就可以在 log 输出框里看到 IAR 链接器选择压缩算法的过程:
痞子衡嵌入式(深扒IAR启动函数流程之段初始化实现中可用的压缩选项)
文章图片

二、RW段压缩算法选项详解
上一节 initialize 完整语法介绍里,我们知道了 algorithm 参数共有六种选择,除了默认的 auto/smallest,还有四种:none、zeros、packbits、lz77,这四种就是可用的压缩算法选项,它们的解压函数分别在如下四个源文件里:
\IAR Systems\Embedded Workbench 9.10.2\arm\src\lib\init\copy_init3.c- 存放 __iar_copy_init3 函数 \IAR Systems\Embedded Workbench 9.10.2\arm\src\lib\init\rle_init.c- 存放 __iar_rle_init3 函数 \IAR Systems\Embedded Workbench 9.10.2\arm\src\lib\init\packbits_init.c- 存放 __iar_packbits_init3 函数 \IAR Systems\Embedded Workbench 9.10.2\arm\src\lib\init\lz77_init.c- 存放 __iar_lz77_init3 函数

2.1 algorithm = none none 选项顾名思义,就是完全不压缩,它对应的解压函数 __iar_copy_init3 实现最简单,就是单纯的数据拷贝。none 选项比较适用数据流很小或者规律性极差的情况。
2.2 algorithm = zeros zeros 算法对应解压函数 __iar_rle_init3 ,这种算法主要用于压缩数据流中出现的连续零值,数据流中连续零值占比越大,zeros 算法压缩效果越好。
2.3 algorithm = packbits packbits 算法对应解压函数 __iar_packbits_init3 ,PackBits是一种应用于数据长度编码的快速,简单无损的数据压缩方案(是苹果公司在 Mactionsh 计算机上首先推出的算法)。对于数据流中具有许多连续相同字节的情况,packbits 算法压缩效果最佳。
2.4 algorithm = lz77 lz77 算法对应解压函数 __iar_lz77_init3 ,该算法全称 Lempel-Ziv-77,是 Abraham Lempel 与 Jacob Ziv 在 1977 年发表的论文 “A Universal Algorithm for Sequential Data Compression” 中提出的无损数据压缩算法。lz77 算法可用于各种类型的数据流,压缩表现很均衡,唯一的缺点是解压函数代码尺寸稍微大一些。
至此,IAR启动函数流程里段初始化实现中可用的压缩选项痞子衡便介绍完毕了,掌声在哪里~~~
欢迎订阅
文章会同时发布到我的 博客园主页、CSDN主页、知乎主页、微信公众号 平台上。
微信搜索"痞子衡嵌入式"或者扫描下面二维码,就可以在手机上第一时间看了哦。
痞子衡嵌入式(深扒IAR启动函数流程之段初始化实现中可用的压缩选项)
文章图片

    推荐阅读